TopBlend: Here is the first difference. There are 1 differences. is old. is new.

The AWT Focus Subsystem

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.

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.

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 WINDOW_ACTIVATED events and thus could never be activated, and only active Windows could contain focused Components.

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.

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.

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:

Overview of KeyboardFocusManager

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.

KeyboardFocusManager introduces seven main concepts and their terminology:

  1. The "focus owner" -- the Component which typically receives keyboard input.
  2. 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.
  3. The "focused Window" -- the Window which contains the "focus owner".
  4. 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".
  5. "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.
  6. "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.
  7. "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.
  8. "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 setFocusTraversalPolicyProvider on the Container.

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.

Here is an example:
Three groups as described below: ABCF BDE and DGH.

Assume the following:

There are a total of three focus cycle roots in this example:
  1. A is a root, and A , B , C , and F are members of A 's cycle.
  2. B is a root, and B , D , and E are members of B 's cycle.
  3. D is a root, and D , G , and H are members of D 's cycle.
Windows are the only Containers which, by default, are focus cycle roots.KeyboardFocusManager is an abstract class. AWT provides a defaultimplementation in the DefaultKeyboardFocusManager class.

KeyboardFocusManager and Browser Contexts

Some browsers partition applets in different code bases into separatecontexts, and establish walls between these contexts. Each thread andeach Component is associated with a particular context and cannotinterfere with threads or access Components in other contexts. In sucha scenario, there will be one KeyboardFocusManager per context. Otherbrowsers place all applets into the same context, implying that therewill be only a single, global KeyboardFocusManager for allapplets. This behavior is implementation-dependent. Consult yourbrowser's documentation for more information. No matter how manycontexts there may be, however, there can never be more than one focusowner, focused Window, or active Window, per ClassLoader.

KeyEventDispatcher and KeyEventPostProcessor

While the user's KeyEvents should generally be delivered to the focusowner, there are rare cases where this is not desirable. An inputmethod is an example of a specialized Component that should receiveKeyEvents even though its associated text Component is and shouldremain the focus owner.

A KeyEventDispatcher is a lightweight interface that allows clientcode to pre-listen to all KeyEvents in a particular context. Instancesof classes that implement the interface and are registered with thecurrent KeyboardFocusManager will receive KeyEvents before they aredispatched to the focus owner, allowing the KeyEventDispatcher toretarget the event, consume it, dispatch it itself, or make otherchanges.

For consistency, KeyboardFocusManager itself is aKeyEventDispatcher. By default, the current KeyboardFocusManager willbe the sink for all KeyEvents not dispatched by the registeredKeyEventDispatchers. The current KeyboardFocusManager cannot becompletely deregistered as a KeyEventDispatcher. However, if aKeyEventDispatcher reports that it dispatched the KeyEvent, regardlessof whether it actually did so, the KeyboardFocusManager will take nofurther action with regard to the KeyEvent. (While it is possible forclient code to register the current KeyboardFocusManager as aKeyEventDispatcher one or more times, there is no obvious reason whythis would be necessary, and therefore it is not recommended.)

Client-code may also post-listen to KeyEvents in a particular contextusing the KeyEventPostProcessor interface. KeyEventPostProcessorsregistered with the current KeyboardFocusManager will receiveKeyEvents after the KeyEvents have been dispatched to and handled bythe focus owner. The KeyEventPostProcessors will also receiveKeyEvents that would have been otherwise discarded because noComponent in the application currently owns the focus. This will allowapplications to implement features that require global KeyEvent post-handling, such as menu shortcuts.

Like KeyEventDispatcher, KeyboardFocusManager also implementsKeyEventPostProcessor, and similar restrictions apply to its use inthat capacity.

FocusEvent and WindowEvent

The AWT defines the following six event types central to the focusmodel in two different java.awt.event classes:

  1. WindowEvent.WINDOW_ACTIVATED: 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.
  2. WindowEvent.WINDOW_GAINED_FOCUS: This event is dispatched to a Window when it becomes the focused Window. Only focusable Windows can receive this event.
  3. FocusEvent.FOCUS_GAINED: This event is dispatched to a Component when it becomes the focus owner. Only focusable Components can receive this event.
  4. FocusEvent.FOCUS_LOST: This event is dispatched to a Component when it is no longer the focus owner.
  5. WindowEvent.WINDOW_LOST_FOCUS: This event is dispatched to a Window when it is no longer the focused Window.
  6. WindowEvent.WINDOW_DEACTIVATED: 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.

