Advanced   Java   Services
New 1.4 FocusManagement
Back Next Up Home


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

comp.setFocusTraversalKeysEnabled(false) ;

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



FocusTraversalPolicy (lokal)


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.

top Back Next Up Home