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