Focus on Focus:
A Tutorial on the New API
David Mendenhall
Member of Technical Staff
Hania Gajewska
Senior Staff Engineer
Sun Microsystems, Inc.
Abstract
This session will be a tutorial of what is easily the largest change to the Java Foundation Classes (JFC/Swing) API and AWT since 1.2. Developers will learn how to use the new keyboard focus API to create substantial JFC/Swing API and AWT-based applications with a focus behavior that is customized, yet consistent across platforms.
Overview
Fundamentals
Focus Traversal
Focus-related Events
Quick Tips
What Is Keyboard Focus?
Simply, how and where users keystrokes
are delivered
How
- AWT and the JFC/Swing API translate native platform key events into Java KeyEvents
- Handle event ordering and delivery logic
Where
- Components (or JComponents)
Keystrokes
- May not originate from keyboard
Fundamental Focus State
Focus owner
- Component which receives keyboard input
Focused Window
- Top-level Window which contains focus owner
Active Window
- Only Frame or Dialog, never Window
- Often given special appearance by window manager (e.g., blue title bar)
- Either same as focused Window, or nearest owning Frame or Dialog
Focus Debugging Tool
Written by Oleg Sukhodolsky
Performs static and dynamic focus
analysis of AWT and JFC/Swing
technology-based applications
Public domain license
Soon to be available on-line
Centralized Focus Management
New class: java.awt.KeyboardFocusManager
- javax.swing.FocusManager
only handled JFC/Swing TAB traversal
- Centralized location for client to find and change focus owner
- Tracks all focus activitynot just keyboard focus traversal, not just JComponents
- Singleton
Querying Focus State
The Java 2 Platform, Standard Edition (J2SE) 1.4 release
Others
- getFocusedWindow()
- getActiveWindow()
- Component.isFocusOwner()
- Window.isFocused()
- Window.isActive()
Observing Focus State Changes
J2SE SDK 1.3: Component-level observation
- FocusEvent (FOCUS_GAINED, FOCUS_LOST)
- WindowEvent (WINDOW_ACTIVATED, WINDOW_DEACTIVATED)
J2SE, SDK 1.4: global observation
Focus Traversal
Users ability to change focus owner
without moving mouse cursor
Usually with TAB key
- Major exceptions are TextArea/JTextArea
- Applications can also initiate traversal programmatically
Normal traversal can be forward to next Component, or backward to previous
Focus Traversal in
the J2SE 1.3 Release
AWT
- TAB and SHIFT-TABnot customizable
- Only forward programmatic traversal: Component.transferFocus()
JFC/Swing technology
- DefaultFocusManagerfought AWT
- setNextFocusableComponentdangerous
- isFocusCycleRootincomplete
- isManagingFocusconfusing
Focus Traversal Policies
New class: java.awt.FocusTraversalPolicy
- Define algorithms for next, previous, first, last, default, and initial Components
- Lighter-weight than javax.swing.DefaultFocusManager
- Less error-prone than JComponents setNextFocusableComponent
FocusTraversalPolicy
FocusTraversalPolicy Implementations
AWT
- ContainerOrderFocusTraversalPolicy
- DefaultFocusTraversalPolicy
- accept(Component)
JFC/Swing technology
- SortingFocusTraversalPolicy
- LayoutFocusTraversalPolicy
- accept(Component)
Creating a Custom
FocusTraversalPolicy
Subclassing existing implementations
is highly recommended
- Prevents JLabels from getting focus,
for example
Focus Traversal Cycles
Component hierarchy divided into focus traversal cycles
- Once focus enters cycle, normal traversal constrained
Rooted at one focus cycle root Container
- Window and JInternalFrame
must be root; others optional
Has own FocusTraversalPolicy
- Recall that FocusTraversalPolicy methods parameterized on rootallows sharing
Traversal Cycle API
Containers focus-cycle-root
state is dynamic
Traversal Cycle API (2)
Container inherits parents policy if none explicitly set
KeyboardFocusManager controls application default policy
Traversal Cycle API Example
Focus Traversal Keys
Each Component defines own focus
traversal keys
- Component: forward, backward, up-cycle
- Focus cycle roots: down-cycle as well
Multiple keys for same operation
Keys can be disabled en masse
Traversal Keys API
Components focus traversal keys are Sets of AWTKeyStrokes
Empty Set (Collections.EMPTY_SET) denotes no key for that operation
null denotes key inheritance from parent
Traversal Keys API Example
Programmatic Traversal
Application code can initiate traversal programmatically
- Several different ways
- final methods on KeyboardFocusManager preferred
WindowEvent
The J2SE 1.3 release
- WINDOW_ACTIVATED
- WINDOW_DEACTIVATED
- Frame and Dialog only
The J2SE 1.4 release
- WINDOW_GAINED_FOCUS
- WINDOW_LOST_FOCUS
- Window, Frame, and Dialog
FocusEvent
The J2SE 1.3 release
- FOCUS_GAINED
- FOCUS_LOST
- isTemporary()
Temporary focus loss indicates Component
will soon regain focus
- Switch to another application
- Pop-down menu (depends on platform)
Permanent Focus Owner
Last Component to receive focus permanently
- Same as focus owner, unless temporary focus transfer in progress
- Part of fundamental focus state
- Query and observer support in KeyboardFocusManager
Opposite
Win32 WM_SETFOCUS and WM_KILLFOCUS
events include opposite HWND
- e.g., for WM_SETFOCUS, HWND losing focus
J2SE, SDK 1.4
- FocusEvent.getOppositeComponent()
- WindowEvent.getOppositeWindow()
Quick TipsFocus Changes
Dont use requestFocus(); use requestFocusInWindow()
Dont assume Component owns focus until FOCUS_GAINED delivered
Requesting focus in FOCUS_LOST doesnt prevent FOCUS_GAINED
Z-order focus behavior is platform-dependent
Quick TipsUseful APIs
Use KeyEventDispatcher to pre-listen
to KeyEvents
Use KeyEventPostProcessor to post-listen to KeyEvents
Use non-focusable Windows for palettes
Replace KeyboardFocusManager
as last resort
Quick TipsEdge Cases
JWindows with null owners are non-focusable
Verify that all Components are
reachable using keyboard traversal
There is no difference between focusability
and focus traversability
Remember that input methods can affect
focus behavior
When in doubt, consult new focus specification
Summary
KeyboardFocusManager class centralizes
focus management
FocusTraversalPolicy provides lightweight traversal handling
Download 1.4-beta and try it out!
-
-