Event Delivery

The events are dispatched in the order in which they are presentedabove. That is, if the user clicks on a focusable child Component a of an inactive Frame b , the following events willbe dispatched and handled in order:

  1. b will receive a WINDOW_ACTIVATED event.
  2. Next, b will receive a WINDOW_GAINED_FOCUS event.
  3. Finally, a will receive a FOCUS_GAINED event.
If the user later clicks on a focusable child Component c of anotherFrame d , the following events will be dispatched and handled inorder:
  1. a will receive a FOCUS_LOST event.
  2. b will receive a WINDOW_LOST_FOCUS event.
  3. b will receive a WINDOW_DEACTIVATED event.
  4. d will receive a WINDOW_ACTIVATED event.
  5. d will receive a WINDOW_GAINED_FOCUS event.
  6. c will receive a FOCUS_GAINED event.
Note that each event will be fully handled before the next event isdispatched. This restriction will be enforced even if the Componentsare in different contexts and are handled on different eventdispatching threads.

In addition, each event type will be dispatched in 1-to-1correspondence with its opposite event type. For example, if aComponent receives a FOCUS_GAINED event, under nocircumstances can it ever receive another FOCUS_GAINEDevent without an intervening FOCUS_LOST event.

Finally, it is important to note that these events are delivered forinformational purposes only. It is impossible, for example, to preventthe delivery of a pending FOCUS_GAINED event by requestingfocus back to the Component losing focus while handling the precedingFOCUS_LOST event. While client code may make such a request,the pending FOCUS_GAINED will still be delivered,followed later by the events transferring focus back to the originalfocus owner.

If it is absolutely necessary to suppress the FOCUS_GAINED event,client code can install a VetoableChangeListener whichrejects the focus change. See Focusand VetoableChangeListener .

Opposite Components and Windows

Each event includes information about the "opposite" Component orWindow involved in the focus or activation change. For example, for aFOCUS_GAINED event, the opposite Component is the Componentthat lost focus. If the focus or activation change occurs with a nativeapplication, with a Java application in a different VM or context, orwith no other Component, then the opposite Component or Window isnull. This information is accessible usingFocusEvent.getOppositeComponent orWindowEvent.getOppositeWindow.

On some platforms, it is not possible to discern the oppositeComponent or Window when the focus or activation change occurs betweentwo different heavyweight Components. In these cases, the oppositeComponent or Window may be set to null on some platforms, and to avalid non-null value on other platforms. However, for a focus changebetween two lightweight Components which share the same heavyweightContainer, the opposite Component will always be set correctly. Thus,a pure Swing application can ignore this platform restriction whenusing the opposite Component of a focus change that occurred within atop-level Window.

Temporary FocusEvents

FOCUS_GAINED and FOCUS_LOST events aremarked as either temporary or permanent.

Temporary FOCUS_LOST events are sent when a Component islosing the focus, but will regain the focus shortly. These eventscan be useful when focus changes are used as triggers for validationof 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 FOCUS_LOST events.However, if the FocusEvent received is temporary,the commit should not be done, since the text field will be receivingthe focus again shortly.

A permanent focus transfer typically occurs as the result of a userclicking on a selectable, heavyweight Component, focus traversal withthe keyboard or an equivalent input device, or from a call torequestFocus() or requestFocusInWindow().

A temporary focus transfer typically occurs as the result of showing aMenu or PopupMenu, clicking or dragging a Scrollbar, moving a Windowby dragging the title bar, or making another Window the focusedWindow. Note that on some platforms, these actions may not generateany FocusEvents at all. On others, temporary focus transfers willoccur.

When a Component receives a temporary FOCUS_LOST event,the event's opposite Component (if any) may receive a temporaryFOCUS_GAINED event, but could also receive a permanentFOCUS_GAINED event. Showing a Menu or PopupMenu, or clicking or dragging a Scrollbar, should generate a temporary FOCUS_GAINED event. Changing the focused Window,however, will yield a permanent FOCUS_GAINED eventfor the new focus owner.

The Component class includes variants of requestFocus andrequestFocusInWindow which take a desired temporary state as aparameter. However, because specifying an arbitrary temporary statemay not be implementable on all native windowing systems, correctbehavior for this method can be guaranteed only for lightweightComponents. This method is not intended for general use, but existsinstead as a hook for lightweight Component libraries, such as Swing.

