Home » openjdk-7 » javax » swing » [javadoc | source]

    1   /*
    2    * Copyright (c) 2000, 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.ComponentOrientation;
   30   import java.util.Comparator;
   31   import java.io;
   32   import sun.awt.SunToolkit;
   33   
   34   
   35   /**
   36    * A SortingFocusTraversalPolicy which sorts Components based on their size,
   37    * position, and orientation. Based on their size and position, Components are
   38    * roughly categorized into rows and columns. For a Container with horizontal
   39    * orientation, columns run left-to-right or right-to-left, and rows run top-
   40    * to-bottom. For a Container with vertical orientation, columns run top-to-
   41    * bottom and rows run left-to-right or right-to-left. See
   42    * <code>ComponentOrientation</code> for more information. All columns in a
   43    * row are fully traversed before proceeding to the next row.
   44    *
   45    * @author David Mendenhall
   46    *
   47    * @see java.awt.ComponentOrientation
   48    * @since 1.4
   49    */
   50   public class LayoutFocusTraversalPolicy extends SortingFocusTraversalPolicy
   51       implements Serializable
   52   {
   53       // Delegate most of our fitness test to Default so that we only have to
   54       // code the algorithm once.
   55       private static final SwingDefaultFocusTraversalPolicy fitnessTestPolicy =
   56           new SwingDefaultFocusTraversalPolicy();
   57   
   58       /**
   59        * Constructs a LayoutFocusTraversalPolicy.
   60        */
   61       public LayoutFocusTraversalPolicy() {
   62           super(new LayoutComparator());
   63       }
   64   
   65       /**
   66        * Constructs a LayoutFocusTraversalPolicy with the passed in
   67        * <code>Comparator</code>.
   68        */
   69       LayoutFocusTraversalPolicy(Comparator<? super Component> c) {
   70           super(c);
   71       }
   72   
   73       /**
   74        * Returns the Component that should receive the focus after aComponent.
   75        * aContainer must be a focus cycle root of aComponent.
   76        * <p>
   77        * By default, LayoutFocusTraversalPolicy implicitly transfers focus down-
   78        * cycle. That is, during normal focus traversal, the Component
   79        * traversed after a focus cycle root will be the focus-cycle-root's
   80        * default Component to focus. This behavior can be disabled using the
   81        * <code>setImplicitDownCycleTraversal</code> method.
   82        * <p>
   83        * If aContainer is <a href="../../java/awt/doc-files/FocusSpec.html#FocusTraversalPolicyProviders">focus
   84        * traversal policy provider</a>, the focus is always transferred down-cycle.
   85        *
   86        * @param aContainer a focus cycle root of aComponent or a focus traversal policy provider
   87        * @param aComponent a (possibly indirect) child of aContainer, or
   88        *        aContainer itself
   89        * @return the Component that should receive the focus after aComponent, or
   90        *         null if no suitable Component can be found
   91        * @throws IllegalArgumentException if aContainer is not a focus cycle
   92        *         root of aComponent or a focus traversal policy provider, or if either aContainer or
   93        *         aComponent is null
   94        */
   95       public Component getComponentAfter(Container aContainer,
   96                                          Component aComponent) {
   97           if (aContainer == null || aComponent == null) {
   98               throw new IllegalArgumentException("aContainer and aComponent cannot be null");
   99           }
  100           Comparator comparator = getComparator();
  101           if (comparator instanceof LayoutComparator) {
  102               ((LayoutComparator)comparator).
  103                   setComponentOrientation(aContainer.
  104                                           getComponentOrientation());
  105           }
  106           return super.getComponentAfter(aContainer, aComponent);
  107       }
  108   
  109       /**
  110        * Returns the Component that should receive the focus before aComponent.
  111        * aContainer must be a focus cycle root of aComponent.
  112        * <p>
  113        * By default, LayoutFocusTraversalPolicy implicitly transfers focus down-
  114        * cycle. That is, during normal focus traversal, the Component
  115        * traversed after a focus cycle root will be the focus-cycle-root's
  116        * default Component to focus. This behavior can be disabled using the
  117        * <code>setImplicitDownCycleTraversal</code> method.
  118        * <p>
  119        * If aContainer is <a href="../../java/awt/doc-files/FocusSpec.html#FocusTraversalPolicyProviders">focus
  120        * traversal policy provider</a>, the focus is always transferred down-cycle.
  121        *
  122        * @param aContainer a focus cycle root of aComponent or a focus traversal policy provider
  123        * @param aComponent a (possibly indirect) child of aContainer, or
  124        *        aContainer itself
  125        * @return the Component that should receive the focus before aComponent,
  126        *         or null if no suitable Component can be found
  127        * @throws IllegalArgumentException if aContainer is not a focus cycle
  128        *         root of aComponent or a focus traversal policy provider, or if either aContainer or
  129        *         aComponent is null
  130        */
  131       public Component getComponentBefore(Container aContainer,
  132                                           Component aComponent) {
  133           if (aContainer == null || aComponent == null) {
  134               throw new IllegalArgumentException("aContainer and aComponent cannot be null");
  135           }
  136           Comparator comparator = getComparator();
  137           if (comparator instanceof LayoutComparator) {
  138               ((LayoutComparator)comparator).
  139                   setComponentOrientation(aContainer.
  140                                           getComponentOrientation());
  141           }
  142           return super.getComponentBefore(aContainer, aComponent);
  143       }
  144   
  145       /**
  146        * Returns the first Component in the traversal cycle. This method is used
  147        * to determine the next Component to focus when traversal wraps in the
  148        * forward direction.
  149        *
  150        * @param aContainer a focus cycle root of aComponent or a focus traversal policy provider whose
  151        *        first Component is to be returned
  152        * @return the first Component in the traversal cycle of aContainer,
  153        *         or null if no suitable Component can be found
  154        * @throws IllegalArgumentException if aContainer is null
  155        */
  156       public Component getFirstComponent(Container aContainer) {
  157           if (aContainer == null) {
  158               throw new IllegalArgumentException("aContainer cannot be null");
  159           }
  160           Comparator comparator = getComparator();
  161           if (comparator instanceof LayoutComparator) {
  162               ((LayoutComparator)comparator).
  163                   setComponentOrientation(aContainer.
  164                                           getComponentOrientation());
  165           }
  166           return super.getFirstComponent(aContainer);
  167       }
  168   
  169       /**
  170        * Returns the last Component in the traversal cycle. This method is used
  171        * to determine the next Component to focus when traversal wraps in the
  172        * reverse direction.
  173        *
  174        * @param aContainer a focus cycle root of aComponent or a focus traversal policy provider whose
  175        *        last Component is to be returned
  176        * @return the last Component in the traversal cycle of aContainer,
  177        *         or null if no suitable Component can be found
  178        * @throws IllegalArgumentException if aContainer is null
  179        */
  180       public Component getLastComponent(Container aContainer) {
  181           if (aContainer == null) {
  182               throw new IllegalArgumentException("aContainer cannot be null");
  183           }
  184           Comparator comparator = getComparator();
  185           if (comparator instanceof LayoutComparator) {
  186               ((LayoutComparator)comparator).
  187                   setComponentOrientation(aContainer.
  188                                           getComponentOrientation());
  189           }
  190           return super.getLastComponent(aContainer);
  191       }
  192   
  193       /**
  194        * Determines whether the specified <code>Component</code>
  195        * is an acceptable choice as the new focus owner.
  196        * This method performs the following sequence of operations:
  197        * <ol>
  198        * <li>Checks whether <code>aComponent</code> is visible, displayable,
  199        *     enabled, and focusable.  If any of these properties is
  200        *     <code>false</code>, this method returns <code>false</code>.
  201        * <li>If <code>aComponent</code> is an instance of <code>JTable</code>,
  202        *     returns <code>true</code>.
  203        * <li>If <code>aComponent</code> is an instance of <code>JComboBox</code>,
  204        *     then returns the value of
  205        *     <code>aComponent.getUI().isFocusTraversable(aComponent)</code>.
  206        * <li>If <code>aComponent</code> is a <code>JComponent</code>
  207        *     with a <code>JComponent.WHEN_FOCUSED</code>
  208        *     <code>InputMap</code> that is neither <code>null</code>
  209        *     nor empty, returns <code>true</code>.
  210        * <li>Returns the value of
  211        *     <code>DefaultFocusTraversalPolicy.accept(aComponent)</code>.
  212        * </ol>
  213        *
  214        * @param aComponent the <code>Component</code> whose fitness
  215        *                   as a focus owner is to be tested
  216        * @see java.awt.Component#isVisible
  217        * @see java.awt.Component#isDisplayable
  218        * @see java.awt.Component#isEnabled
  219        * @see java.awt.Component#isFocusable
  220        * @see javax.swing.plaf.ComboBoxUI#isFocusTraversable
  221        * @see javax.swing.JComponent#getInputMap
  222        * @see java.awt.DefaultFocusTraversalPolicy#accept
  223        * @return <code>true</code> if <code>aComponent</code> is a valid choice
  224        *         for a focus owner;
  225        *         otherwise <code>false</code>
  226        */
  227        protected boolean accept(Component aComponent) {
  228           if (!super.accept(aComponent)) {
  229               return false;
  230           } else if (SunToolkit.isInstanceOf(aComponent, "javax.swing.JTable")) {
  231               // JTable only has ancestor focus bindings, we thus force it
  232               // to be focusable by returning true here.
  233               return true;
  234           } else if (SunToolkit.isInstanceOf(aComponent, "javax.swing.JComboBox")) {
  235               JComboBox box = (JComboBox)aComponent;
  236               return box.getUI().isFocusTraversable(box);
  237           } else if (aComponent instanceof JComponent) {
  238               JComponent jComponent = (JComponent)aComponent;
  239               InputMap inputMap = jComponent.getInputMap(JComponent.WHEN_FOCUSED,
  240                                                          false);
  241               while (inputMap != null && inputMap.size() == 0) {
  242                   inputMap = inputMap.getParent();
  243               }
  244               if (inputMap != null) {
  245                   return true;
  246               }
  247               // Delegate to the fitnessTestPolicy, this will test for the
  248               // case where the developer has overriden isFocusTraversable to
  249               // return true.
  250           }
  251           return fitnessTestPolicy.accept(aComponent);
  252       }
  253   
  254       private void writeObject(ObjectOutputStream out) throws IOException {
  255           out.writeObject(getComparator());
  256           out.writeBoolean(getImplicitDownCycleTraversal());
  257       }
  258       private void readObject(ObjectInputStream in)
  259           throws IOException, ClassNotFoundException
  260       {
  261           setComparator((Comparator)in.readObject());
  262           setImplicitDownCycleTraversal(in.readBoolean());
  263       }
  264   }
  265   
  266   // Create our own subclass and change accept to public so that we can call
  267   // accept.
  268   class SwingDefaultFocusTraversalPolicy
  269       extends java.awt.DefaultFocusTraversalPolicy
  270   {
  271       public boolean accept(Component aComponent) {
  272           return super.accept(aComponent);
  273       }
  274   }

Home » openjdk-7 » javax » swing » [javadoc | source]