Das GUI-Framework JControl/Vole stellt Mechanismen zur Nachrichten-basierten Ereignisbehandlung zur Verfügung, die von allen interaktiven Komponenten verwendet werden. Programmierer von Anwendungen auf der Basis von JControl/Vole müssen lediglich einen ActionListener
implementieren, um auf Benutzereingaben reagieren zu können. Wie ein ActionListener
auf eine bestimmte GUI-Komponente installiert und seine ActionEvents
verarbeitet werden, wird in den folgenden Abschnitten gezeigt.
Bild 1 skizziert das Prinzip der Nachrichtenübermittlung bei JControl/Vole: Eine Nachrichtenschleife, die als Thread im Hintergrund arbeitet, wird von der Klasse Frame
automatisch installiert. Diese Schleife fragt kontinuierlich die Tastatur ab und löst ein KeyEvent
aus, wenn eine Taste gedrückt wird. Das KeyEvent
wird an das Container
-Framework der Benutzeroberfläche übermittelt, welches nun herausfinden muss, welcher GUI-Komponente das KeyEvent
zugeordnet werden muss. Letztendlich erreicht das Event diejenige GUI-Komponente, die momentan den Eingabefokus besitzt, und wird dort in ein ActionEvent
umgewandelt.
Nur wenn das Anwendungsprogramm einen ActionListener
auf die GUI-Komponente installiert hat (durch Aufruf der Methode {Komponente}.
setActionListener(ActionListener listener)
), kann dieses auch ein ActionEvent
auslösen. Dann wird die Methode onActionEvent(ActionEvent event)
des entsprechenden ActionListeners
aufgerufen und das Anwendungsprogramm kann auf die Nachrichten dieser GUI-Komponente reagieren.
Ein Beispielprogramm soll nun die Behandlung von ActionEvents
veranschaulichen. Wir erzeugen zwei Buttons
und ein Label
. Auf beide Schaltflächen wird ein ActionListener
installiert, der auf ihre Betätigung durch den Benutzer reagieren soll, indem er den Text des Labels
ändert.
1 | import jcontrol.ui.vole.Button; |
2 | import jcontrol.ui.vole.Frame; |
3 | import jcontrol.ui.vole.Label; |
4 | import jcontrol.ui.vole.event.ActionEvent; |
5 | import jcontrol.ui.vole.event.ActionListener; |
6 | |
7 | /** |
8 | * <p>This example demonstrates how to handle |
9 | * events within the GUI framework JControl/Vole. |
10 | * This program needs the image resource |
11 | * 'mouse.jcif'.</p> |
12 | * |
13 | * <p>(C) DOMOLOGIC Home Automation GmbH 2003-2005</p> |
14 | */ |
15 | public class VoleEventHandlingExample |
16 | extends Frame implements ActionListener { |
17 | // the Label |
18 | Label label; |
19 | // the right Button |
20 | Button button_right; |
21 | |
22 | /** |
23 | * Create two buttons and a label and add an ActionListener. |
24 | */ |
25 | public VoleEventHandlingExample() { |
26 | // create the Buttons |
27 | Button b1 = new Button("Left Button", 2, 10, 60, 13); |
28 | button_right = new Button("Right Button", 66, 10, 60, 13); |
29 | |
30 | // add the ActionListener |
31 | b1.setActionListener(this); |
32 | button_right.setActionListener(this); |
33 | |
34 | // add the Buttons to the Frame |
35 | this.add(b1); |
36 | this.add(button_right); |
37 | |
38 | // create the Label |
39 | label = new Label("Please press a button!", 0, 30, 128, 10, |
40 | Label.ALIGN_CENTER); |
41 | this.add(label); |
42 | } |
43 | |
44 | |
45 | /** |
46 | * This is the event handler. When a component fires an |
47 | * ActionEvent for us, this method is invoked. |
48 | */ |
49 | public void onActionEvent(ActionEvent event) { |
50 | // check whether this is a BUTTON_PRESSED event |
51 | if (event.getType() == ActionEvent.BUTTON_PRESSED) { |
52 | |
53 | // recognize event's source by using getActionCommand() |
54 | if (event.getActionCommand().equals("Left Button")) |
55 | label.setLabel("You pressed the left button!", true); |
56 | |
57 | // recognize event's source by using getSource() |
58 | if (event.getSource() == button_right) |
59 | label.setLabel("The right button was hit!", true); |
60 | } |
61 | } |
62 | |
63 | |
64 | /** |
65 | * Instantiate and show the main frame. |
66 | */ |
67 | public static void main(String[] args) { |
68 | new VoleEventHandlingExample().show(); |
69 | } |
70 | } |
Die ActionListener
-Instanz zum Empfangen von ActionEvents
ist in dem Beispiel in vorigem Abschnitt die Klasse VoleEventHandlingExample
selbst. Dies wird bei der Deklaration der Klasse durch die Angabe "implements ActionListener
" definiert. Um die Anforderungen an eine ActionListener
-Instanz zu erfüllen, muss die Methode onActionEvent(ActionEvent event)
implementiert werden. Die folgenden Bereiche wurden dem Quelltext-Listing entnommen und zeigen die für eine erfolgreiche Installation eines ActionListeners
relevanten Passagen:
... | |
15 public class VoleEventHandlingExample | |
16 extends Frame implements ActionListener { | |
... | |
30 // add the ActionListener | |
31 b1.setActionListener(this); | |
32 button_right.setActionListener(this); | |
... | |
49 public void onActionEvent(ActionEvent event) { | |
... |
Damit onActionEvent
von den beiden Buttons
auch aufgerufen wird, übergeben wir mit Hilfe der Methode Button.setActionListener(this)
einen Zeiger auf die Klasseninstanz und registrieren damit unseren ActionListener
. Hier kann natürlich auch ein Zeiger auf eine andere Klasse übergeben werden, die das Interface ActionListener
implementiert.
Zur Verarbeitung der empfangenen Nachrichten stellt die Klasse ActionEvent
drei Methoden zur Verfügung: getType()
, getActionCommand()
und getSource()
.
int getType()
: Diese Methode gibt den Typ des ActionEvents
als int
zurück. In Tabelle 1 sind die möglichen Rückgabewerte aufgelistet:
Rückgabewert | Beschreibung |
---|---|
BUTTON_PRESSED | Die Nachricht wurde von einer Schaltfläche ausgelöst. |
ITEM_SELECTED | Ein List - oder ComboBox -Eintrag wurde ausgewählt. |
VALUE_CHANGED | Ein numerischer Wert wurde geändert (z.B. bei einem Slider ). |
STATE_CHANGED | Der Zustand eines RadioButtons oder einer CheckBox wurde geändert. |
String getActionCommand()
: Über das ActionCommand
können UI-Komponenten einem ActionEvent
Informationen mit auf den Weg geben. Vom Empfänger können diese mit Hilfe der getActionCommand()
-Methode wieder ausgelesen werden. Um welche Information es sich handelt, ist Komponenten-abhängig. Bei Buttons
wird beispielsweise die Beschriftung übermittelt. Beachten Sie aber, dass das ActionCommand
auch null
sein kann.Component getSource()
: Mit Hilfe der getSource()
-Methode kann die Quelle eines ActionEvents
erfragt werden. Der Rückgabewert ist ein Zeiger auf ein Component
.Im unten dargestellten Ausschnitt des Beispiel-Programms werden zwei Techniken demonstriert, wie die Quelle eines ActionEvents
ermittelt werden kann. Zunächst prüft die Methode onActionEvent
, ob das empfangene Ereignis von einem Button
ausgelöst wurde (event.getType()
). Dann soll entschieden werden, ob der linke oder der rechte Button
gedrückt wurde. Der linke Button
wird dabei mit Hilfe von event.getActionCommand
anhand seiner Beschriftung identifiziert, der rechte dagegen durch einen Aufruf von event.getSource()
. Letztere Technik erscheint zwar zunächst eleganter, setzt aber voraus, dass ein Zeiger auf den Button
als Instanzvariable der Klasse zur Verfügung steht. Dies ist evt. nicht der Fall, wenn der ActionListener
von einer separaten Klasse implementiert wird.
... | |
49 public void onActionEvent(ActionEvent event) { | |
50 // check whether this is a BUTTON_PRESSED event | |
51 if (event.getType() == ActionEvent.BUTTON_PRESSED) { | |
52 | |
53 // recognize event's source by using getActionCommand() | |
54 if (event.getActionCommand().equals("Left Button")) | |
55 label.setLabel("You pressed the left button!", true); | |
56 | |
57 // recognize event's source by using getSource() | |
58 if (event.getSource() == button_right) | |
59 label.setLabel("The right button was hit!", true); | |
60 } | |
61 } | |
... |
Welche Arten von ActionEvents
durch die verschiedenen Komponenten von JControl/Vole generiert werden, ist in der jeweiligen API-Dokumentation beschrieben. Allen UI-Komponenten gemein ist allerdings, dass sie die Methode setActionListener(ActionListener listener)
bereitstellen. So kann ein Anwendungsprogramm durch den Benutzer ausgelöste Ereignisse individuell behandeln und selbst festlegen, auf welche es reagieren möchte und welche ignoriert werden sollen.
Wenn Sie weitere Beispiele für die Behandlung von UI-Nachrichten betrachten wollen, sei an dieser Stelle auf die umfangreich dokumentierten Beispielprogramme in der Rubrik Examples & Demos http://www.jcontrol.org/examples/index_de.html verwiesen.