1 /*
   2  * Copyright (c) 2000, 2020, 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      * Constructs a {@code FocusTraversalPolicy}.
  74      */
  75     protected FocusTraversalPolicy() {}
  76 
  77     /**
  78      * Returns the Component that should receive the focus after aComponent.
  79      * aContainer must be a focus cycle root of aComponent or a focus traversal
  80      * policy provider.
  81      *
  82      * @param aContainer a focus cycle root of aComponent or focus traversal
  83      *        policy provider
  84      * @param aComponent a (possibly indirect) child of aContainer, or
  85      *        aContainer itself
  86      * @return the Component that should receive the focus after aComponent, or
  87      *         null if no suitable Component can be found
  88      * @throws IllegalArgumentException if aContainer is not a focus cycle
  89      *         root of aComponent or a focus traversal policy provider, or if
  90      *         either aContainer or aComponent is null
  91      */
  92     public abstract Component getComponentAfter(Container aContainer,
  93                                                 Component aComponent);
  94 
  95     /**
  96      * Returns the Component that should receive the focus before aComponent.
  97      * aContainer must be a focus cycle root of aComponent or a focus traversal
  98      * policy provider.
  99      *
 100      * @param aContainer a focus cycle root of aComponent or focus traversal
 101      *        policy provider
 102      * @param aComponent a (possibly indirect) child of aContainer, or
 103      *        aContainer itself
 104      * @return the Component that should receive the focus before aComponent,
 105      *         or null if no suitable Component can be found
 106      * @throws IllegalArgumentException if aContainer is not a focus cycle
 107      *         root of aComponent or a focus traversal policy provider, or if
 108      *         either aContainer or aComponent is null
 109      */
 110     public abstract Component getComponentBefore(Container aContainer,
 111                                                  Component aComponent);
 112 
 113     /**
 114      * Returns the first Component in the traversal cycle. This method is used
 115      * to determine the next Component to focus when traversal wraps in the
 116      * forward direction.
 117      *
 118      * @param aContainer the focus cycle root or focus traversal policy provider
 119      *        whose first Component is to be returned
 120      * @return the first Component in the traversal cycle of aContainer,
 121      *         or null if no suitable Component can be found
 122      * @throws IllegalArgumentException if aContainer is null
 123      */
 124     public abstract Component getFirstComponent(Container aContainer);
 125 
 126     /**
 127      * Returns the last Component in the traversal cycle. This method is used
 128      * to determine the next Component to focus when traversal wraps in the
 129      * reverse direction.
 130      *
 131      * @param aContainer the focus cycle root or focus traversal policy
 132      *        provider whose last Component is to be returned
 133      * @return the last Component in the traversal cycle of aContainer,
 134      *         or null if no suitable Component can be found
 135      * @throws IllegalArgumentException if aContainer is null
 136      */
 137     public abstract Component getLastComponent(Container aContainer);
 138 
 139     /**
 140      * Returns the default Component to focus. This Component will be the first
 141      * to receive focus when traversing down into a new focus traversal cycle
 142      * rooted at aContainer.
 143      *
 144      * @param aContainer the focus cycle root or focus traversal policy
 145      *        provider whose default Component is to be returned
 146      * @return the default Component in the traversal cycle of aContainer,
 147      *         or null if no suitable Component can be found
 148      * @throws IllegalArgumentException if aContainer is null
 149      */
 150     public abstract Component getDefaultComponent(Container aContainer);
 151 
 152     /**
 153      * Returns the Component that should receive the focus when a Window is
 154      * made visible for the first time. Once the Window has been made visible
 155      * by a call to {@code show()} or {@code setVisible(true)}, the
 156      * initial Component will not be used again. Instead, if the Window loses
 157      * and subsequently regains focus, or is made invisible or undisplayable
 158      * and subsequently made visible and displayable, the Window's most
 159      * recently focused Component will become the focus owner. The default
 160      * implementation of this method returns the default Component.
 161      *
 162      * @param window the Window whose initial Component is to be returned
 163      * @return the Component that should receive the focus when window is made
 164      *         visible for the first time, or null if no suitable Component can
 165      *         be found
 166      * @see #getDefaultComponent
 167      * @see Window#getMostRecentFocusOwner
 168      * @throws IllegalArgumentException if window is null
 169      */
 170     public Component getInitialComponent(Window window) {
 171         if ( window == null ){
 172             throw new IllegalArgumentException("window cannot be equal to null.");
 173         }
 174         Component def = getDefaultComponent(window);
 175         if (def == null && window.isFocusableWindow()) {
 176             def = window;
 177         }
 178         return def;
 179     }
 180 }