| <!-- | |
| Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. | |
| DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| This code is free software; you can redistribute it and/or modify it | |
| under the terms of the GNU General Public License version 2 only, as | |
| published by the Free Software Foundation. Oracle designates this | |
| particular file as subject to the "Classpath" exception as provided | |
| by Oracle in the LICENSE file that accompanied this code. | |
| This code is distributed in the hope that it will be useful, but WITHOUT | |
| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| version 2 for more details (a copy is included in the LICENSE file that | |
| accompanied this code). | |
| You should have received a copy of the GNU General Public License version | |
| 2 along with this work; if not, write to the Free Software Foundation, | |
| Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| or visit www.oracle.com if you need additional information or have any | |
| questions. | |
| --> | |
| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> | |
| <html> | |
| <head> | |
| <title>The AWT Focus Subsystem</title> | |
| </head> | |
| <body bgcolor="white"> | |
| <h1 align=center>The AWT Focus Subsystem</h1> | |
| <p> | |
| Prior to Java 2 Standard Edition, JDK 1.4, the AWT focus subsystem | |
| was inadequate. It suffered from major design and API problems, | |
| as well as over a hundred open bugs. Many of these bugs were caused by | |
| platform inconsistencies, or incompatibilities between the native | |
| focus system for heavyweights and the Java focus system for | |
| lightweights. | |
| <p> | |
| The single worst problem with the AWT focus implementation was the | |
| inability to query for the currently focused Component. Not only was | |
| there no API for such a query, but also, because of an insufficient | |
| architecture, such information was not even maintained by the code. | |
| <p> | |
| Almost as bad was the inability of lightweight children of a Window | |
| (not a Frame or a Dialog) to receive keyboard input. This problem | |
| existed because Windows never received <code>WINDOW_ACTIVATED</code> | |
| events and thus could never be activated, and only active Windows | |
| could contain focused Components. | |
| <p> | |
| In addition, many developers noted that the APIs for FocusEvent and | |
| WindowEvent were insufficient because they did not provide a way for | |
| determining the "opposite" Component involved in the focus or | |
| activation change. For example, when a Component received a FOCUS_LOST | |
| event, it had no way of knowing which Component was gaining | |
| focus. Since Microsoft Windows provides this functionality for free, | |
| developers migrating from Microsoft Windows C/C++ or Visual Basic to | |
| Java had been frustrated by the omission. | |
| <p> | |
| To address these and other deficiencies, we have designed a new focus | |
| model for the AWT in JDK 1.4. The primary design changes were the | |
| construction of a new centralized KeyboardFocusManager class, and a | |
| lightweight focus architecture. The amount of focus-related, | |
| platform-dependent code has been minimized and replaced by fully | |
| pluggable and extensible public APIs in the AWT. While we have | |
| attempted to remain backward compatible with the existing | |
| implementation, we were forced to make minor incompatible changes in | |
| order to reach an elegant and workable conclusion. We anticipate that | |
| these incompatibilities will have only a trivial impact on existing | |
| applications. | |
| <p> | |
| This document is a formal specification both of the new APIs and of | |
| existing APIs which remain relevant in the new model. Combined with | |
| the javadoc for focus-related classes and methods, this document | |
| should enable developers to create substantial AWT and Swing | |
| applications with a focus behavior that is customized yet consistent | |
| across platforms. This document has the following sections: | |
| <ul> | |
| <li><a href=#Overview>Overview of KeyboardFocusManager</a> | |
| <li><a href=#BrowserContexts>KeyboardFocusManager and Browser Contexts</a> | |
| <li><a href=#KeyEventDispatcher>KeyEventDispatcher</a> | |
| <li><a href=#FocusEventAndWindowEvent>FocusEvent and WindowEvent</a> | |
| <li><a href=#EventDelivery>Event Delivery</a> | |
| <li><a href=#OppositeComponents>Opposite Components and Windows</a> | |
| <li><a href=#TemporaryFocusEvents>Temporary FocusEvents</a> | |
| <li><a href=#FocusTraversal>Focus Traversal</a> | |
| <li><a href=#FocusTraversalPolicy>Focus Traversal Policy</a> | |
| <li><a href=#FocusTraversalPolicyProviders>Focus Traversal Policy Providers</a> | |
| <li><a href=#ProgrammaticTraversal>Programmatic Traversal</a> | |
| <li><a href=#Focusability>Focusability</a> | |
| <li><a href=#FocusableWindows>Focusable Windows</a> | |
| <li><a href=#RequestingFocus>Requesting Focus</a> | |
| <li><a href=#FocusAndPropertyChangeListener>Focus and PropertyChangeListener</a> | |
| <li><a href=#FocusAndVetoableChangeListener>Focus and VetoableChangeListener</a> | |
| <li><a href=#ZOrder>Z-Order</a> | |
| <li><a href=#ReplacingDefaultKeyboardFocusManager>Replacing DefaultKeyboardFocusManager</a> | |
| <li><a href=#Incompatibilities>Incompatibilities with Previous Releases</a> | |
| </ul> | |
| <a name="Overview"></a> | |
| <h3>Overview of KeyboardFocusManager</h3> | |
| <p> | |
| The focus model is centralized around a single class, | |
| KeyboardFocusManager, that provides a set of APIs for client code to | |
| inquire about the current focus state, initiate focus changes, and | |
| replace default focus event dispatching with a custom dispatcher. | |
| Clients can inquire about the focus state directly, or can register a | |
| PropertyChangeListener that will receive PropertyChangeEvents when a | |
| change to the focus state occurs. | |
| <p> | |
| KeyboardFocusManager introduces the following main concepts and their | |
| terminology: | |
| <ol> | |
| <li>The "focus owner" -- the Component which typically receives | |
| keyboard input. | |
| <li>The "permanent focus owner" -- the last Component to receive | |
| focus permanently. The "focus owner" and the "permanent focus | |
| owner" are equivalent unless a temporary focus change is | |
| currently in effect. In such a situation, the "permanent focus | |
| owner" will again be the "focus owner" when the temporary focus | |
| change ends. | |
| <li>The "focused Window" -- the Window which contains the "focus | |
| owner". | |
| <li>The "active Window" -- the Frame or Dialog that is either the | |
| "focused Window", or the first Frame or Dialog that is an owner | |
| of the "focused Window". | |
| <li>"Focus traversal" -- the user's ability to change the "focus | |
| owner" without moving the cursor. Typically, this is done using | |
| the keyboard (for example, by using the TAB key), or an | |
| equivalent device in an accessible environment. Client code can | |
| also initiate traversal programmatically. Normal focus traversal | |
| can be either "forward" to the "next" Component, or "backward" to | |
| the "previous" Component. | |
| <li>"Focus traversal cycle" -- a portion of the Component hierarchy, | |
| such that normal focus traversal "forward" (or "backward") will | |
| traverse through all of the Components in the focus cycle, but no | |
| other Components. This cycle provides a mapping from an arbitrary | |
| Component in the cycle to its "next" (forward traversal) and | |
| "previous" (backward traversal) Components. | |
| <li>"Traversable Component" -- Component that is in the focus traversal | |
| cycle. | |
| <li>"Non-traversable Component" -- Component that is not in the focus | |
| traversal cycle. Note that a non-traversable Component can nevertheless | |
| be focused in other way (e.g. by direct focus request). | |
| <li>"Focus cycle root" -- Container that is the root of the Component | |
| hierarchy for a particular "focus traversal cycle". When the | |
| "focus owner" is a Component inside a particular cycle, normal | |
| forward and backward focus traversal cannot move the "focus | |
| owner" above the focus cycle root in the Component hierarchy. | |
| Instead, two additional traversal operations, "up cycle" and | |
| "down cycle", are defined to allow keyboard and programmatic | |
| navigation up and down the focus traversal cycle hierarchy. </li> | |
| <li>"Focus traversal policy provider" - Container which has | |
| "FocusTraversalPolicyProvider" property as true. This Container will | |
| be used to acquire focus traversal policy. This container doesn't | |
| define new focus cycle but only modifies the order by which its | |
| children are traversed "forward" and "backward". Focus traversal | |
| policy provider can be set using | |
| <code>setFocusTraversalPolicyProvider</code> on the Container. | |
| </ol> | |
| <p> | |
| Every Window and JInternalFrame is, by default, a "focus cycle | |
| root". If it's the only focus cycle root, then all of its | |
| focusable descendants should be in its focus cycle, and its focus | |
| traversal policy should enforce that they are by making sure that | |
| all will be reached during normal forward (or backward) | |
| traversal. If, on the other hand, the Window or JInternalFrame | |
| has descendants that are also focus cycle roots, then each such | |
| descendant is a member of two focus cycles: the one that it is | |
| the root of, and the one of its nearest focus-cycle-root | |
| ancestor. In order to traverse the focusable components belonging | |
| to the focus cycle of such a "descendant" focus cycle root, one | |
| first traverses (forward or backward) to reach the descendant, | |
| and then uses the "down cycle" operation to reach, in turn, its | |
| descendants. | |
| <p> | |
| Here is an example:<br> <img src="FocusCycle.gif" align=middle | |
| alt="Three groups as described below: ABCF BDE and DGH. "><br> | |
| <p>Assume the following: | |
| <ul> | |
| <li><b>A</b> is a <code>Window</code>, which means that it | |
| must be a focus cycle root. | |
| <li><b>B</b> and <b>D</b> are <code>Container</code>s that | |
| are focus cycle roots. | |
| <li><b>C</b> is a <code>Container</code> that is not a focus cycle root. | |
| <li><b>G</b>, <b>H</b>, <b>E</b>, and <b>F</b> are all | |
| <code>Component</code>s. | |
| </ul> | |
| There are a total of three focus cycle roots in this example: | |
| <ol> | |
| <li><b>A</b> is a root, and <b>A</b>, <b>B</b>, <b>C</b>, | |
| and <b>F</b> are members of <b>A</b>'s cycle. | |
| <li><b>B</b> is a root, and <b>B</b>, <b>D</b>, and | |
| <b>E</b> are members of <b>B</b>'s cycle. | |
| <li><b>D</b> is a root, and <b>D</b>, <b>G</b>, | |
| and <b>H</b> are members of <b>D</b>'s cycle. | |
| </ol> | |
| Windows are the only Containers which, by default, are focus cycle | |
| roots. | |
| <code>KeyboardFocusManager</code> is an abstract class. AWT provides a default | |
| implementation in the <code>DefaultKeyboardFocusManager</code> class. | |
| <a name="BrowserContexts"></a> | |
| <h3>KeyboardFocusManager and Browser Contexts</h3> | |
| <p> | |
| Some browsers partition applets in different code bases into separate | |
| contexts, and establish walls between these contexts. Each thread and | |
| each Component is associated with a particular context and cannot | |
| interfere with threads or access Components in other contexts. In such | |
| a scenario, there will be one KeyboardFocusManager per context. Other | |
| browsers place all applets into the same context, implying that there | |
| will be only a single, global KeyboardFocusManager for all | |
| applets. This behavior is implementation-dependent. Consult your | |
| browser's documentation for more information. No matter how many | |
| contexts there may be, however, there can never be more than one focus | |
| owner, focused Window, or active Window, per ClassLoader. | |
| <a name="KeyEventDispatcher"></a> | |
| <h3>KeyEventDispatcher and KeyEventPostProcessor</h3> | |
| <p> | |
| While the user's KeyEvents should generally be delivered to the focus | |
| owner, there are rare cases where this is not desirable. An input | |
| method is an example of a specialized Component that should receive | |
| KeyEvents even though its associated text Component is and should | |
| remain the focus owner. | |
| <p> | |
| A KeyEventDispatcher is a lightweight interface that allows client | |
| code to pre-listen to all KeyEvents in a particular context. Instances | |
| of classes that implement the interface and are registered with the | |
| current KeyboardFocusManager will receive KeyEvents before they are | |
| dispatched to the focus owner, allowing the KeyEventDispatcher to | |
| retarget the event, consume it, dispatch it itself, or make other | |
| changes. | |
| <p> | |
| For consistency, KeyboardFocusManager itself is a | |
| KeyEventDispatcher. By default, the current KeyboardFocusManager will | |
| be the sink for all KeyEvents not dispatched by the registered | |
| KeyEventDispatchers. The current KeyboardFocusManager cannot be | |
| completely deregistered as a KeyEventDispatcher. However, if a | |
| KeyEventDispatcher reports that it dispatched the KeyEvent, regardless | |
| of whether it actually did so, the KeyboardFocusManager will take no | |
| further action with regard to the KeyEvent. (While it is possible for | |
| client code to register the current KeyboardFocusManager as a | |
| KeyEventDispatcher one or more times, there is no obvious reason why | |
| this would be necessary, and therefore it is not recommended.) | |
| <p> | |
| Client-code may also post-listen to KeyEvents in a particular context | |
| using the KeyEventPostProcessor interface. KeyEventPostProcessors | |
| registered with the current KeyboardFocusManager will receive | |
| KeyEvents after the KeyEvents have been dispatched to and handled by | |
| the focus owner. The KeyEventPostProcessors will also receive | |
| KeyEvents that would have been otherwise discarded because no | |
| Component in the application currently owns the focus. This will allow | |
| applications to implement features that require global KeyEvent post- | |
| handling, such as menu shortcuts. | |
| <p> | |
| Like KeyEventDispatcher, KeyboardFocusManager also implements | |
| KeyEventPostProcessor, and similar restrictions apply to its use in | |
| that capacity. | |
| <a name="FocusEventAndWindowEvent"></a> | |
| <h3>FocusEvent and WindowEvent</h3> | |
| <p> | |
| The AWT defines the following six event types central to the focus | |
| model in two different <code>java.awt.event</code> classes: | |
| <ol> | |
| <li><code>WindowEvent.WINDOW_ACTIVATED</code>: This event is | |
| dispatched to a Frame or Dialog (but never a Window which | |
| is not a Frame or Dialog) when it becomes the active Window. | |
| <li><code>WindowEvent.WINDOW_GAINED_FOCUS</code>: This event is | |
| dispatched to a Window when it becomes the focused Window. | |
| Only focusable Windows can receive this event. | |
| <li><code>FocusEvent.FOCUS_GAINED</code>: This event is dispatched | |
| to a Component when it becomes the focus owner. Only focusable | |
| Components can receive this event. | |
| <li><code>FocusEvent.FOCUS_LOST</code>: This event is dispatched | |
| to a Component when it is no longer the focus owner. | |
| <li><code>WindowEvent.WINDOW_LOST_FOCUS</code>: This event is | |
| dispatched to a Window when it is no longer the focused Window. | |
| <li><code>WindowEvent.WINDOW_DEACTIVATED</code>: This event is | |
| dispatched to a Frame or Dialog (but never a Window which is | |
| not a Frame or Dialog) when it is no longer the active Window. | |
| </ol> | |
| <a name="EventDelivery"></a> | |
| <h3>Event Delivery</h3> | |
| <p> | |
| If the focus is not in java application and the user clicks on a focusable | |
| child Component<b>a</b> of an inactive Frame <b>b</b>, the following events | |
| will be dispatched and handled in order: | |
| <ol> | |
| <li><b>b</b> will receive a <code>WINDOW_ACTIVATED</code> event. | |
| <li>Next, <b>b</b> will receive a <code>WINDOW_GAINED_FOCUS</code> event. | |
| <li>Finally, <b>a</b> will receive a <code>FOCUS_GAINED</code> event. | |
| </ol> | |
| If the user later clicks on a focusable child Component <b>c</b> of another | |
| Frame <b>d</b>, the following events will be dispatched and handled in | |
| order: | |
| <ol> | |
| <li><b>a</b> will receive a <code>FOCUS_LOST</code> event. | |
| <li><b>b</b> will receive a <code>WINDOW_LOST_FOCUS</code> event. | |
| <li><b>b</b> will receive a <code>WINDOW_DEACTIVATED</code> event. | |
| <li><b>d</b> will receive a <code>WINDOW_ACTIVATED</code> event. | |
| <li><b>d</b> will receive a <code>WINDOW_GAINED_FOCUS</code> event. | |
| <li><b>c</b> will receive a <code>FOCUS_GAINED</code> event. | |
| </ol> | |
| Note that each event will be fully handled before the next event is | |
| dispatched. This restriction will be enforced even if the Components | |
| are in different contexts and are handled on different event | |
| dispatching threads. | |
| <p> | |
| In addition, each event type will be dispatched in 1-to-1 | |
| correspondence with its opposite event type. For example, if a | |
| Component receives a <code>FOCUS_GAINED</code> event, under no | |
| circumstances can it ever receive another <code>FOCUS_GAINED</code> | |
| event without an intervening <code>FOCUS_LOST</code> event. | |
| <p> | |
| Finally, it is important to note that these events are delivered for | |
| informational purposes only. It is impossible, for example, to prevent | |
| the delivery of a pending <code>FOCUS_GAINED</code> event by requesting | |
| focus back to the Component losing focus while handling the preceding | |
| <code>FOCUS_LOST</code> event. While client code may make such a request, | |
| the pending <code>FOCUS_GAINED</code> will still be delivered, | |
| followed later by the events transferring focus back to the original | |
| focus owner. | |
| <p> | |
| If it is absolutely necessary to suppress the <code>FOCUS_GAINED</code> event, | |
| client code can install a <code>VetoableChangeListener</code> which | |
| rejects the focus change. See <a href="#FocusAndVetoableChangeListener">Focus | |
| and VetoableChangeListener</a>. | |
| <a name="OppositeComponents"></a> | |
| <h3>Opposite Components and Windows</h3> | |
| <p> | |
| Each event includes information about the "opposite" Component or | |
| Window involved in the focus or activation change. For example, for a | |
| <code>FOCUS_GAINED</code> event, the opposite Component is the Component | |
| that lost focus. If the focus or activation change occurs with a native | |
| application, with a Java application in a different VM or context, or | |
| with no other Component, then the opposite Component or Window is | |
| null. This information is accessible using | |
| <code>FocusEvent.getOppositeComponent</code> or | |
| <code>WindowEvent.getOppositeWindow</code>. | |
| <p> | |
| On some platforms, it is not possible to discern the opposite | |
| Component or Window when the focus or activation change occurs between | |
| two different heavyweight Components. In these cases, the opposite | |
| Component or Window may be set to null on some platforms, and to a | |
| valid non-null value on other platforms. However, for a focus change | |
| between two lightweight Components which share the same heavyweight | |
| Container, the opposite Component will always be set correctly. Thus, | |
| a pure Swing application can ignore this platform restriction when | |
| using the opposite Component of a focus change that occurred within a | |
| top-level Window. | |
| <a name="TemporaryFocusEvents"></a> | |
| <h3>Temporary FocusEvents</h3> | |
| <p> | |
| <code>FOCUS_GAINED</code> and <code>FOCUS_LOST</code> events are | |
| marked as either temporary or permanent. | |
| <p> | |
| Temporary <code>FOCUS_LOST</code> events are sent when a Component is | |
| losing the focus, but will regain the focus shortly. These events | |
| can be useful when focus changes are used as triggers for validation | |
| of data. For instance, a text Component may want to commit its | |
| contents when the user begins interacting with another Component, | |
| and can accomplish this by responding to <code>FOCUS_LOST</code> events. | |
| However, if the <code>FocusEvent</code> received is temporary, | |
| the commit should not be done, since the text field will be receiving | |
| the focus again shortly. | |
| <p> | |
| A permanent focus transfer typically occurs as the result of a user | |
| clicking on a selectable, heavyweight Component, focus traversal with | |
| the keyboard or an equivalent input device, or from a call to | |
| <code>requestFocus()</code> or <code>requestFocusInWindow()</code>. | |
| <p> | |
| A temporary focus transfer typically occurs as the result of showing a | |
| Menu or PopupMenu, clicking or dragging a Scrollbar, moving a Window | |
| by dragging the title bar, or making another Window the focused | |
| Window. Note that on some platforms, these actions may not generate | |
| any FocusEvents at all. On others, temporary focus transfers will | |
| occur. | |
| <p> | |
| When a Component receives a temporary <code>FOCUS_LOST</code> event, | |
| the event's opposite Component (if any) may receive a temporary | |
| <code>FOCUS_GAINED</code> event, but could also receive a permanent | |
| <code>FOCUS_GAINED</code> event. Showing a Menu or PopupMenu, or | |
| clicking or dragging a Scrollbar, should generate a temporary | |
| <code>FOCUS_GAINED</code> event. Changing the focused Window, | |
| however, will yield a permanent <code>FOCUS_GAINED</code> event | |
| for the new focus owner. | |
| <p> | |
| The Component class includes variants of <code>requestFocus</code> and | |
| <code>requestFocusInWindow</code> which take a desired temporary state as a | |
| parameter. However, because specifying an arbitrary temporary state | |
| may not be implementable on all native windowing systems, correct | |
| behavior for this method can be guaranteed only for lightweight | |
| Components. This method is not intended for general use, but exists | |
| instead as a hook for lightweight Component libraries, such as Swing. | |
| <a name="FocusTraversal"></a> | |
| <h3>Focus Traversal</h3> | |
| <p> | |
| Each Component defines its own Set of focus traversal keys for a given | |
| focus traversal operation. Components support separate Sets of keys | |
| for forward and backward traversal, and also for traversal up one | |
| focus traversal cycle. Containers which are focus cycle roots also | |
| support a Set of keys for traversal down one focus traversal cycle. If | |
| a Set is not explicitly defined for a Component, that Component | |
| recursively inherits a Set from its parent, and ultimately from a | |
| context-wide default set on the current <code>KeyboardFocusManager</code>. | |
| <p> | |
| Using the <code>AWTKeyStroke</code> API, client code can specify | |
| on which of two specific KeyEvents, <code>KEY_PRESSED</code> or | |
| <code>KEY_RELEASED</code>, the focus traversal operation will occur. | |
| Regardless of which KeyEvent is specified, however, all KeyEvents | |
| related to the focus traversal key, including the associated | |
| <code>KEY_TYPED</code> event, will be consumed, and will not be | |
| dispatched to any Component. It is a runtime error to specify a | |
| <code>KEY_TYPED</code> event as mapping to a focus traversal operation, | |
| or to map the same event to multiple focus traversal operations for any | |
| particular Component or for a <code>KeyboardFocusManager</code>'s defaults. | |
| <p> | |
| The default focus traversal keys are implementation-dependent. Sun | |
| recommends that the all implementations for a particular native | |
| platform use the same keys. For Windows and Unix, the recommendations | |
| are: | |
| <ul> | |
| <li>traverse forward to the next Component: | |
| <br><i>TextAreas</i>: <code>CTRL-TAB</code> on <code>KEY_PRESSED</code> | |
| <br><i>All others</i>: <code>TAB</code> on <code>KEY_PRESSED</code> and | |
| <code>CTRL-TAB</code> on <code>KEY_PRESSED</code> | |
| <li>traverse backward to the previous Component: | |
| <br><i>TextAreas</i>: <code>CTRL-SHIFT-TAB</code> on | |
| <code>KEY_PRESSED</code> | |
| <br><i>All others</i>: <code>SHIFT-TAB</code> on <code>KEY_PRESSED</code> | |
| and <code>CTRL-SHIFT-TAB</code> on | |
| <code>KEY_PRESSED</code> | |
| <li>traverse up one focus traversal cycle : <none> | |
| <li>traverse down one focus traversal cycle : <none> | |
| </ul> | |
| <p> | |
| Components can enable and disable all of their focus traversal keys en | |
| masse using <code>Component.setFocusTraversalKeysEnabled</code>. When focus | |
| traversal keys are disabled, the Component receives all KeyEvents for | |
| those keys. When focus traversal keys are enabled, the Component never | |
| receives KeyEvents for traversal keys; instead, the KeyEvents are | |
| automatically mapped to focus traversal operations. | |
| <p> | |
| For normal forward and backward traversal, the AWT focus | |
| implementation determines which Component to focus next based on the | |
| <a href=#FocusTraversalPolicy><code>FocusTraversalPolicy</code></a> of | |
| the focus owner's focus cycle root or focus traversal policy provider. If the | |
| focus owner is a focus cycle root, then it may be ambiguous as to which | |
| Components represent the next and previous Components to focus during | |
| normal focus traversal. Thus, the current | |
| <code>KeyboardFocusManager</code> maintains a reference to the | |
| "current" focus cycle root, which is global across all contexts. The | |
| current focus cycle root is used to resolve the ambiguity. | |
| <p> | |
| For up-cycle traversal, the focus owner is set to the current focus | |
| owner's focus cycle root, and the current focus cycle root is set to | |
| the new focus owner's focus cycle root. If, however, the current focus | |
| owner's focus cycle root is a top-level window, then the focus owner | |
| is set to the focus cycle root's default component to focus, and the | |
| current focus cycle root is unchanged. | |
| <p> | |
| For down-cycle traversal, if the current focus owner is a focus cycle | |
| root, then the focus owner is set to the current focus owner's default | |
| component to focus, and the current focus cycle root is set to the | |
| current focus owner. If the current focus owner is not a focus cycle | |
| root, then no focus traversal operation occurs. | |
| <a name="FocusTraversalPolicy"></a> | |
| <h3>FocusTraversalPolicy</h3> | |
| <p> | |
| A <code>FocusTraversalPolicy</code> defines the order in which Components within | |
| a particular focus cycle root or focus traversal policy provider are | |
| traversed. Instances of <code>FocusTraversalPolicy</code> can be shared across | |
| Containers, allowing those Containers to implement the same traversal policy. | |
| FocusTraversalPolicies do not need to be reinitialized when the | |
| focus-traversal-cycle hierarchy changes. | |
| <p> | |
| Each <code>FocusTraversalPolicy</code> must define the following | |
| five algorithms: | |
| <ol> | |
| <li>Given a focus cycle root and a Component <b>a</b> in that cycle, the | |
| next Component after <b>a</b>. | |
| <li>Given a focus cycle root and a Component <b>a</b> in that cycle, the | |
| previous Component before <b>a</b>. | |
| <li>Given a focus cycle root, the "first" Component in that cycle. | |
| The "first" Component is the Component to focus when traversal | |
| wraps in the forward direction. | |
| <li>Given a focus cycle root, the "last" Component in that cycle. | |
| The "last" Component is the Component to focus when traversal | |
| wraps in the reverse direction. | |
| <li>Given a focus cycle root, the "default" Component in that cycle. | |
| The "default" Component will be the first to receive focus when | |
| traversing down into a new focus traversal cycle. This may be the | |
| same as the "first" Component, but need not be. | |
| </ol> | |
| <p> | |
| A <code>FocusTraversalPolicy</code> may optionally provide an | |
| algorithm for the following: | |
| <blockquote> | |
| Given a Window, the "initial" Component in that Window. The initial | |
| Component will be the first to receive focus when the Window is | |
| first made visible. By default, this is the same as the "default" | |
| Component. | |
| </blockquote> | |
| In addition, Swing provides a subclass of <code>FocusTraversalPolicy</code>, | |
| <code>InternalFrameFocusTraversalPolicy</code>, which allows developers | |
| to provide an algorithm for the following: | |
| <blockquote> | |
| Given a <code>JInternalFrame</code>, the "initial" Component in that | |
| <code>JInternalFrame</code>. The initial Component is the first to | |
| receive focus when the <code>JInternalFrame</code> is first selected. | |
| By default, this is the same as the <code>JInternalFrame</code>'s | |
| default Component to focus. | |
| </blockquote> | |
| A <code>FocusTraversalPolicy</code> is installed on a Container using | |
| Container.<code>setFocusTraversalPolicy</code>. If a policy is not explicitly | |
| set, then a Container inherits its policy from its nearest focus-cycle-root | |
| ancestor. Top-levels initialize their focus traversal policies using the context | |
| default policy. The context default policy is established by using | |
| KeyboardFocusManager. <code>setDefaultFocusTraversalPolicy</code>. | |
| <p> | |
| AWT provides two standard <code>FocusTraversalPolicy</code> | |
| implementations for use by client code. | |
| <ol> | |
| <li><code>ContainerOrderFocusTraversalPolicy</code>: Iterates across the | |
| Components in a focus traversal cycle in the order they were added | |
| to their Containers. Each Component is tested for fitness using the | |
| accept(Component) method. By default, a Component is fit only if it | |
| is visible, displayable, enabled, and focusable. | |
| <li>By default, ContainerOrderFocusTraversalPolicy implicitly transfers | |
| focus down-cycle. That is, during normal forward focus traversal, | |
| the Component traversed after a focus cycle root will be the | |
| focus-cycle-root's default Component to focus, regardless of whether | |
| the focus cycle root is a traversable or non-traversable Container | |
| (see the pic.1,2 below). Such behavior provides backward compatibility | |
| with applications designed without the concepts of up- and down-cycle | |
| traversal. | |
| <li><code>DefaultFocusTraversalPolicy</code>: A subclass of | |
| <code>ContainerOrderFocusTraversalPolicy</code> which redefines | |
| the fitness test. If client code has explicitly set the | |
| focusability of a Component by either overriding | |
| <code>Component.isFocusTraversable()</code> or | |
| <code>Component.isFocusable()</code>, or by calling | |
| <code>Component.setFocusable(boolean)</code>, then a | |
| <code>DefaultFocusTraversalPolicy</code> behaves exactly | |
| like a <code>ContainerOrderFocusTraversalPolicy</code>. If, | |
| however, the Component is relying on default focusability, then a | |
| <code>DefaultFocusTraversalPolicy</code> will reject all | |
| Components with non-focusable peers. | |
| <br> | |
| The focusability of a peer is implementation-dependent. Sun | |
| recommends that all implementations for a particular native platform | |
| construct peers with the same focusability. The recommendations for | |
| Windows and Unix are that Canvases, Labels, Panels, Scrollbars, | |
| ScrollPanes, Windows, and lightweight Components have non-focusable | |
| peers, and all other Components have focusable peers. These | |
| recommendations are used in the Sun AWT implementations. Note that | |
| the focusability of a Component's peer is different from, and does | |
| not impact, the focusability of the Component itself. | |
| </ol> | |
| <p> | |
| Swing provides two additional, standard FocusTraversalPolicy | |
| implementations for use by client code. Each implementation is an | |
| InternalFrameFocusTraversalPolicy. | |
| <ol> | |
| <li>SortingFocusTraversalPolicy: Determines traversal order by | |
| sorting the Components of a focus traversal cycle based on a given | |
| Comparator. Each Component is tested for fitness using the | |
| accept(Component) method. By default, a Component is fit only if it | |
| is visible, displayable, enabled, and focusable. | |
| <li>By default, SortingFocusTraversalPolicy implicitly transfers focus | |
| down-cycle. That is, during normal forward focus traversal, the | |
| Component traversed after a focus cycle root will be the | |
| focus-cycle-root's default Component to focus, regardless of | |
| whether the focus cycle root is a traversable or non-traversable | |
| Container (see the pic.1,2 below). Such behavior provides backward | |
| compatibility with applications designed without the concepts of | |
| up- and down-cycle traversal. | |
| <li>LayoutFocusTraversalPolicy: A subclass of | |
| SortingFocusTraversalPolicy which sorts Components based on their | |
| size, position, and orientation. Based on their size and position, | |
| Components are roughly categorized into rows and columns. For a | |
| Container with horizontal orientation, columns run left-to-right or | |
| right-to-left, and rows run top-to-bottom. For a Container with | |
| vertical orientation, columns run top-to-bottom and rows run | |
| left-to-right or right-to-left. All columns in a row are fully | |
| traversed before proceeding to the next row. | |
| <br> | |
| In addition, the fitness test is extended to exclude JComponents | |
| that have or inherit empty InputMaps. | |
| </ol> | |
| <p> | |
| The figure below shows an implicit focus transfer: | |
| <br><img src="ImplicitFocusTransfer.gif" align=middle alt="Implicit focus transfer."><br> | |
| Assume the following: | |
| <ul> | |
| <li><b>A</b>, <b>B</b> and <b>C</b> are components in some window (a container) | |
| <li><b>R</b> is a container in the window and it is a parent of <b>B</b> and <b>C</b>. | |
| Besides, <b>R</b> is a focus cycle root. | |
| <li><b>B</b> is the default component in the focul traversal cycle of <b>R</b> | |
| <li><b>R</b> is a traversable Container in the pic.1, and it is a non-traversable | |
| Container in the pic.2. | |
| <li>In such a case a forward traversal will look as follows: | |
| <ul> | |
| <li> pic.1 : <b>A</b> -> <b>R</b> -> <b>B</b> -> <b>C</b> | |
| <li> pic.2 : <b>A</b> -> <b>B</b> -> <b>C</b> | |
| </ul> | |
| </ul> | |
| <p> | |
| Swing applications, or mixed Swing/AWT applications, that use one of | |
| the standard look and feels, or any other look and feel derived from | |
| BasicLookAndFeel, will use LayoutFocusTraversalPolicy for all | |
| Containers by default. | |
| <p> | |
| All other applications, including pure AWT applications, will use | |
| <code>DefaultFocusTraversalPolicy</code> by default. | |
| <a name="FocusTraversalPolicyProviders"></a> | |
| <h3>Focus Traversal Policy Providers</h3> | |
| <p> | |
| A Container that isn't a focus cycle root has an option to provide a | |
| FocusTraversalPolicy of its own. To do so, one needs to set Container's focus | |
| traversal policy provider property to <code>true</code> with the call to | |
| <blockquote> | |
| <code>Container.setFocusTraversalPolicyProvider(boolean)</code> | |
| </blockquote> | |
| To determine whether a Container is a focus traversal policy provider, the | |
| following method should be used: | |
| <blockquote> | |
| <code>Container.isFocusTraversalPolicyProvider()</code> | |
| </blockquote> | |
| If focus traversal policy provider property is set on a focus cycle root, it | |
| isn't considered a focus traversal policy provider and behaves just like any | |
| other focus cycle root. | |
| <p> | |
| The main difference between focus cycle roots and focus traversal policy | |
| providers is that the latter allow focus to enter and leave them just as all other | |
| Containers. However, children inside focus traversal policy provider are | |
| traversed in the order determined by provider's FocusTraversalPolicy. In order | |
| to enable focus traversal policy providers to behave this way, | |
| FocusTraversalPolicies treat them in the following manner: | |
| <ul> | |
| <li> Focus traversal policy providers can be passed to FocusTraversalPolicy | |
| methods instead of focus cycle roots. | |
| <li> When calculating next or previous Component in | |
| <code>FocusTraversalPolicy.getComponentAfter</code> or | |
| <code>FocusTraversalPolicy.getComponentBefore</code>, | |
| <ul> | |
| <li>if a Component is a child of a focus traversal policy provider, | |
| the next and previous for this Component are determined using this | |
| focus traversal policy provider's FocusTraversalPolicy. However, | |
| in order for focus to leave the provider, the following rules are | |
| applied: | |
| <ul> | |
| <li> if at some point the <code>next</code> found Component is | |
| the <code>first</code> Component of focus traversal policy | |
| provider, the Component after the focus traversal policy | |
| provider is returned | |
| <li> if at some point the <code>previous</code> found Component is | |
| the <code>last</code> Component of focus traversal policy | |
| provider, the Component before the focus traversal policy | |
| provider is returned | |
| </ul> | |
| <li> When calculating the next Component in | |
| <code>FocusTraversalPolicy.getComponentAfter</code>, | |
| <ul> | |
| <li> if an obtained Component is a non-traversable Container and | |
| it is a focus traversal policy provider, then the default Component | |
| of that provider is returned | |
| <li> if the Component passed to the <code>FocusTraversalPolicy.getComponentAfter</code> | |
| method is a traversable Container and it is a focus | |
| traversal policy provider, then the default Component of this provider | |
| is returned | |
| </ul> | |
| <li> When calculating the previous Component in | |
| <code>FocusTraversalPolicy.getComponentBefore</code>, | |
| <ul> | |
| <li> if an obtained Component is a Container (traversable or | |
| non-traversable) and it is a focus traversal policy provider, then | |
| the last Component of that provider is returned | |
| </ul> | |
| </ul> | |
| <li> When calculating the first Component in FocusTraversalPolicy.getFirstComponent, | |
| <ul> | |
| <li> if an obtained Component is a non-traversable Container and it is a focus | |
| traversal policy provider, then the default Component of that provider is | |
| returned | |
| <li> if an obtained Component is a traversable Container and it is a focus traversal | |
| policy provider, then that Container itself is returned | |
| </ul> | |
| <li> When calculating the last Component in FocusTraversalPolicy.getLastComponent, | |
| <ul> | |
| <li> if an obtained Component is a Container (traversable or non-traversable) | |
| and it is a focus traversal policy provider, then the last Component of | |
| that provider is returned | |
| </ul> | |
| </ul> | |
| <a name="ProgrammaticTraversal"></a> | |
| <h3>Programmatic Traversal</h3> | |
| <p> | |
| In addition to user-initiated focus traversal, client code can | |
| initiate a focus traversal operation programmatically. To client code, | |
| programmatic traversals are indistinguishable from user-initiated | |
| traversals. The preferred way to initiate a programmatic traversal is | |
| to use one of the following methods on <code>KeyboardFocusManager</code>: | |
| <ul> | |
| <li><code>KeyboardFocusManager.focusNextComponent()</code> | |
| <li><code>KeyboardFocusManager.focusPreviousComponent()</code> | |
| <li><code>KeyboardFocusManager.upFocusCycle()</code> | |
| <li><code>KeyboardFocusManager.downFocusCycle()</code> | |
| </ul> | |
| <p> | |
| Each of these methods initiates the traversal operation with the | |
| current focus owner. If there is currently no focus owner, then no | |
| traversal operation occurs. In addition, if the focus owner is not a | |
| focus cycle root, then downFocusCycle() performs no traversal | |
| operation. | |
| <p> | |
| <code>KeyboardFocusManager</code> also supports the following variants | |
| of these methods: | |
| <ul> | |
| <li><code>KeyboardFocusManager.focusNextComponent(Component)</code> | |
| <li><code>KeyboardFocusManager.focusPreviousComponent(Component)</code> | |
| <li><code>KeyboardFocusManager.upFocusCycle(Component)</code> | |
| <li><code>KeyboardFocusManager.downFocusCycle(Container)</code> | |
| </ul> | |
| Each of these methods initiates the traversal operation with the | |
| specified Component rather than the focus owner. That is, the | |
| traversal occurs as though the specified Component is the focus owner, | |
| though it need not be. | |
| <p> | |
| Alternate, but equivalent, APIs are defined on the Component and | |
| Container classes themselves: | |
| <ul> | |
| <li><code>Component.transferFocus()</code> | |
| <li><code>Component.transferFocusBackward()</code> | |
| <li><code>Component.transferFocusUpCycle()</code> | |
| <li><code>Container.transferFocusDownCycle()</code> | |
| </ul> | |
| As with the <code>KeyboardFocusManager</code> variants, each of these methods | |
| initiates the traversal operation as though the Component is the focus | |
| owner, though it need not be. | |
| <p> | |
| Also note that hiding or disabling the focus owner, directly or | |
| indirectly via an ancestor, or making the focus owner non-displayable | |
| or non-focusable, initiates an automatic, forward focus traversal. | |
| While hiding any ancestor, lightweight or heavyweight, will always | |
| indirectly hide its children, only disabling a heavyweight ancestor | |
| will disable its children. Thus, disabling a lightweight ancestor of | |
| the focus owner does not automatically initiate a focus traversal. | |
| <p> | |
| If client code initiates a focus traversal, and there is no other | |
| Component to focus, then the focus owner remains unchanged. If client | |
| code initiates an automatic focus traversal by hiding the focus owner, | |
| directly or indirectly, or by making the focus owner non-displayable or | |
| non-focusable, and there is no other Component to focus, then the | |
| global focus owner is cleared. If client code initiates an automatic | |
| focus traversal by disabling the focus owner, directly or indirectly, | |
| and there is no other Component to focus, then the focus owner remains | |
| unchanged. | |
| <a name="Focusability"></a> | |
| <h3>Focusability</h3> | |
| <p> | |
| A focusable Component can become the focus owner ("focusability") and | |
| participates in keyboard focus traversal ("focus traversability") with | |
| a FocusTraversalPolicy. There is no separation of these two concepts; | |
| a Component must either be both focusable and focus traversable, or | |
| neither. | |
| A Component expresses this state via the isFocusable() method. By | |
| default, all Components return true from this method. Client code can | |
| change this default by calling Component.setFocusable(boolean). | |
| <a name="FocusableWindows"></a> | |
| <h3>Focusable Windows</h3> | |
| <p> | |
| To support palette windows and input methods, client code can prevent | |
| a Window from becoming the focused Window. By transitivity, this | |
| prevents the Window or any of its descendants from becoming the focus | |
| owner. Non-focusable Windows may still own Windows that are | |
| focusable. By default, every Frame and Dialog is focusable. Every | |
| Window which is not a Frame or Dialog, but whose nearest owning Frame | |
| or Dialog is showing on the screen, and which has at least one | |
| Component in its focus traversal cycle, is also focusable by | |
| default. To make a Window non-focusable, use | |
| Window.setFocusableWindowState(false). | |
| <p> | |
| If a Window is non-focusable, this restriction is enforced when the | |
| <code>KeyboardFocusManager</code> sees a <code>WINDOW_GAINED_FOCUS</code> | |
| event for the Window. At this point, the focus change is rejected and | |
| focus is reset to a different Window. The rejection recovery scheme | |
| is the same as if a <code>VetoableChangeListener</code> rejected the | |
| focus change. See <a href="#FocusAndVetoableChangeListener">Focus | |
| and VetoableChangeListener</a>. | |
| <p> | |
| Because the new focus implementation requires that KeyEvents intended | |
| for a Window or its descendants be proxied through a child of the | |
| Window's owner, and because this proxy must be mapped on X11 in order | |
| to receive events, a Window whose nearest owning Frame or Dialog is | |
| not showing could never receive KeyEvents on X11. To support this | |
| restriction, we have made a distinction between a Window's "window | |
| focusability" and its "window focusability state". A Window's | |
| focusability state is combined with the showing state of the Window's | |
| nearest owning Frame or Dialog to determine the Window's focusability. | |
| By default, all Windows have a focusability state of true. Setting a | |
| Window's focusability state to false ensures that it will not become | |
| the focused Window regardless of the showing state of its nearest | |
| owning Frame or Dialog. | |
| <p> | |
| Swing allows applications to create JWindows with null owners. Swing | |
| constructs all such JWindows so that they are owned by a private, | |
| hidden Frame. Because the showing state of this Frame will always be | |
| false, a JWindow constructed will a null owner can never be the | |
| focused Window, even if it has a Window focusability state of true. | |
| <p> | |
| If the focused Window is made non-focusable, then the AWT will attempt | |
| to focus the most recently focused Component of the Window's | |
| owner. The Window's owner will thus become the new focused Window. If | |
| the Window's owner is also a non-focusable Window, then the focus | |
| change request will proceed up the ownership hierarchy recursively. | |
| Since not all platforms support cross-Window focus changes (see | |
| <a href=#RequestingFocus>Requesting Focus</a>), it is possible that | |
| all such focus change requests will fail. In this case, the global | |
| focus owner will be cleared and the focused Window will remain unchanged. | |
| <a name="RequestingFocus"></a> | |
| <h3>Requesting Focus</h3> | |
| <p> | |
| A Component can request that it become the focus owner by calling | |
| <code>Component.requestFocus()</code>. This initiates a permanent | |
| focus transfer to the Component only if the Component is displayable, | |
| focusable, visible and all of its ancestors (with the exception of the | |
| top-level Window) are visible. The request will be immediately denied if | |
| any of these conditions is not met. A disabled Component may be | |
| the focus owner; however, in this case, all KeyEvents will be discarded. | |
| <p> | |
| The request will also be denied if the Component's top-level Window is | |
| not the focused Window and the platform does not support requesting | |
| focus across Windows. If the request is denied for this reason, the | |
| request is remembered and will be granted when the Window is later | |
| focused by the user. Otherwise, the focus change request changes the | |
| focused Window as well. | |
| <p> | |
| There is no way to determine synchronously whether a focus change | |
| request has been granted. Instead, client code must install a | |
| FocusListener on the Component and watch for the delivery of a | |
| <code>FOCUS_GAINED</code> event. Client code must not assume that | |
| the Component is the focus owner until it receives this event. | |
| The event may or may not be delivered before <code>requestFocus()</code> | |
| returns. Developers must not assume one behavior or the other. | |
| <p> | |
| The AWT supports type-ahead if all focus change requests are made on | |
| the EventDispatchThread. If client code requests a focus change, and | |
| the AWT determines that this request might be granted by the native | |
| windowing system, then the AWT will notify the current | |
| KeyboardFocusManager that is should enqueue all KeyEvents with a | |
| timestamp later than the that of the event currently being handled. | |
| These KeyEvents will not be dispatched until the new Component becomes | |
| the focus owner. The AWT will cancel the delayed dispatching request | |
| if the focus change does not succeed at the native level, if the | |
| Component's peer is disposed, or if the focus change is vetoed by a | |
| VetoableChangeListener. KeyboardFocusManagers are not required to | |
| support type-ahead if a focus change request is made from a thread | |
| other than the EventDispatchThread. | |
| <p> | |
| Because <code>Component.requestFocus()</code> cannot be implemented | |
| consistently across platforms, developers are encouraged to use | |
| <code>Component.requestFocusInWindow()</code> instead. This method | |
| denies cross-Window focus transfers on all platforms automatically. | |
| By eliminating the only platform-specific element of the focus transfer, | |
| this method achieves consistent cross-platform behavior. | |
| <p> | |
| In addition, <code>requestFocusInWindow()</code> returns a boolean value. | |
| If 'false' is returned, the request is guaranteed to fail. If 'true' is | |
| returned, the request will succeed unless it is vetoed, or an | |
| extraordinary event, such as disposal of the Component's peer, occurs | |
| before the request can be granted by the native windowing | |
| system. Again, while a return value of 'true' indicates that the | |
| request is likely to succeed, developers must never assume that this | |
| Component is the focus owner until this Component receives a | |
| <code>FOCUS_GAINED</code> event. | |
| <p> | |
| If client code wants no Component in the application to be the focus | |
| owner, it can call the method <code>KeyboardFocusManager</code>. | |
| <code>clearGlobalFocusOwner()</code> on the current | |
| <code>KeyboardFocusManager</code>. If there exists a focus owner | |
| when this method is called, the focus owner will receive a permanent | |
| <code>FOCUS_LOST</code> event. After this point, the AWT | |
| focus implementation will discard all KeyEvents until the user or | |
| client code explicitly sets focus to a Component. | |
| <p> | |
| The Component class also supports variants of <code>requestFocus</code> and | |
| <code>requestFocusInWindow</code> that allow client code to specify | |
| a temporary state. | |
| See <a href="#TemporaryFocusEvents">Temporary FocusEvents</a> | |
| <a name="FocusAndPropertyChangeListener"></a> | |
| <h3>Focus and PropertyChangeListener</h3> | |
| <p> | |
| Client code can listen to changes in context-wide focus state, or to | |
| changes in focus-related state in Components, via | |
| PropertyChangeListeners. | |
| <p> | |
| The <code>KeyboardFocusManager</code> supports the following properties: | |
| <ol> | |
| <li><code>focusOwner</code>: the focus owner | |
| <li><code>focusedWindow</code>: the focused Window | |
| <li><code>activeWindow</code>: the active Window | |
| <li><code>defaultFocusTraversalPolicy</code>: the default focus | |
| traversal policy | |
| <li><code>forwardDefaultFocusTraversalKeys</code>: the Set of default | |
| <code>FORWARD_TRAVERSAL_KEYS</code> | |
| <li><code>backwardDefaultFocusTraversalKeys</code>: the Set of default | |
| <code>BACKWARD_TRAVERSAL_KEYS</code> | |
| <li><code>upCycleDefaultFocusTraversalKeys</code>: the Set of default | |
| <code>UP_CYCLE_TRAVERSAL_KEYS</code> | |
| <li><code>downCycleDefaultFocusTraversalKeys</code>: the Set of default | |
| <code>DOWN_CYCLE_TRAVERSAL_KEYS</code> | |
| <li><code>currentFocusCycleRoot</code>: the current focus cycle root | |
| </ol> | |
| <p> | |
| A <code>PropertyChangeListener</code> installed on the current | |
| <code>KeyboardFocusManager</code> will only see these changes within | |
| the <code>KeyboardFocusManager</code>'s context, even though the | |
| focus owner, focused Window, active Window, and current focus cycle | |
| root comprise the global focus state shared by all contexts. | |
| We believe this is less intrusive than requiring client code to pass | |
| a security check before installing a <code>PropertyChangeListener</code>. | |
| <p> | |
| Component supports the following focus-related properties: | |
| <ol> | |
| <li><code>focusable</code>: the Component's focusability | |
| <li><code>focusTraversalKeysEnabled</code>: the Component's | |
| focus traversal keys enabled state | |
| <li><code>forwardFocusTraversalKeys</code>: the Component's Set of | |
| <code>FORWARD_TRAVERSAL_KEYS</code> | |
| <li><code>backwardFocusTraversalKeys</code>: the Component's Set of | |
| <code>BACKWARD_TRAVERSAL_KEYS</code> | |
| <li><code>upCycleFocusTraversalKeys</code>: the Component's Set of | |
| <code>UP_CYCLE_TRAVERSAL_KEYS</code> | |
| </ol> | |
| <p> | |
| In addition to the Component properties, Container supports the | |
| following focus-related properties: | |
| <ol> | |
| <li><code>downCycleFocusTraversalKeys</code>: the Container's Set of | |
| <code>DOWN_CYCLE_TRAVERSAL_KEYS</code> | |
| <li><code>focusTraversalPolicy</code>: the Container's focus | |
| traversal policy | |
| <li><code>focusCycleRoot</code>: the Container's focus-cycle-root state | |
| </ol> | |
| <p> | |
| In addition to the Container properties, Window supports the following | |
| focus-related property: | |
| <ol> | |
| <li><code>focusableWindow</code>: the Window's focusable Window state | |
| </ol> | |
| <p> | |
| Also note that a <code>PropertyChangeListener</code> installed on a | |
| Window will never see a <code>PropertyChangeEvent</code> for the | |
| <code>focusCycleRoot</code> property. | |
| A Window is always a focus cycle root; this property cannot change. | |
| <p> | |
| <a name="FocusAndVetoableChangeListener"></a> | |
| <h3>Focus and VetoableChangeListener</h3> | |
| <p> | |
| The <code>KeyboardFocusManager</code> also supports | |
| <code>VetoableChangeListener</code>s for the following properties: | |
| <ol> | |
| <li>"focusOwner": the focus owner | |
| <li>"focusedWindow": the focused Window | |
| <li>"activeWindow": the active Window | |
| </ol> | |
| If a VetoableChangeListener vetoes a focus or activation change by | |
| throwing a PropertyVetoException, the change is aborted. Any | |
| VetoableChangeListeners which had already approved the change will | |
| asynchronously receive PropertyChangeEvents indicating a reversion of | |
| state to the previous value. | |
| <p> | |
| VetoableChangeListeners are notified of the state change before the | |
| change is reflected in the KeyboardFocusManager. Conversely, | |
| PropertyChangeListeners are notified after the change is reflected. | |
| It follows that all VetoableChangeListeners will be notified before | |
| any PropertyChangeListener. | |
| <p> | |
| VetoableChangeListeners must be idempotent, and must veto both loss | |
| and gain events for a particular focus change (e.g., both | |
| <code>FOCUS_LOST</code> and <code>FOCUS_GAINED</code>). For example, | |
| if a <code>VetoableChangeListener</code> vetoes a <code>FOCUS_LOST</code> | |
| event, a <code>KeyboardFocusManager</code> is not required to search the | |
| <code>EventQueue</code> and remove the associated pending | |
| <code>FOCUS_GAINED</code> event. Instead, the | |
| <code>KeyboardFocusManager</code> is free to attempt to | |
| dispatch this event and it is the responsibility of the | |
| <code>VetoableChangeListener</code> to veto it as well. In addition, | |
| during processing of the <code>FOCUS_GAINED</code> event, the | |
| <code>KeyboardFocusManager</code> may attempt to resync the global | |
| focus state by synthesizing another <code>FOCUS_LOST</code> event. | |
| This event must be vetoed just as the first <code>FOCUS_LOST</code> event was. | |
| <p> | |
| A <code>KeyboardFocusManager</code> may not hold any locks while | |
| notifying <code>PropertyChangeListener</code>s of a state change. | |
| This requirement is relaxed for <code>VetoableChangeListeners</code>, | |
| however. Therefore, client-definied <code>VetoableChangeListener</code>s | |
| should avoid acquiring additional locks inside | |
| <code>vetoableChange(PropertyChangeEvent)</code> as this may lead to deadlock. | |
| If a focus or activation change is rejected, the KeyboardFocusManager | |
| will initiate rejection recovery as follows: | |
| <ul> | |
| <li>If a focused or active Window change was rejected, then the | |
| focused or active Window will be reset to the Window which was | |
| previously the focused or active Window. If there is no such | |
| Window, then the <code>KeyboardFocusManager</code> will clear | |
| the global focus owner. | |
| <li>If a focus owner change was rejected, then the focus owner will be | |
| reset to the Component which was previously the focus owner. If | |
| that is not possible, then it will be reset to the next Component | |
| in the focus traversal cycle after the previous focus owner. If | |
| that is also not possible, then the <code>KeyboardFocusManager</code> | |
| will clear the global focus owner. | |
| </ul> | |
| <code>VetoableChangeListener</code>s must be careful to avoid vetoing focus | |
| changes initiated as a result of veto rejection recovery. Failure | |
| to anticipate this situation could lead to an infinite cycle of | |
| vetoed focus changes and recovery attempts. | |
| <a name="ZOrder"></a> | |
| <h3>Z-Order</h3> | |
| <p> | |
| On some native windowing systems, the Z-order of a Window can affect | |
| its focused or active (if applicable) state. On Microsoft Windows, the | |
| top-most Window is naturally the focused Window as well. However, on | |
| Solaris, many window managers use a point-to-focus model that ignores | |
| Z-order in determining the focused Window. | |
| When focusing or activating Windows, the AWT adheres to the UI | |
| requirements of the native platform. Therefore, the focus behavior of | |
| Z-order-related methods such as: | |
| <ul> | |
| <li><code>Window.toFront()</code> | |
| <li><code>Window.toBack()</code> | |
| <li><code>Window.show()</code> | |
| <li><code>Window.hide()</code> | |
| <li><code>Window.setVisible(boolean)</code> | |
| <li><code>Window.dispose()</code> | |
| <li><code>Frame.setState(int)</code> | |
| </ul> | |
| is platform-dependent. In JDK 1.4, the behavior of these methods on | |
| Microsoft Windows and Solaris is as follows: | |
| <ul> | |
| <li><code>Window.toFront()</code>:<br> | |
| <b>Microsoft Windows</b>: The Window is moved to front, if possible. | |
| While we will always be able to move this Window in front of other | |
| Windows in the same VM, Windows 98 and Windows 2000 do not allow an | |
| application to bring any of its windows to the front unless one | |
| of that application's windows is already in the foreground. In | |
| this case, Windows will instead flash the Window's icon in the | |
| taskbar. If the Window is moved to the front, it will be made | |
| the focused and (if applicable) active Window. | |
| <br> | |
| <b>Solaris</b>: The Window is moved to front. In a point-to-focus | |
| window manager, the Window will become the focused Window if it | |
| is the top-most Window underneath the cursor. In a click-to-focus | |
| window manager, the focused Window will remain unchanged. | |
| <li><code>Window.toBack()</code>:<br> | |
| <b>Microsoft Windows</b>: The Window is moved to back. Note however | |
| that Microsoft Windows insists that an owned Window always be in | |
| front of all of its recursive owners. Thus, after the completion of | |
| this operation, the Window may not be the lowest Java Window in the | |
| Z-order. If the Window, or any of its owners, was the focused Window, | |
| then the focused Window is reset to the top-most Window in the VM. | |
| <br> | |
| <b>Solaris</b>: The Window is moved to back. Like Microsoft Windows, | |
| some window managers insist than an owned Window always be in front | |
| of all of its recursive owners. Thus, after the completion of this | |
| operation, the Window may not be the lowest Java Window in the | |
| Z-order. If the Window was the focused Window, it will lose | |
| focus in a point-to-focus window manager if it is no longer the | |
| top-most Window under the cursor. In a click-to-focus window | |
| manager, the focused Window will remain unchanged. | |
| <li><code>Window.show()/Window.setVisible(true)/Frame.setState(NORMAL)</code>:<br> | |
| <b>Microsoft Windows</b>: The Window is moved to front and becomes the focused | |
| Window. | |
| <br> | |
| <b>Solaris</b>: The Window is moved to front. In a point-to-focus focus | |
| window manager, the Window will be focused if it is now the | |
| top-most Window under the cursor. In a click-to-focus window | |
| manager, the Window will become the focused Window. | |
| <li><code>Window.hide()/Window.setVisible(false)/Window.dispose()/ | |
| Frame.setState(ICONIFIED)</code>:<br> | |
| <b>Microsoft Windows</b>: If the Window was the focused Window, the focused | |
| Window is reset to a window chosen by the OS, or to no window. The | |
| window may be in a native application, or a Java application in | |
| another VM. | |
| <br> | |
| <b>Solaris</b>: If the Window was the focused Window, in a point-to- | |
| focus window manager, the top-most Window under the cursor will | |
| become the focused Window. In a click-to-focus window manager, | |
| the focused Window is reset to a window chosen by the window | |
| manager. The window may be in a native application, or a Java | |
| application in another VM. | |
| </ul> | |
| <a name="ReplacingDefaultKeyboardFocusManager"></a> | |
| <h3>Replacing DefaultKeyboardFocusManager</h3> | |
| <p> | |
| <code>KeyboardFocusManager</code>s are pluggable at the browser context | |
| level. Client code can subclass <code>KeyboardFocusManager</code> or | |
| <code>DefaultKeyboardFocusManager</code> to modify the way that WindowEvents | |
| related to focus, FocusEvents, and KeyEvents are handled and | |
| dispatched, and to examine and modify the global focus state. A custom | |
| <code>KeyboardFocusManager</code> can also reject focus changes at a more | |
| fundamental level then a FocusListener or WindowListener ever could. | |
| <p> | |
| While giving a developer ultimate control over the focus model, | |
| replacing the entire <code>KeyboardFocusManager</code> is a difficult process | |
| requiring a thorough understanding of the peer focus layer. | |
| Fortunately, most applications do not need this much control. | |
| Developers are encouraged to use KeyEventDispatchers, | |
| KeyEventPostProcessors, FocusTraversalPolicies, | |
| VetoableChangeListeners, and other concepts discussed in this document | |
| before resorting to a full replacement of the <code>KeyboardFocusManager</code>. | |
| <p> | |
| First note that, because unhindered access to Components in other | |
| contexts represents a security hole, the SecurityManager must grant a | |
| new permission, "replaceKeyboardFocusManager", before client code is | |
| permitted to replace the <code>KeyboardFocusManager</code> with an arbitrary | |
| subclass instance. Because of the security check, replacing the | |
| <code>KeyboardFocusManager</code> is not an option for applications that will be | |
| deployed in environments with a SecurityManager, such as applets in a | |
| browser. | |
| <p> | |
| Once installed, a <code>KeyboardFocusManager</code> instance has | |
| access to the global focus state via a set of protected functions. | |
| The <code>KeyboardFocusManager</code> can only call these functions | |
| if it is installed in the calling thread's context. This ensures | |
| that malicious code cannot circumvent the security check in | |
| <code>KeyboardFocusManager.setCurrentFocusManager</code>. | |
| A <code>KeyboardFocusManager</code> should always work with | |
| the global focus state instead of the context focus state. | |
| Failure to do this will lead to incorrect behavior of the | |
| <code>KeyboardFocusManager</code>. | |
| <p> | |
| The primary responsibility of a <code>KeyboardFocusManager</code> | |
| is the dispatch of the following events: | |
| <ul> | |
| <li>all <code>KeyEvent</code>s | |
| <li>all <code>FocusEvent</code>s | |
| <li><code>WindowEvent.WINDOW_GAINED_FOCUS</code> | |
| <li><code>WindowEvent.WINDOW_LOST_FOCUS</code> | |
| <li><code>WindowEvent.WINDOW_ACTIVATED</code> | |
| <li><code>WindowEvent.WINDOW_DEACTIVATED</code> | |
| </ul> | |
| The peer layer will provide the <code>KeyboardFocusManager</code> | |
| with all of the above events except <code>WINDOW_ACTIVATED</code> | |
| and <code>WINDOW_DEACTIVATED</code>. The <code>KeyboardFocusManager</code> | |
| must synthesize <code>WINDOW_ACTIVATED</code> and | |
| <code>WINDOW_DEACTIVATED</code> events when appropriate and target them | |
| accordingly. | |
| <p> | |
| The <code>KeyboardFocusManager</code> may need to retarget the events | |
| provided by the peer layer to its own notion of the focus owner or | |
| focused Window: | |
| <ul> | |
| <li>A KeyEvent must be retargeted to the focus owner. Because the peer | |
| layer is unaware of any lightweight Components, KeyEvents will | |
| arrive from the peer layer targeted to the focus owner's | |
| heavyweight Container, not the focus owner. | |
| <li>A <code>FOCUS_LOST</code> event must be retargeted to the focus | |
| owner. Again, this is necessary because the peer layer is | |
| unaware of lightweight Components. | |
| <li>A <code>WINDOW_LOST_FOCUS</code> event must be retargeted to | |
| the focused Window. The implementation of the Window class | |
| may cause the native focused Window to differ from the Java | |
| focused Window. | |
| </ul> | |
| <p> | |
| A <code>KeyboardFocusManager</code> must ensure proper event ordering, | |
| and a 1-to-1 correspondence between an event and its opposite event type. | |
| The peer layer does not make any of these guarantees. For example, it is | |
| possible for the peer layer to send a <code>FOCUS_GAINED</code> | |
| event before a <code>WINDOW_GAINED_FOCUS</code> event. | |
| The <code>KeyboardFocusManager</code> is responsible for | |
| ensuring that the <code>WINDOW_GAINED_FOCUS</code> event is dispatched | |
| before the <code>FOCUS_GAINED</code> event. | |
| <p> | |
| Before redispatching an event via <code>KeyboardFocusManager</code>. | |
| <code>redispatchEvent</code>, a <code>KeyboardFocusManager</code> | |
| must attempt to update the global focus state. Typically, this | |
| is done using one of the <code>KeyboardFocusManager.setGlobal*</code> | |
| methods; however, an implementation is free to implement its own methods. | |
| After attempting an update, the <code>KeyboardFocusManager</code> | |
| must verify that the global focus state change | |
| was not rejected. A rejection is detected when a call to the | |
| corresponding <code>getGlobal*</code> method returns a value different than the | |
| value just set. Rejections occur in three standard cases: | |
| <ul> | |
| <li>If the <code>KeyboardFocusManager</code> attempts | |
| to set the global focus owner to a non-focusable Component. | |
| <li>If the <code>KeyboardFocusManager</code> attempts | |
| to set the global focused Window to a non-focusable Window. | |
| <li>If the change is rejected by an installed | |
| <code>VetoableChangeListener</code>. | |
| </ul> | |
| <p> | |
| Client-defined implementations of <code>KeyboardFocusManager</code> | |
| can adjust the set of focus transfers which are rejected by overriding the | |
| accessor and mutator methods for the global focus state. | |
| <p> | |
| If a request to change the global focus state is rejected, the | |
| <code>KeyboardFocusManager</code> must discard the event which prompted | |
| the focus change request. The Component to which the event was targeted | |
| must not receive the event. | |
| <p> | |
| The <code>KeyboardFocusManager</code> is also expected to initiate rejection | |
| recovery as outlined in <a href="#FocusAndVetoableChangeListener">Focus | |
| and VetoableChangeListener</a>. | |
| <p> | |
| Finally, a KeyboardFocusManager must handle the following set of | |
| special cases: | |
| <ul> | |
| <li>When handling a <code>WINDOW_GAINED_FOCUS</code> event, the | |
| <code>KeyboardFocusManager</code> must set focus to the | |
| appropriate child Component of the Window. If a child | |
| Component of the Window previously requested focus, | |
| but the focus change was rejected because the platform | |
| does not support cross-Window focus change requests, | |
| then focus should be set to that child Component. | |
| Otherwise, if the Window has never been focused, focus should be | |
| set to the Window's initial Component to focus. If the Window was | |
| previously focused, focus should be set to the Window's most | |
| recent focus owner. | |
| <li>The <code>KeyboardFocusManager</code> must ensure that the | |
| opposite Component or Window are as accurate as the native | |
| windowing platform permits. For example, the | |
| <code>KeyboardFocusManager</code> may need to | |
| retarget the opposite Component to a lightweight child of the | |
| heavyweight initially specified by the peer layer. | |
| <br> | |
| If the peer layer states that the opposite Component or Window is | |
| <code>null</code>, it is acceptable for the | |
| <code>KeyboardFocusManager</code> to propagate | |
| this value. <code>null</code> indicates that it is highly | |
| probably that no other Component or Window was involved | |
| in the focus or activation change. Because of platform | |
| limitations, this computation may be | |
| subject to a heuristic and could be incorrect. Nevertheless, this | |
| heuristic will be the best possible guess which the peer layer | |
| could make. | |
| <li>Focus and activation changes in which a Component or Window loses | |
| focus or activation to itself must be discarded. | |
| <li>Events posted by the peer layer claiming that the active Window | |
| has lost focus to the focused Window must be discarded. The peer | |
| implementation of the Window class may generate these spurious | |
| events. | |
| </ul> | |
| <a name="Incompatibilities"></a> | |
| <h3>Incompatibilities with Previous Releases</h3> | |
| <p><b>Cross-platform changes:</b> | |
| <ol> | |
| <li>The default focus traversability for all Components is now | |
| 'true'. Previously, some Components (in particular, all | |
| lightweights), had a default focus traversability of 'false'. Note | |
| that despite this change, however, the | |
| <code>DefaultFocusTraversalPolicy</code> for all AWT Containers | |
| will preserve the traversal order of previous releases. | |
| <li>A request to focus a non-focus traversable (i.e., non-focusable) | |
| Component will be denied. Previously, such requests were granted. | |
| <li><code>Window.toFront()</code> and <code>Window.toBack()</code> | |
| now perform no operation if the Window is not visible. | |
| Previously, the behavior was platform-dependent. | |
| <li>KeyListeners installed on <code>Component</code>s | |
| will no longer see <code>KeyEvent</code>s that map to focus | |
| traversal operations, and | |
| <code>Component.handleEvent()</code> will no longer be invoked | |
| for such events. Previously, AWT Components saw these events | |
| and had an opportunity to consume them before AWT | |
| initiated focus traversal. Code that requires this | |
| functionality should instead disable focus traversal keys on | |
| its <code>Component</code>s and handle focus traversal | |
| itself. Alternately, the code can use an | |
| <code>AWTEventListener</code> or | |
| <code>KeyEventDispatcher</code> to pre-listen to all | |
| <code>KeyEvent</code>s. | |
| </ol> | |
| <p><b>Changes specific to Microsoft Windows:</b> | |
| <ol> | |
| <li><code>Window.toBack()</code> changes the focused Window to | |
| the top-most Window after the Z-order change. | |
| <li><code>requestFocus()</code> now allows cross-Window focus | |
| change requests in all cases. Previously, requests were granted | |
| for heavyweights, but denied for lightweights. | |
| </ol> | |
| </body> | |
| </html> |