Focus Traversal

Each Component defines its own Set of focus traversal keys for a givenfocus traversal operation. Components support separate Sets of keysfor forward and backward traversal, and also for traversal up onefocus traversal cycle. Containers which are focus cycle roots alsosupport a Set of keys for traversal down one focus traversal cycle. Ifa Set is not explicitly defined for a Component, that Componentrecursively inherits a Set from its parent, and ultimately from acontext-wide default set on the current KeyboardFocusManager.

Using the AWTKeyStroke API, client code can specify on which of two specific KeyEvents, KEY_PRESSED or KEY_RELEASED, the focus traversal operation will occur.Regardless of which KeyEvent is specified, however, all KeyEventsrelated to the focus traversal key, including the associated KEY_TYPED event, will be consumed, and will not bedispatched to any Component. It is a runtime error to specify aKEY_TYPED event as mapping to a focus traversal operation,or to map the same event to multiple focus traversal operations for anyparticular Component or for a KeyboardFocusManager's defaults.

The default focus traversal keys are implementation-dependent. Sunrecommends that the all implementations for a particular nativeplatform use the same keys. For Windows and Unix, the recommendationsare:

Components can enable and disable all of their focus traversal keys enmasse using Component.setFocusTraversalKeysEnabled. When focustraversal keys are disabled, the Component receives all KeyEvents forthose keys. When focus traversal keys are enabled, the Component neverreceives KeyEvents for traversal keys; instead, the KeyEvents areautomatically mapped to focus traversal operations.

For normal forward and backward traversal, the AWT focusimplementation determines which Component to focus next based on the FocusTraversalPolicy ofthe focus owner's focus cycle root or focus traversal policy provider. If thefocus owner is a focus cycle root, then it may be ambiguous as to whichComponents represent the next and previous Components to focus duringnormal focus traversal. Thus, the currentKeyboardFocusManager maintains a reference to the"current" focus cycle root, which is global across all contexts. Thecurrent focus cycle root is used to resolve the ambiguity.

For up-cycle traversal, the focus owner is set to the current focusowner's focus cycle root, and the current focus cycle root is set tothe new focus owner's focus cycle root. If, however, the current focusowner's focus cycle root is a top-level window, then the focus owneris set to the focus cycle root's default component to focus, and thecurrent focus cycle root is unchanged.

For down-cycle traversal, if the current focus owner is a focus cycleroot, then the focus owner is set to the current focus owner's defaultcomponent to focus, and the current focus cycle root is set to thecurrent focus owner. If the current focus owner is not a focus cycleroot, then no focus traversal operation occurs.

FocusTraversalPolicy

A FocusTraversalPolicy defines the order in which Components withina particular focus cycle root or focus traversal policy provider aretraversed. Instances of FocusTraversalPolicy can be shared acrossContainers, allowing those Containers to implement the same traversal policy.FocusTraversalPolicies do not need to be reinitialized when thefocus-traversal-cycle hierarchy changes.

Each FocusTraversalPolicy must define the followingfive algorithms:

  1. Given a focus cycle root and a Component a in that cycle, the next Component after a .
  2. Given a focus cycle root and a Component a in that cycle, the previous Component before a .
  3. 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.
  4. 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.
  5. 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.

A FocusTraversalPolicy may optionally provide an algorithm for the following:

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.
In addition, Swing provides a subclass of FocusTraversalPolicy,InternalFrameFocusTraversalPolicy, which allows developersto provide an algorithm for the following:
Given a JInternalFrame, the "initial" Component in that JInternalFrame. The initial Component is the first to receive focus when the JInternalFrame is first selected. By default, this is the same as the JInternalFrame's default Component to focus.
A FocusTraversalPolicy is installed on a Container usingContainer.setFocusTraversalPolicy. If a policy is not explicitlyset, then a Container inherits its policy from its nearest focus-cycle-rootancestor. Top-levels initialize their focus traversal policies using the contextdefault policy. The context default policy is established by usingKeyboardFocusManager. setDefaultFocusTraversalPolicy.

AWT provides two standard FocusTraversalPolicyimplementations for use by client code.

  1. ContainerOrderFocusTraversalPolicy: 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.
    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. This provides backward compatibility with applications designed without the concepts of up- and down-cycle traversal.
  2. DefaultFocusTraversalPolicy: A subclass of ContainerOrderFocusTraversalPolicy which redefines the fitness test. If client code has explicitly set the focusability of a Component by either overriding Component.isFocusTraversable() or Component.isFocusable(), or by calling Component.setFocusable(boolean), then a DefaultFocusTraversalPolicy behaves exactly like a ContainerOrderFocusTraversalPolicy. If, however, the Component is relying on default focusability, then a DefaultFocusTraversalPolicy will reject all Components with non-focusable peers.
    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.

Swing provides two additional, standard FocusTraversalPolicyimplementations for use by client code. Each implementation is anInternalFrameFocusTraversalPolicy.

  1. 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.
  2. 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. This provides backward compatibility with applications designed without the concepts of up- and down-cycle traversal.
  3. 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.
    In addition, the fitness test is extended to exclude JComponents that have or inherit empty InputMaps.

Swing applications, or mixed Swing/AWT applications, that use one ofthe standard look and feels, or any other look and feel derived fromBasicLookAndFeel, will use LayoutFocusTraversalPolicy for allContainers by default.

All other applications, including pure AWT applications, will useDefaultFocusTraversalPolicy by default.

Focus Traversal Policy Providers

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 true with the call to

To determine whether a Container is a focus traversal policy provider, the following method should be used: 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.

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:

Programmatic Traversal

In addition to user-initiated focus traversal, client code caninitiate a focus traversal operation programmatically. To client code,programmatic traversals are indistinguishable from user-initiatedtraversals. The preferred way to initiate a programmatic traversal isto use one of the following methods on KeyboardFocusManager:

Each of these methods initiates the traversal operation with thecurrent focus owner. If there is currently no focus owner, then notraversal operation occurs. In addition, if the focus owner is not afocus cycle root, then downFocusCycle() performs no traversaloperation.

KeyboardFocusManager also supports the following variantsof these methods:

Each of these methods initiates the traversal operation with thespecified Component rather than the focus owner. That is, thetraversal occurs as though the specified Component is the focus owner,though it need not be.

Alternate, but equivalent, APIs are defined on the Component andContainer classes themselves:

As with the KeyboardFocusManager variants, each of these methodsinitiates the traversal operation as though the Component is the focusowner, though it need not be.

Also note that hiding or disabling the focus owner, directly orindirectly via an ancestor, or making the focus owner non-displayableor non-focusable, initiates an automatic, forward focus traversal.While hiding any ancestor, lightweight or heavyweight, will alwaysindirectly hide its children, only disabling a heavyweight ancestorwill disable its children. Thus, disabling a lightweight ancestor ofthe focus owner does not automatically initiate a focus traversal.

If client code initiates a focus traversal, and there is no otherComponent to focus, then the focus owner remains unchanged. If clientcode initiates an automatic focus traversal by hiding the focus owner,directly or indirectly, or by making the focus owner non-displayable ornon-focusable, and there is no other Component to focus, then theglobal focus owner is cleared. If client code initiates an automaticfocus traversal by disabling the focus owner, directly or indirectly,and there is no other Component to focus, then the focus owner remainsunchanged.

Focusability

A focusable Component can become the focus owner ("focusability") andparticipates in keyboard focus traversal ("focus traversability") witha FocusTraversalPolicy. There is no separation of these two concepts;a Component must either be both focusable and focus traversable, orneither.A Component expresses this state via the isFocusable() method. Bydefault, all Components return true from this method. Client code canchange this default by calling Component.setFocusable(boolean).

Focusable Windows

To support palette windows and input methods, client code can preventa Window from becoming the focused Window. By transitivity, thisprevents the Window or any of its descendants from becoming the focusowner. Non-focusable Windows may still own Windows that arefocusable. By default, every Frame and Dialog is focusable. EveryWindow which is not a Frame or Dialog, but whose nearest owning Frameor Dialog is showing on the screen, and which has at least oneComponent in its focus traversal cycle, is also focusable bydefault. To make a Window non-focusable, useWindow.setFocusableWindowState(false).

If a Window is non-focusable, this restriction is enforced when theKeyboardFocusManager sees a WINDOW_GAINED_FOCUSevent for the Window. At this point, the focus change is rejected andfocus is reset to a different Window. The rejection recovery schemeis the same as if a VetoableChangeListener rejected thefocus change. See Focusand VetoableChangeListener .

Because the new focus implementation requires that KeyEvents intendedfor a Window or its descendants be proxied through a child of theWindow's owner, and because this proxy must be mapped on X11 in orderto receive events, a Window whose nearest owning Frame or Dialog isnot showing could never receive KeyEvents on X11. To support thisrestriction, we have made a distinction between a Window's "windowfocusability" and its "window focusability state". A Window'sfocusability state is combined with the showing state of the Window'snearest owning Frame or Dialog to determine the Window's focusability.By default, all Windows have a focusability state of true. Setting aWindow's focusability state to false ensures that it will not becomethe focused Window regardless of the showing state of its nearestowning Frame or Dialog.

Swing allows applications to create JWindows with null owners. Swingconstructs all such JWindows so that they are owned by a private,hidden Frame. Because the showing state of this Frame will always befalse, a JWindow constructed will a null owner can never be thefocused Window, even if it has a Window focusability state of true.

If the focused Window is made non-focusable, then the AWT will attemptto focus the most recently focused Component of the Window'sowner. The Window's owner will thus become the new focused Window. Ifthe Window's owner is also a non-focusable Window, then the focuschange request will proceed up the ownership hierarchy recursively.Since not all platforms support cross-Window focus changes (see Requesting Focus ), it is possible thatall such focus change requests will fail. In this case, the globalfocus owner will be cleared and the focused Window will remain unchanged.

Requesting Focus

A Component can request that it become the focus owner by callingComponent.requestFocus(). This initiates a permanentfocus transfer to the Component only if the Component is displayable,focusable, visible displayable,visible, and all of its ancestors (with the exception of thetop-level Window) are visible. focusable. The request will be immediately denied ifany of these conditions is not met. A disabled Component may bethe focus owner; however, in this case, all KeyEvents will be discarded.

The request will also be denied if the Component's top-level Window isnot the focused Window and the platform does not support requestingfocus across Windows. If the request is denied for this reason, therequest is remembered and will be granted when the Window is laterfocused by the user. Otherwise, the focus change request changes thefocused Window as well. Currently, Microsoft Windows supports cross-Window focus transfers while Solaris does not.

There is no way to determine synchronously whether a focus changerequest has been granted. Instead, client code must install aFocusListener on the Component and watch for the delivery of aFOCUS_GAINED event. Client code must not assume thatthe Component is the focus owner until it receives this event.The event may or may not be delivered before requestFocus()returns. Developers must not assume one behavior or the other.

The AWT supports type-ahead if all focus change requests are made onthe EventDispatchThread. If client code requests a focus change, andthe AWT determines that this request might be granted by the nativewindowing system, then the AWT will notify the currentKeyboardFocusManager that is should enqueue all KeyEvents with atimestamp later than the that of the event currently being handled.These KeyEvents will not be dispatched until the new Component becomesthe focus owner. The AWT will cancel the delayed dispatching requestif the focus change does not succeed at the native level, if theComponent's peer is disposed, or if the focus change is vetoed by aVetoableChangeListener. KeyboardFocusManagers are not required tosupport type-ahead if a focus change request is made from a threadother than the EventDispatchThread.

Because Component.requestFocus() cannot be implementedconsistently across platforms, developers are encouraged to useComponent.requestFocusInWindow() instead. This methoddenies 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.

In addition, requestFocusInWindow() returns a boolean value.If 'false' is returned, the request is guaranteed to fail. If 'true' isreturned, the request will succeed unless it is vetoed, or anextraordinary event, such as disposal of the Component's peer, occursbefore the request can be granted by the native windowingsystem. Again, while a return value of 'true' indicates that therequest is likely to succeed, developers must never assume that thisComponent is the focus owner until this Component receives aFOCUS_GAINED event.

If client code wants no Component in the application to be the focusowner, it can call the method KeyboardFocusManager.clearGlobalFocusOwner() on the currentKeyboardFocusManager. If there exists a focus ownerwhen this method is called, the focus owner will receive a permanentFOCUS_LOST event. After this point, the AWTfocus implementation will discard all KeyEvents until the user orclient code explicitly sets focus to a Component.

The Component class also supports variants of requestFocus andrequestFocusInWindow that allow client code to specifya temporary state.See Temporary FocusEvents

Focus and PropertyChangeListener

Client code can listen to changes in context-wide focus state, or tochanges in focus-related state in Components, viaPropertyChangeListeners.

