Advanced
Java
Services
|
New 1.4 FocusManagement |
Focusdurchquerung und Fokuszyklus (focus traversal and focuscycle)
focus traversal (to travers = durchqueren) ist die Eigenschaft mit einer Taste (meist der TAB-Taste)
den Fokus von einer Komponente auf die nächste zu setzen. Damit kann man etwa eine Reihe von Buttons
(aber auch andere Komponenten) mit der TAB-Taste durchqueren. Kommt man dabei von der letzten Komponente
wieder zurück zur ersten Komponente, so spricht man von einem Fokuszyklus (focuscycle). Dieses
Standardverhalten von Software mußte man bisher in Java von Hand programmieren. Dazu verwendete man
einen KeyListener, "horchte" auf die Tastatur und setzte meist in der Methode keyPressed() den Fokus
per Hand dahion, wie man ihn hinhaben wollte. Unter Umständen mußte mann auch noch einen FocusListener
zu Hilfe nehmen.
In der Version 1.4 ist das Fokusmanagement von Java grundlegend neu gestaltet worden. Dabei wurden Ideen,
die man zunächst nur auf SwingKlassen beschränkte, weiterentwickelt und für alle Klassen verfügbar gemacht,
die sich von Component bzw. Container ableiten, sodaß auch reine AWT-Entwicklungen in den Genuß der neuen
Möglichkeiten kommen. Es gibt nun einen neuen zentralen Focusmanager, der das Fokusverhalten einer
graphischen Oberfläche bestimmt und der eine Weiterentwicklung des nunmehr obsoleten Klasse Fokusmanager
der Swingklassen darstellt. Der nächste Link führt führt sie zu einer Übersicht über die
Fokusmanagerklassen
KeyBoardFocusManager Hierarchie
Wo bleibt die TAB-Taste ?
Wer schon einmal das Fokusverhalten von Hand programmiert hat, wird sich wundern, wenn seine alte
Anwendung ab 1.4 nicht mehr funktioniert. Bei genauerem Hinsehen wird er feststellen, daß das Drücken
der TAB-Taste keinen KeyEvent mehr auslöst. Alle KeyEvents, die etwas mit Fokustraversierung zu tun
haben werden automatisch an den neuen KeyboardFokusmanager geleitet, eine entsprechende
KeyListenermethode wird nicht mehr aufgerufen. Im "Normalfall" versucht dafür der Keyboardmanager den
Fokus auf die nächste in Frage kommende Komponente zu setzen.
Abschalten des KeyboardFocusManagers
Wer nicht in den Genuß der neuen Möglichkeiten kommen will, der kann den KeyboardFocusManager
komponentenweise ausschalten durch den Aufruf von
In diesem Fall liefert der Druck auf die TAB-Taste wieder einen KeyEvent, auf den man in den
KeyListenerMethoden keyPressed und keyReleased reagieren kann. Dann ist man allerdings wieder auf dem
Stand von JDK 1.3
DefaultKeyboardFocusManager
Der KeyboardFocusManager ist die zentrale Fokussteuerung einer Applikation oder eines Applets. Er tritt mit dem Start einer Anwendung automatisch in Aktion. Die abstrakte Klasse KeyboardFocusmanager kann diesen zentralen Fokusmanager mit Hilfe einer statischen Methode liefern:
Die Methode liefert ein Objekt vom Typ DefaultKeyboardFocusManager . Es gibt auch das Gegenstück
zu dieser Methode getCurrentKeyboardFocusManager(KeyboardFocusManager kbf). Ein selbstgebastelter
Fokusmanager muß (natürlich) eine Unterklasse von KeyboardFocusManager oder DefaultKeyboardFocusManager
sein und (natürlich) alle abstrakten Methoden realisieren. Sun empfiehlt, das eher nicht zu tun, denn
"replacing the entire KeyboardFocusManager is a difficult process requiring a thorough understanding
of the peer focus layer."
Stattdessen empfiehlt es sich, von den reichhaltigen Konfigurierungsmöglichkeiten des
KeyboardFocusManager und der Komponenten und Container Gebrauch zu machen.
FocusTraversalKeys und FocusTraversalPolicy (global)
Zu den wichtigsten Aufgaben des KeyboardFocusManagers gehört es, die Tasten zu verwalten, mit denen man den Fokus vorwärts oder rückwärts transportiert. Im Normalfall ist das die TAB-Taste alleine oder kombiniert mit SHIFT und/oder CTRL. Diese vom KeyboardFocusManager gesetzten Tasten gelten für alle Komponenten und Container eine Applikation oder eines Applets. Man erfährt die Defaulteinstellungen über die Methode
Für id setzt man einen der folgenden Werte ein:
Per default gibt es weder UP_CYCLE_TRAVERSAL_KEYS noch DOWN_CYCLE_TRAVERSAL_KEYS, da es hierfür keinen
Standard gibt und es seltener vorkommt, daß man von einem Fukuszyklus zu einem anderen unbedingt mit
der Tastatur gehen will, das macht man oft eben mit der Maus.
Ist man mit der Voreinstellung nicht zufrieden, kann man mit
die globale Voreinstellung nach seinen Wünschen verändern.
Interessanter noch ist das Traversierungsverhalten durch die fokusfähigen Komponenten. Diese
FocusTraversalPolicy bestimmt nämlich, in welcher Reihenfolge die einzelnen Komponenten abgeklappert
werden, wenn man die TAB-Taste drückt. Man erfährt die Defaulteinstellungen über die Methode
die ein Objekt vom Typ FocusTraversalPolicy liefert, das sich bei näherer Untersuchung als Instanz vom
Typ DefaultFocusTraversalPolicy herausstellt. Eine Übersicht über diese Hierarchie bringt der folgende
Link
FocusTraversalPolicy Hierarchie
Der KeyboardFocusManager setzt diese Verhalten für alle Container, aber er setzt es nicht überall gleich.
Für die Container Window, Frame und Dialog setzt er ein Objekt der Klasse DefaultFocusTraversalPolicy,
für die Container Panel und ScrollPane setzt er dagegen keine policy, also null.
Eine Übersicht über die Defaultfokuseinstellungen der Container und Komponenten bringen die nächsten
beiden Links
FocusDefaults for Containers
FocusDefaults for Components
Die globale FocusTraversalPolicy läßt sich, wie zu erwarten, auch ändern.
Neben DefaultFocusTraversalPolicy kommt da hauptsächlich die ContainerOrderFocusTraversalPolicy
in Betracht oder man schreibt sich selber eine FocusTraversalPolicy, indem man geeignete Ableitungen
bildet.
FocusTraversalKeys (lokal)
Die Traversierungstasten lassen sich für jede Komponente einzeln setzen, bzw. erfragen.
Für die Abfrage braucht man wieder eine der vier bereits erwähnten Konstanten
Mit zu den interessantesten Features gehört die Möglichkeit, das Traversierungsverhalten für jeden Container individuell zu setzen. Voraussetzung dafür ist allerdings, daß der Container "focuscyclefähig" ist. Die Container Window, Frame und Dialog sind per default "focuscyclefähig", die Container Panel und Scrollpane jedoch nicht. Mit der folgenden Methode kann man auch Panel und ScrollPane "focuscyclefähig" machen. Das ist Voraussetzung dafür, daß eine gesetzte FocusTraversalPolicy überhaupt eingesetzt wird.
Hat man einen Container, der eine FocusCycleRoot darstellt, so kann man Abfragen, ob eine FocusTraversalPolicy gesetzt ist
oder mit
eine Policy setzen.
Es folgt eine Übersicht über die fokusbezogenen Methoden der Klassen Component und
Container
Focusmethoden in Component
boolean areFocusTraversalKeysSet(int id)
// Returns whether the Set of focus traversal keys for the given focus traversal operation has been explicitly defined for this Component.
Container getFocusCycleRootAncestor()
// Returns the Container which is the focus cycle root of this Component's focus traversal cycle.
FocusListener[] getFocusListeners()
// Returns an array of all the focus listeners registered on this component.
Set getFocusTraversalKeys(int id)
// Returns the Set of focus traversal keys for a given traversal operation for this Component.
boolean getFocusTraversalKeysEnabled()
// Returns whether focus traversal keys are enabled for this Component.
KeyListener[] getKeyListeners()
// Returns an array of all the key listeners registered on this component.
boolean isFocusable()
// Returns whether this Component can be focused.
boolean isFocusCycleRoot(Container container)
// Returns whether the specified Container is the focus cycle root of this Component's focus traversal cycle.
boolean isFocusOwner()
// Returns true if this Component is the focus owner.
boolean isFocusTraversable()
// Deprecated. As of 1.4, replaced by isFocusable().
void requestFocus()
// (1.0)Requests that this Component get the input focus, and that this Component's top-level ancestor become the focused Window.
protected boolean requestFocus(boolean temporary)
// Requests that this Component get the input focus, and that this Component's top-level ancestor become the focused Window.
boolean requestFocusInWindow()
// Requests that this Component get the input focus, if this Component's top-level ancestor is already the focused Window.
protected boolean requestFocusInWindow(boolean temporary)
// Requests that this Component get the input focus, if this Component's top-level ancestor is already the focused Window.
void setFocusable(boolean focusable)
// Sets the focusable state of this Component to the specified value.
void setFocusTraversalKeys(int id, Set keystrokes)
// Sets the focus traversal keys for a given traversal operation for this Component.
void setFocusTraversalKeysEnabled(boolean focusTraversalKeysEnabled)
// Sets whether focus traversal keys are enabled for this Component.
void transferFocusBackward()
// Transfers the focus to the previous component, as though this Component were the focus owner.
void transferFocusUpCycle()
// Transfers the focus up one focus traversal cycle.
Focusmethoden in Container
boolean areFocusTraversalKeysSet(int id)
// Returns whether the Set of focus traversal keys for the given focus traversal operation has been explicitly defined for this Container.
Set getFocusTraversalKeys(int id)
// Returns the Set of focus traversal keys for a given traversal operation for this Container.
FocusTraversalPolicy getFocusTraversalPolicy()
// Returns the focus traversal policy that will manage keyboard traversal of this Container's children, or null if this Container is not a focus cycle root.
boolean isFocusCycleRoot()
// Returns whether this Container is the root of a focus traversal cycle.
boolean isFocusCycleRoot(Container container)
// Returns whether the specified Container is the focus cycle root of this Container's focus traversal cycle.
boolean isFocusTraversalPolicySet()
// Returns whether the focus traversal policy has been explicitly set for this Container.
void setFocusCycleRoot(boolean focusCycleRoot)
// Sets whether this Container is the root of a focus traversal cycle.
void setFocusTraversalKeys(int id, Set keystrokes)
// Sets the focus traversal keys for a given traversal operation for this Container.
void setFocusTraversalPolicy(FocusTraversalPolicy policy)
// Sets the focus traversal policy that will manage keyboard traversal of this Container's children, if this Container is a focus cycle root.
void transferFocusBackward()
// Transfers the focus to the previous component, as though this Component were the focus owner.
void transferFocusDownCycle()
// Transfers the focus down one focus traversal cycle.