10.9Swing Action *
Aktiviert der Nutzer eine Schaltfläche, etwa für »Ende« oder einen Eintrag im Menü, löst er damit eine Aktion aus. Das Hinzufügen der Ereignisbehandler zu den Schaltflächen ist die offensichtliche Möglichkeit. Swing bietet mit Aktionen aber eine weitere Möglichkeit, deren Sinn klar wird, wenn wir uns folgendes Szenario überlegen: Der Benutzer soll nicht nur über das Menü eine Aktion auslösen, sondern auch über die Symbolleiste. Die spontane Antwort bestünde darin, beiden Schaltflächen einfach den gleichen Ereignisbehandler zu geben. Sicherlich ist das möglich. Gehen wir aber einen Schritt weiter: Was geschieht, wenn aufgrund eines bestimmten Zustands die beiden Auslöser deaktiviert werden müssen? Und wie sieht der Aufbau aus, wenn beide beispielsweise das gleiche Icon, den gleichen Tooltip und den gleichen Text tragen? Das wäre eine Quellcodeduplizierung und unschön.
javax.swing.Action
Swing beantwortet die Fragen mit der Schnittstelle javax.swing.Action, mit der sich Programmlogik und Zustände wie Aufschrift und Text repräsentieren lassen. In unserem Szenario müssten wir nun einmal das Action-Objekt aufbauen und dann in das Menü und die Symbolleiste hängen.
Während Action eine Schnittstelle ist, die ActionListener erweitert und zusätzliche Operationen deklariert, nutzen wir im Allgemeinen Unterklassen von AbstractAction. Bei dieser Klasse müssen wir nur noch actionPerformed(ActionEvent) überschreiben und dort die Aktion implementieren:
Listing 10.19com/tutego/insel/ui/swing/JButtonAction.java, Ausschnitt
@Override public void actionPerformed( ActionEvent e ) {
System.exit( 0 );
}
};
JButton button2 = new JButton( exitAction );
frame.add( button2 );
Ein Action-Objekt lässt sich in jedem Konstruktor einer Schaltfläche übergeben, so auch dem JButton oder JMenuItem. Sie kann alternativ über setAction(Action) mit jeder Schaltfläche verbunden werden, die AbstractButton erweitert.
Eigenschaften der Action-Objekte
Während Listener keinen Zustand haben, haben Action-Objekte ganz klar einen Zustand – das ist ja auch ihre Aufgabe. Die konkreten Zustände einer Aktion, wie Beschriftung oder Tooltip, bestimmen Schlüssel-Wert-Paare, die putValue(String, Object) setzt. Für den Schlüssel von putValue(…) deklariert die Klasse bestimmte Zeichenketten über Konstanten, die mit speziellen Bedeutungen verbunden sind. Die wichtigsten sind:
Konstanten | Bedeutung |
---|---|
Action.NAME | Name der Aktion, die für die Schaltfläche oder das Menü verwendet wird |
Action.SHORT_DESCRIPTION | Kurzbeschreibung für Tooltips |
Action.LONG_DESCRIPTION | Längere Beschreibung, die für die Hilfe verwendet werden könnte |
Action.ACCELERATOR_KEY | Tastatur-Shortcut |
Action.MNEMONIC_KEY | Mnemonic |
Action.SMALL_ICON | kleines Icon für Menüeinträge |
Action.LARGE_ICON_KEY | größeres Icon für Symbolleisten und Schaltflächen |
Tabelle 10.6Die wichtigsten Konstanten
Die Icons werden nicht für JCheckBox, JToggleButton oder JRadioButton verwendet. Ist für JButton kein LARGE_ICON_KEY definiert, nimmt es das SMALL_ICON an.
Ob eine Aktion aktiviert ist, bestimmt setEnabled(boolean) und erfragt isEnabled(). Während putValue(String, Object) den Wert setzt, erfragt ihn getValue(String).
[zB]Beispiel
Ein Action-Objekt mit zwei gesetzten Properties zum Beenden der Applikation:
Listing 10.20JButtonAction2.java, ExitAction
{
putValue( Action.NAME, "Beenden" );
putValue( Action.DISPLAYED_MNEMONIC_INDEX_KEY, 0 );
}
@Override public void actionPerformed( ActionEvent e ) {
System.exit( 0 );
}
}
Indem wir DISPLAYED_MNEMONIC_INDEX_KEY auf 0 setzen, erreichen wir, dass vom String "Beenden" das »B« unterstrichen und zum Tastenkürzel wird.
Ein größeres Beispiel mit Aktionen bietet Abschnitt 10.16, »Menüs und Symbolleisten«.