The KeyboardFocusManager supports the following properties:

  1. focusOwner: the focus owner
  2. focusedWindow: the focused Window
  3. activeWindow: the active Window
  4. defaultFocusTraversalPolicy: the default focus traversal policy
  5. forwardDefaultFocusTraversalKeys: the Set of default FORWARD_TRAVERSAL_KEYS
  6. backwardDefaultFocusTraversalKeys: the Set of default BACKWARD_TRAVERSAL_KEYS
  7. upCycleDefaultFocusTraversalKeys: the Set of default UP_CYCLE_TRAVERSAL_KEYS
  8. downCycleDefaultFocusTraversalKeys: the Set of default DOWN_CYCLE_TRAVERSAL_KEYS
  9. currentFocusCycleRoot: the current focus cycle root

A PropertyChangeListener installed on the currentKeyboardFocusManager will only see these changes withinthe KeyboardFocusManager's context, even though the focus owner, focused Window, active Window, and current focus cycleroot comprise the global focus state shared by all contexts.We believe this is less intrusive than requiring client code to passa security check before installing a PropertyChangeListener.

Component supports the following focus-related properties:

  1. focusable: the Component's focusability
  2. focusTraversalKeysEnabled: the Component's focus traversal keys enabled state
  3. forwardFocusTraversalKeys: the Component's Set of FORWARD_TRAVERSAL_KEYS
  4. backwardFocusTraversalKeys: the Component's Set of BACKWARD_TRAVERSAL_KEYS
  5. upCycleFocusTraversalKeys: the Component's Set of UP_CYCLE_TRAVERSAL_KEYS

In addition to the Component properties, Container supports thefollowing focus-related properties:

  1. downCycleFocusTraversalKeys: the Container's Set of DOWN_CYCLE_TRAVERSAL_KEYS
  2. focusTraversalPolicy: the Container's focus traversal policy
  3. focusCycleRoot: the Container's focus-cycle-root state

In addition to the Container properties, Window supports the followingfocus-related property:

  1. focusableWindow: the Window's focusable Window state

Also note that a PropertyChangeListener installed on aWindow will never see a PropertyChangeEvent for thefocusCycleRoot property.A Window is always a focus cycle root; this property cannot change.

Focus and VetoableChangeListener

The KeyboardFocusManager also supports VetoableChangeListeners for the following properties:

  1. "focusOwner": the focus owner
  2. "focusedWindow": the focused Window
  3. "activeWindow": the active Window
If a VetoableChangeListener vetoes a focus or activation change bythrowing a PropertyVetoException, the change is aborted. AnyVetoableChangeListeners which had already approved the change willasynchronously receive PropertyChangeEvents indicating a reversion ofstate to the previous value.

VetoableChangeListeners are notified of the state change before thechange is reflected in the KeyboardFocusManager. Conversely,PropertyChangeListeners are notified after the change is reflected.It follows that all VetoableChangeListeners will be notified beforeany PropertyChangeListener.

VetoableChangeListeners must be idempotent, and must veto both lossand gain events for a particular focus change (e.g., bothFOCUS_LOST and FOCUS_GAINED). For example,if a VetoableChangeListener vetoes a FOCUS_LOSTevent, a KeyboardFocusManager is not required to search theEventQueue and remove the associated pendingFOCUS_GAINED event. Instead, theKeyboardFocusManager is free to attempt todispatch this event and it is the responsibility of theVetoableChangeListener to veto it as well. In addition,during processing of the FOCUS_GAINED event, the KeyboardFocusManager may attempt to resync the globalfocus state by synthesizing another FOCUS_LOST event.This event must be vetoed just as the first FOCUS_LOST event was.

A KeyboardFocusManager may not hold any locks while notifying PropertyChangeListeners of a state change. This requirement is relaxed for VetoableChangeListeners,however. Therefore, client-definied VetoableChangeListenersshould avoid acquiring additional locks insidevetoableChange(PropertyChangeEvent) as this may lead to deadlock.If a focus or activation change is rejected, the KeyboardFocusManagerwill initiate rejection recovery as follows:

VetoableChangeListeners must be careful to avoid vetoing focuschanges initiated as a result of veto rejection recovery. Failureto anticipate this situation could lead to an infinite cycle ofvetoed focus changes and recovery attempts.

Z-Order

