1 /*
   2  * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package javax.swing;
  26 
  27 import java.awt.Component;
  28 import java.awt.Container;
  29 import java.awt.FocusTraversalPolicy;
  30 import java.util.Comparator;
  31 
  32 
  33 /**
  34  * This class has been obsoleted by the 1.4 focus APIs. While client code may
  35  * still use this class, developers are strongly encouraged to use
  36  * {@code java.awt.KeyboardFocusManager} and
  37  * {@code java.awt.DefaultKeyboardFocusManager} instead.
  38  * <p>
  39  * Please see
  40  * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
  41  * How to Use the Focus Subsystem</a>,
  42  * a section in <em>The Java Tutorial</em>, and the
  43  * <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
  44  * for more information.
  45  *
  46  * @author Arnaud Weber
  47  * @author David Mendenhall
  48  * @since 1.2
  49  */
  50 @SuppressWarnings("serial") // Obsolete class
  51 public class DefaultFocusManager extends FocusManager {
  52 
  53     final FocusTraversalPolicy gluePolicy =
  54         new LegacyGlueFocusTraversalPolicy(this);
  55     private final FocusTraversalPolicy layoutPolicy =
  56         new LegacyLayoutFocusTraversalPolicy(this);
  57     private final LayoutComparator comparator =
  58         new LayoutComparator();
  59 
  60     /**
  61      * Constructs a {@code DefaultFocusManager}.
  62      */
  63     public DefaultFocusManager() {
  64         setDefaultFocusTraversalPolicy(gluePolicy);
  65     }
  66 
  67     /**
  68      * Returns the component after.
  69      * @return the component after
  70      * @param aContainer a container
  71      * @param aComponent a component
  72      */
  73     public Component getComponentAfter(Container aContainer,
  74                                        Component aComponent)
  75     {
  76         Container root = (aContainer.isFocusCycleRoot())
  77             ? aContainer
  78             : aContainer.getFocusCycleRootAncestor();
  79 
  80         // Support for mixed 1.4/pre-1.4 focus APIs. If a particular root's
  81         // traversal policy is non-legacy, then honor it.
  82         if (root != null) {
  83             FocusTraversalPolicy policy = root.getFocusTraversalPolicy();
  84             if (policy != gluePolicy) {
  85                 return policy.getComponentAfter(root, aComponent);
  86             }
  87 
  88             comparator.setComponentOrientation(root.getComponentOrientation());
  89             return layoutPolicy.getComponentAfter(root, aComponent);
  90         }
  91 
  92         return null;
  93     }
  94 
  95     /**
  96      * Returns the component before.
  97      * @return the component before
  98      * @param aContainer a container
  99      * @param aComponent a component
 100      */
 101     public Component getComponentBefore(Container aContainer,
 102                                         Component aComponent)
 103     {
 104         Container root = (aContainer.isFocusCycleRoot())
 105             ? aContainer
 106             : aContainer.getFocusCycleRootAncestor();
 107 
 108         // Support for mixed 1.4/pre-1.4 focus APIs. If a particular root's
 109         // traversal policy is non-legacy, then honor it.
 110         if (root != null) {
 111             FocusTraversalPolicy policy = root.getFocusTraversalPolicy();
 112             if (policy != gluePolicy) {
 113                 return policy.getComponentBefore(root, aComponent);
 114             }
 115 
 116             comparator.setComponentOrientation(root.getComponentOrientation());
 117             return layoutPolicy.getComponentBefore(root, aComponent);
 118         }
 119 
 120         return null;
 121     }
 122 
 123     /**
 124      * Returns the first component.
 125      * @return the first component
 126      * @param aContainer a container
 127      */
 128     public Component getFirstComponent(Container aContainer) {
 129         Container root = (aContainer.isFocusCycleRoot())
 130             ? aContainer
 131             : aContainer.getFocusCycleRootAncestor();
 132 
 133         // Support for mixed 1.4/pre-1.4 focus APIs. If a particular root's
 134         // traversal policy is non-legacy, then honor it.
 135         if (root != null) {
 136             FocusTraversalPolicy policy = root.getFocusTraversalPolicy();
 137             if (policy != gluePolicy) {
 138                 return policy.getFirstComponent(root);
 139             }
 140 
 141             comparator.setComponentOrientation(root.getComponentOrientation());
 142             return layoutPolicy.getFirstComponent(root);
 143         }
 144 
 145         return null;
 146     }
 147 
 148     /**
 149      * Returns the last component.
 150      * @return the last component
 151      * @param aContainer a container
 152      */
 153     public Component getLastComponent(Container aContainer) {
 154         Container root = (aContainer.isFocusCycleRoot())
 155             ? aContainer
 156             : aContainer.getFocusCycleRootAncestor();
 157 
 158         // Support for mixed 1.4/pre-1.4 focus APIs. If a particular root's
 159         // traversal policy is non-legacy, then honor it.
 160         if (root != null) {
 161             FocusTraversalPolicy policy = root.getFocusTraversalPolicy();
 162             if (policy != gluePolicy) {
 163                 return policy.getLastComponent(root);
 164             }
 165 
 166             comparator.setComponentOrientation(root.getComponentOrientation());
 167             return layoutPolicy.getLastComponent(root);
 168         }
 169 
 170         return null;
 171     }
 172 
 173     /**
 174      * Compares the components by their focus traversal cycle order.
 175      * @param a the first component
 176      * @param b the second component
 177      * @return a comparison of the components by their focus traversal cycle order
 178      */
 179     public boolean compareTabOrder(Component a, Component b) {
 180         return (comparator.compare(a, b) < 0);
 181     }
 182 }
 183 
 184 @SuppressWarnings("serial") // JDK-implementation class
 185 final class LegacyLayoutFocusTraversalPolicy
 186     extends LayoutFocusTraversalPolicy
 187 {
 188     LegacyLayoutFocusTraversalPolicy(DefaultFocusManager defaultFocusManager) {
 189         super(new CompareTabOrderComparator(defaultFocusManager));
 190     }
 191 }
 192 
 193 final class CompareTabOrderComparator implements Comparator<Component> {
 194     private final DefaultFocusManager defaultFocusManager;
 195 
 196     CompareTabOrderComparator(DefaultFocusManager defaultFocusManager) {
 197         this.defaultFocusManager = defaultFocusManager;
 198     }
 199 
 200     public int compare(Component o1, Component o2) {
 201         if (o1 == o2) {
 202             return 0;
 203         }
 204         return (defaultFocusManager.compareTabOrder(o1, o2)) ? -1 : 1;
 205     }
 206 }