1 /*
   2  * Copyright (c) 2000, 2013, 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 java.awt;
  26 
  27 /**
  28  * A FocusTraversalPolicy defines the order in which Components with a
  29  * particular focus cycle root are traversed. Instances can apply the policy to
  30  * arbitrary focus cycle roots, allowing themselves to be shared across
  31  * Containers. They do not need to be reinitialized when the focus cycle roots
  32  * of a Component hierarchy change.
  33  * <p>
  34  * The core responsibility of a FocusTraversalPolicy is to provide algorithms
  35  * determining the next and previous Components to focus when traversing
  36  * forward or backward in a UI. Each FocusTraversalPolicy must also provide
  37  * algorithms for determining the first, last, and default Components in a
  38  * traversal cycle. First and last Components are used when normal forward and
  39  * backward traversal, respectively, wraps. The default Component is the first
  40  * to receive focus when traversing down into a new focus traversal cycle.
  41  * A FocusTraversalPolicy can optionally provide an algorithm for determining
  42  * a Window's initial Component. The initial Component is the first to receive
  43  * focus when a Window is first made visible.
  44  * <p>
  45  * FocusTraversalPolicy takes into account <a
  46  * href="doc-files/FocusSpec.html#FocusTraversalPolicyProviders">focus traversal
  47  * policy providers</a>.  When searching for first/last/next/previous Component,
  48  * if a focus traversal policy provider is encountered, its focus traversal
  49  * policy is used to perform the search operation.
  50  * <p>
  51  * Please see
  52  * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
  53  * How to Use the Focus Subsystem</a>,
  54  * a section in <em>The Java Tutorial</em>, and the
  55  * <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
  56  * for more information.
  57  *
  58  * @author David Mendenhall
  59  *
  60  * @see Container#setFocusTraversalPolicy
  61  * @see Container#getFocusTraversalPolicy
  62  * @see Container#setFocusCycleRoot
  63  * @see Container#isFocusCycleRoot
  64  * @see Container#setFocusTraversalPolicyProvider
  65  * @see Container#isFocusTraversalPolicyProvider
  66  * @see KeyboardFocusManager#setDefaultFocusTraversalPolicy
  67  * @see KeyboardFocusManager#getDefaultFocusTraversalPolicy
  68  * @since 1.4
  69  */
  70 public abstract class FocusTraversalPolicy {
  71 
  72     /**
  73      * Returns the Component that should receive the focus after aComponent.
  74      * aContainer must be a focus cycle root of aComponent or a focus traversal
  75      * policy provider.
  76      *
  77      * @param aContainer a focus cycle root of aComponent or focus traversal
  78      *        policy provider
  79      * @param aComponent a (possibly indirect) child of aContainer, or
  80      *        aContainer itself
  81      * @return the Component that should receive the focus after aComponent, or
  82      *         null if no suitable Component can be found
  83      * @throws IllegalArgumentException if aContainer is not a focus cycle
  84      *         root of aComponent or a focus traversal policy provider, or if
  85      *         either aContainer or aComponent is null
  86      */
  87     public abstract Component getComponentAfter(Container aContainer,
  88                                                 Component aComponent);
  89 
  90     /**
  91      * Returns the Component that should receive the focus before aComponent.
  92      * aContainer must be a focus cycle root of aComponent or a focus traversal
  93      * policy provider.
  94      *
  95      * @param aContainer a focus cycle root of aComponent or focus traversal
  96      *        policy provider
  97      * @param aComponent a (possibly indirect) child of aContainer, or
  98      *        aContainer itself
  99      * @return the Component that should receive the focus before aComponent,
 100      *         or null if no suitable Component can be found
 101      * @throws IllegalArgumentException if aContainer is not a focus cycle
 102      *         root of aComponent or a focus traversal policy provider, or if
 103      *         either aContainer or aComponent is null
 104      */
 105     public abstract Component getComponentBefore(Container aContainer,
 106                                                  Component aComponent);
 107 
 108     /**
 109      * Returns the first Component in the traversal cycle. This method is used
 110      * to determine the next Component to focus when traversal wraps in the
 111      * forward direction.
 112      *
 113      * @param aContainer the focus cycle root or focus traversal policy provider
 114      *        whose first Component is to be returned
 115      * @return the first Component in the traversal cycle of aContainer,
 116      *         or null if no suitable Component can be found
 117      * @throws IllegalArgumentException if aContainer is null
 118      */
 119     public abstract Component getFirstComponent(Container aContainer);
 120 
 121     /**
 122      * Returns the last Component in the traversal cycle. This method is used
 123      * to determine the next Component to focus when traversal wraps in the
 124      * reverse direction.
 125      *
 126      * @param aContainer the focus cycle root or focus traversal policy
 127      *        provider whose last Component is to be returned
 128      * @return the last Component in the traversal cycle of aContainer,
 129      *         or null if no suitable Component can be found
 130      * @throws IllegalArgumentException if aContainer is null
 131      */
 132     public abstract Component getLastComponent(Container aContainer);
 133 
 134     /**
 135      * Returns the default Component to focus. This Component will be the first
 136      * to receive focus when traversing down into a new focus traversal cycle
 137      * rooted at aContainer.
 138      *
 139      * @param aContainer the focus cycle root or focus traversal policy
 140      *        provider whose default Component is to be returned
 141      * @return the default Component in the traversal cycle of aContainer,
 142      *         or null if no suitable Component can be found
 143      * @throws IllegalArgumentException if aContainer is null
 144      */
 145     public abstract Component getDefaultComponent(Container aContainer);
 146 
 147     /**
 148      * Returns the Component that should receive the focus when a Window is
 149      * made visible for the first time. Once the Window has been made visible
 150      * by a call to {@code show()} or {@code setVisible(true)}, the
 151      * initial Component will not be used again. Instead, if the Window loses
 152      * and subsequently regains focus, or is made invisible or undisplayable
 153      * and subsequently made visible and displayable, the Window's most
 154      * recently focused Component will become the focus owner. The default
 155      * implementation of this method returns the default Component.
 156      *
 157      * @param window the Window whose initial Component is to be returned
 158      * @return the Component that should receive the focus when window is made
 159      *         visible for the first time, or null if no suitable Component can
 160      *         be found
 161      * @see #getDefaultComponent
 162      * @see Window#getMostRecentFocusOwner
 163      * @throws IllegalArgumentException if window is null
 164      */
 165     public Component getInitialComponent(Window window) {
 166         if ( window == null ){
 167             throw new IllegalArgumentException("window cannot be equal to null.");
 168         }
 169         Component def = getDefaultComponent(window);
 170         if (def == null && window.isFocusableWindow()) {
 171             def = window;
 172         }
 173         return def;
 174     }
 175 }