1 /*
   2  * Copyright (c) 1997, 2014, 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</code> and
  37  * <code>java.awt.DefaultKeyboardFocusManager</code> 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     public DefaultFocusManager() {
  61         setDefaultFocusTraversalPolicy(gluePolicy);
  62     }
  63 
  64     public Component getComponentAfter(Container aContainer,
  65                                        Component aComponent)
  66     {
  67         Container root = (aContainer.isFocusCycleRoot())
  68             ? aContainer
  69             : aContainer.getFocusCycleRootAncestor();
  70 
  71         // Support for mixed 1.4/pre-1.4 focus APIs. If a particular root's
  72         // traversal policy is non-legacy, then honor it.
  73         if (root != null) {
  74             FocusTraversalPolicy policy = root.getFocusTraversalPolicy();
  75             if (policy != gluePolicy) {
  76                 return policy.getComponentAfter(root, aComponent);
  77             }
  78 
  79             comparator.setComponentOrientation(root.getComponentOrientation());
  80             return layoutPolicy.getComponentAfter(root, aComponent);
  81         }
  82 
  83         return null;
  84     }
  85 
  86     public Component getComponentBefore(Container aContainer,
  87                                         Component aComponent)
  88     {
  89         Container root = (aContainer.isFocusCycleRoot())
  90             ? aContainer
  91             : aContainer.getFocusCycleRootAncestor();
  92 
  93         // Support for mixed 1.4/pre-1.4 focus APIs. If a particular root's
  94         // traversal policy is non-legacy, then honor it.
  95         if (root != null) {
  96             FocusTraversalPolicy policy = root.getFocusTraversalPolicy();
  97             if (policy != gluePolicy) {
  98                 return policy.getComponentBefore(root, aComponent);
  99             }
 100 
 101             comparator.setComponentOrientation(root.getComponentOrientation());
 102             return layoutPolicy.getComponentBefore(root, aComponent);
 103         }
 104 
 105         return null;
 106     }
 107 
 108     public Component getFirstComponent(Container aContainer) {
 109         Container root = (aContainer.isFocusCycleRoot())
 110             ? aContainer
 111             : aContainer.getFocusCycleRootAncestor();
 112 
 113         // Support for mixed 1.4/pre-1.4 focus APIs. If a particular root's
 114         // traversal policy is non-legacy, then honor it.
 115         if (root != null) {
 116             FocusTraversalPolicy policy = root.getFocusTraversalPolicy();
 117             if (policy != gluePolicy) {
 118                 return policy.getFirstComponent(root);
 119             }
 120 
 121             comparator.setComponentOrientation(root.getComponentOrientation());
 122             return layoutPolicy.getFirstComponent(root);
 123         }
 124 
 125         return null;
 126     }
 127 
 128     public Component getLastComponent(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.getLastComponent(root);
 139             }
 140 
 141             comparator.setComponentOrientation(root.getComponentOrientation());
 142             return layoutPolicy.getLastComponent(root);
 143         }
 144 
 145         return null;
 146     }
 147 
 148     public boolean compareTabOrder(Component a, Component b) {
 149         return (comparator.compare(a, b) < 0);
 150     }
 151 }
 152 
 153 @SuppressWarnings("serial") // JDK-implementation class
 154 final class LegacyLayoutFocusTraversalPolicy
 155     extends LayoutFocusTraversalPolicy
 156 {
 157     LegacyLayoutFocusTraversalPolicy(DefaultFocusManager defaultFocusManager) {
 158         super(new CompareTabOrderComparator(defaultFocusManager));
 159     }
 160 }
 161 
 162 final class CompareTabOrderComparator implements Comparator<Component> {
 163     private final DefaultFocusManager defaultFocusManager;
 164 
 165     CompareTabOrderComparator(DefaultFocusManager defaultFocusManager) {
 166         this.defaultFocusManager = defaultFocusManager;
 167     }
 168 
 169     public int compare(Component o1, Component o2) {
 170         if (o1 == o2) {
 171             return 0;
 172         }
 173         return (defaultFocusManager.compareTabOrder(o1, o2)) ? -1 : 1;
 174     }
 175 }