On some native windowing systems, the Z-order of a Window can affectits 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 UIrequirements of the native platform. Therefore, the focus behavior ofZ-order-related methods such as:

is platform-dependent. In JDK 1.4, the behavior of these methods onMicrosoft Windows and Solaris is as follows:

Replacing DefaultKeyboardFocusManager

KeyboardFocusManagers are pluggable at the browser contextlevel. Client code can subclass KeyboardFocusManager orDefaultKeyboardFocusManager to modify the way that WindowEventsrelated to focus, FocusEvents, and KeyEvents are handled anddispatched, and to examine and modify the global focus state. A customKeyboardFocusManager can also reject focus changes at a morefundamental level then a FocusListener or WindowListener ever could.

While giving a developer ultimate control over the focus model,replacing the entire KeyboardFocusManager is a difficult processrequiring 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 documentbefore resorting to a full replacement of the KeyboardFocusManager.

First note that, because unhindered access to Components in othercontexts represents a security hole, the SecurityManager must grant anew permission, "replaceKeyboardFocusManager", before client code ispermitted to replace the KeyboardFocusManager with an arbitrarysubclass instance. Because of the security check, replacing theKeyboardFocusManager is not an option for applications that will bedeployed in environments with a SecurityManager, such as applets in abrowser.

Once installed, a KeyboardFocusManager instance hasaccess to the global focus state via a set of protected functions.The KeyboardFocusManager can only call these functionsif it is installed in the calling thread's context. This ensuresthat malicious code cannot circumvent the security check inKeyboardFocusManager.setCurrentFocusManager.A KeyboardFocusManager should always work withthe global focus state instead of the context focus state.Failure to do this will lead to incorrect behavior of theKeyboardFocusManager.

The primary responsibility of a KeyboardFocusManageris the dispatch of the following events:

The peer layer will provide the KeyboardFocusManagerwith all of the above events except WINDOW_ACTIVATEDand WINDOW_DEACTIVATED. The KeyboardFocusManagermust synthesize WINDOW_ACTIVATED andWINDOW_DEACTIVATED events when appropriate and target themaccordingly.

The KeyboardFocusManager may need to retarget the eventsprovided by the peer layer to its own notion of the focus owner orfocused Window:

A KeyboardFocusManager 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 ispossible for the peer layer to send a FOCUS_GAINEDevent before a WINDOW_GAINED_FOCUS event.The KeyboardFocusManager is responsible forensuring that the WINDOW_GAINED_FOCUS event is dispatchedbefore the FOCUS_GAINED event.

Before redispatching an event via KeyboardFocusManager.redispatchEvent, a KeyboardFocusManagermust attempt to update the global focus state. Typically, thisis done using one of the KeyboardFocusManager.setGlobal*methods; however, an implementation is free to implement its own methods.After attempting an update, the KeyboardFocusManagermust verify that the global focus state changewas not rejected. A rejection is detected when a call to thecorresponding getGlobal* method returns a value different than thevalue just set. Rejections occur in three standard cases:

Client-defined implementations of KeyboardFocusManagercan adjust the set of focus transfers which are rejected by overriding theaccessor and mutator methods for the global focus state.

If a request to change the global focus state is rejected, theKeyboardFocusManager must discard the event which promptedthe focus change request. The Component to which the event was targetedmust not receive the event.

The KeyboardFocusManager is also expected to initiate rejectionrecovery as outlined in Focusand VetoableChangeListener .

Finally, a KeyboardFocusManager must handle the following set of special cases:

Incompatibilities with Previous Releases

Cross-platform changes:

  1. 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 DefaultFocusTraversalPolicy for all AWT Containers will preserve the traversal order of previous releases.
  2. A request to focus a non-focus traversable (i.e., non-focusable) Component will be denied. Previously, such requests were granted.
  3. Window.toFront() and Window.toBack() now perform no operation if the Window is not visible. Previously, the behavior was platform-dependent.
  4. KeyListeners installed on Components will no longer see KeyEvents that map to focus traversal operations, and Component.handleEvent() 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 Components and handle focus traversal itself. Alternately, the code can use an AWTEventListener or KeyEventDispatcher to pre-listen to all KeyEvents.

Changes specific to Microsoft Windows:

  1. Window.toBack() changes the focused Window to the top-most Window after the Z-order change.
  2. requestFocus() now allows cross-Window focus change requests in all cases. Previously, requests were granted for heavyweights, but denied for lightweights.