📄 keyboardfocusmanager.java
字号:
/* KeyboardFocusManager.java -- manage component focusing via the keyboard Copyright (C) 2002, 2004 Free Software FoundationThis file is part of GNU Classpath.GNU Classpath is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU Classpath is distributed in the hope that it will be useful, butWITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNUGeneral Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU Classpath; see the file COPYING. If not, write to theFree Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA02110-1301 USA.Linking this library statically or dynamically with other modules ismaking a combined work based on this library. Thus, the terms andconditions of the GNU General Public License cover the wholecombination.As a special exception, the copyright holders of this library give youpermission to link this library with independent modules to produce anexecutable, regardless of the license terms of these independentmodules, and to copy and distribute the resulting executable underterms of your choice, provided that you also meet, for each linkedindependent module, the terms and conditions of the license of thatmodule. An independent module is a module which is not derived fromor based on this library. If you modify this library, you may extendthis exception to your version of the library, but you are notobligated to do so. If you do not wish to do so, delete thisexception statement from your version. */package java.awt;import java.applet.Applet;import java.awt.FocusTraversalPolicy;import java.awt.event.FocusEvent;import java.awt.event.KeyEvent;import java.awt.event.WindowEvent;import java.beans.PropertyChangeListener;import java.beans.PropertyChangeSupport;import java.beans.PropertyVetoException;import java.beans.VetoableChangeListener;import java.beans.VetoableChangeSupport;import java.util.ArrayList;import java.util.Collection;import java.util.Collections;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;/** * The <code>KeyboardFocusManager</code> handles the focusing of * windows for receiving keyboard events. The manager handles * the dispatch of all <code>FocusEvent</code>s and * <code>KeyEvent</code>s, along with <code>WindowEvent</code>s * relating to the focused window. Users can use the manager * to ascertain the current focus owner and fire events. * <br /> * <br /> * The focus owner is the <code>Component</code> that receives * key events. The focus owner is either the currently focused * window or a component within this window. * <br /> * <br /> * The underlying native windowing system may denote the active * window or its children with special decorations (e.g. a highlighted * title bar). The active window is always either a <code>Frame</code> * or <code>Dialog</code>, and is either the currently focused * window or its owner. * <br /> * <br /> * Applets may be partitioned into different applet contexts, according * to their code base. In this case, each context has its own * <code>KeyboardFocusManager</code>, as opposed to the global * manager maintained by applets which share the same context. * Each context is insulated from the others, and they don't interact. * The resulting behaviour, as with context division, depends on the browser * supporting the applets. Regardless, there can only ever be * one focused window, one active window and one focus owner * per <code>ClassLoader</code>. * <br /> * <br /> * To support this separation of focus managers, the manager instances * and the internal state information is grouped by the * <code>ThreadGroup</code> to which it pertains. With respect to * applets, each code base has its own <code>ThreadGroup</code>, so the * isolation of each context is enforced within the manager. * <br /> * <br /> * By default, the manager defines TAB and Ctrl+TAB as the * forward focus traversal keys and Shift+TAB and Ctrl+Shift+TAB * as the backward focus traversal keys. No up or down cycle * traversal keys are defined by default. Traversal takes effect * on the firing of a relevant <code>KEY_PRESSED</code> event. * However, all other key events related to the use of the * defined focus traversal key sequence are consumed and not * dispatched. * <br /> * <br /> * These default traversal keys come into effect on all windows * for which no alternative set of keys is defined. This also * applies recursively to any child components of such a window, * which define no traversal keys of their own. * * @author Eric Blake (ebb9@email.byu.edu) * @author Thomas Fitzsimmons (fitzsim@redhat.com) * @author Andrew John Hughes (gnu_andrew@member.fsf.org) * @since 1.4 */public abstract class KeyboardFocusManager implements KeyEventDispatcher, KeyEventPostProcessor{ /** Identifies {@link AWTKeyStroke}s that move the focus forward in the focus cycle. */ public static final int FORWARD_TRAVERSAL_KEYS = 0; /** Identifies {@link AWTKeyStroke}s that move the focus backward in the focus cycle. */ public static final int BACKWARD_TRAVERSAL_KEYS = 1; /** Identifies {@link AWTKeyStroke}s that move the focus up to the parent focus cycle root. */ public static final int UP_CYCLE_TRAVERSAL_KEYS = 2; /** Identifies {@link AWTKeyStroke}s that move the focus down to the child focus cycle root. */ public static final int DOWN_CYCLE_TRAVERSAL_KEYS = 3; /** The set of {@link AWTKeyStroke}s that cause focus to be moved to the next focusable Component in the focus cycle. */ private static final Set DEFAULT_FORWARD_KEYS; /** The set of {@link AWTKeyStroke}s that cause focus to be moved to the previous focusable Component in the focus cycle. */ private static final Set DEFAULT_BACKWARD_KEYS; /** Populate the DEFAULT_FORWARD_KEYS and DEFAULT_BACKWARD_KEYS {@link java.util.Set}s. */ static { Set s = new HashSet(); s.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB, 0)); s.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB, KeyEvent.CTRL_DOWN_MASK)); DEFAULT_FORWARD_KEYS = Collections.unmodifiableSet(s); s = new HashSet(); s.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB, KeyEvent.SHIFT_DOWN_MASK)); s.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB, KeyEvent.SHIFT_DOWN_MASK | KeyEvent.CTRL_DOWN_MASK)); DEFAULT_BACKWARD_KEYS = Collections.unmodifiableSet(s); } /** The global object {@link java.util.Map}s. */ /** For security reasons, {@link java.applet.Applet}s in different codebases must be insulated from one another. Since {@link KeyboardFocusManager}s have the ability to return {@link Component}s from a given {@link java.applet.Applet}, each codebase must have an independent {@link KeyboardFocusManager}. Since each codebase has its own {@link ThreadGroup} in which its {@link Applet}s run, it makes sense to partition {@link KeyboardFocusManager}s according to {@link java.lang.ThreadGroup}. Thus, currentKeyboardFocusManagers is a {@link java.util.Map} keyed on {@link java.lang.ThreadGroup}. */ private static Map currentKeyboardFocusManagers = new HashMap (); /** {@link java.applet.Applet}s in one codebase must not be allowed to access {@link Component}s in {@link java.applet.Applet}s in other codebases. To enforce this restriction, we key the following {@link java.util.Map}s on {@link java.lang.ThreadGroup}s (which are per-codebase). For example, if {@link java.lang.ThreadGroup} A calls {@link #setGlobalFocusOwner}, passing {@link Component} C, currentFocusOwners[A] is assigned C, and all other currentFocusOwners values are nullified. Then if {@link java.lang.ThreadGroup} A subsequently calls {@link #getGlobalFocusOwner}, it will return currentFocusOwners[A], that is, {@link Component} C. If another {@link java.lang.ThreadGroup} K calls {@link #getGlobalFocusOwner}, it will return currentFocusOwners[K], that is, null. Since this is a static field, we ensure that there is only one focused {@link Component} per class loader. */ private static Map currentFocusOwners = new HashMap (); /** A {@link java.util.Map} keyed on {@link java.lang.ThreadGroup}s that stores the {@link Component} that owns the permanent keyboard focus. @see currentFocusOwners */ private static Map currentPermanentFocusOwners = new HashMap (); /** A {@link java.util.Map} keyed on {@link java.lang.ThreadGroup}s that stores the focused {@link Window}. @see currentFocusOwners */ private static Map currentFocusedWindows = new HashMap (); /** A {@link java.util.Map} keyed on {@link java.lang.ThreadGroup}s that stores the active {@link Window}. @see currentFocusOwners */ private static Map currentActiveWindows = new HashMap (); /** A {@link java.util.Map} keyed on {@link java.lang.ThreadGroup}s that stores the focus cycle root {@link Container}. @see currentFocusOwners */ private static Map currentFocusCycleRoots = new HashMap (); /** The default {@link FocusTraversalPolicy} that focus-managing {@link Container}s will use to define their initial focus traversal policy. */ private FocusTraversalPolicy defaultPolicy; /** An array that stores the {@link #FORWARD_TRAVERSAL_KEYS}, {@link #BACKWARD_TRAVERSAL_KEYS}, {@link #UP_CYCLE_TRAVERSAL_KEYS} and {@link #DOWN_CYCLE_TRAVERSAL_KEYS} {@link AWTKeyStroke}s {@link java.util.Set}s. */ private Set[] defaultFocusKeys = new Set[] { DEFAULT_FORWARD_KEYS, DEFAULT_BACKWARD_KEYS, Collections.EMPTY_SET, Collections.EMPTY_SET }; /** * A utility class to support the handling of events relating to property changes. */ private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport (this); /** * A utility class to support the handling of events relating to vetoable changes. */ private final VetoableChangeSupport vetoableChangeSupport = new VetoableChangeSupport (this); /** A list of {@link KeyEventDispatcher}s that process {@link KeyEvent}s before they are processed the default keyboard focus manager. */ private final ArrayList keyEventDispatchers = new ArrayList(); /** A list of {@link KeyEventPostProcessor}s that process unconsumed {@link KeyEvent}s. */ private final ArrayList keyEventPostProcessors = new ArrayList(); /** * Construct a KeyboardFocusManager. */ public KeyboardFocusManager () { } /** * Retrieve the keyboard focus manager associated with the {@link * java.lang.ThreadGroup} to which the calling thread belongs. * * @return the keyboard focus manager associated with the current * thread group */ public static KeyboardFocusManager getCurrentKeyboardFocusManager () { ThreadGroup currentGroup = Thread.currentThread ().getThreadGroup (); if (currentKeyboardFocusManagers.get (currentGroup) == null) setCurrentKeyboardFocusManager (null); return (KeyboardFocusManager) currentKeyboardFocusManagers.get (currentGroup); } /** * Set the keyboard focus manager associated with the {@link * java.lang.ThreadGroup} to which the calling thread belongs. * * @param m the keyboard focus manager for the current thread group */ public static void setCurrentKeyboardFocusManager (KeyboardFocusManager m) { SecurityManager sm = System.getSecurityManager (); if (sm != null) sm.checkPermission (new AWTPermission ("replaceKeyboardFocusManager")); ThreadGroup currentGroup = Thread.currentThread ().getThreadGroup (); KeyboardFocusManager manager; if (m == null) manager = new DefaultKeyboardFocusManager(); else manager = m; currentKeyboardFocusManagers.put (currentGroup, manager); } /** * Retrieve the {@link Component} that has the keyboard focus, or * null if the focus owner was not set by a thread in the current * {@link java.lang.ThreadGroup}. * * @return the keyboard focus owner or null */ public Component getFocusOwner () { Component owner = (Component) getObject (currentFocusOwners); if (owner == null) owner = (Component) getObject (currentPermanentFocusOwners); return owner; } /** * Retrieve the {@link Component} that has the keyboard focus, * regardless of whether or not it was set by a thread in the * current {@link java.lang.ThreadGroup}. If there is no temporary * focus owner in effect then this method will return the same value * as {@link #getGlobalPermanentFocusOwner}. * * @return the keyboard focus owner * @throws SecurityException if this is not the keyboard focus * manager associated with the current {@link java.lang.ThreadGroup} */ protected Component getGlobalFocusOwner () { // Check if there is a temporary focus owner. Component focusOwner = (Component) getGlobalObject (currentFocusOwners); return (focusOwner == null) ? getGlobalPermanentFocusOwner () : focusOwner; } /** * Set the {@link Component} that will be returned by {@link * #getFocusOwner} (when it is called from the current {@link * java.lang.ThreadGroup}) and {@link #getGlobalFocusOwner}. This * method does not actually transfer the keyboard focus. * * @param owner the Component to return from getFocusOwner and * getGlobalFocusOwner * * @see Component#requestFocus() * @see Component#requestFocusInWindow() */ protected void setGlobalFocusOwner (Component owner) { if (owner == null || owner.focusable) setGlobalObject (currentFocusOwners, owner, "focusOwner"); } /** * Clear the global focus owner and deliver a FOCUS_LOST event to * the previously-focused {@link Component}. Until another {@link * Component} becomes the keyboard focus owner, key events will be * discarded by top-level windows. */ public void clearGlobalFocusOwner () { synchronized (currentFocusOwners) { Component focusOwner = getGlobalFocusOwner ();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -