Das GUI-Framework JControl/Wombat stellt Mechanismen zur Nachrichten-basierten Ereignisbehandlung zur Verfügung, die von allen interaktiven Komponenten verwendet werden. Programmierer von Anwendungen auf der Basis von JControl/Wombat 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/Wombat: Eine Nachrichtenschleife, die als Thread im Hintergrund arbeitet, wird von der Klasse Frame automatisch installiert. Diese Schleife fragt kontinuierlich die Tastatur und den Touch-Screen ab und ggf. ein KeyEvent, bzw. ein TouchEvent aus, wenn vom Benutzer eine Eingabe getätigt wird. Das Event wird an das Container-Framework der Benutzeroberfläche übermittelt, welches nun herausfinden muss, welcher GUI-Komponente es zugeordnet werden muss. Dies geschieht je nach Event-Typ über die Position der GUI-Komponente (TouchEvent) oder über den Eingabefokus (KeyEvent). Die ermittelte GUI-Komponente reagiert nun auf die Eingabe und erzeugt ggf. ein ActionEvent.
Hat das Anwendungsprogramm über die Methode setActionListener(ActionListener listener) einen ActionListener an die entsprechende GUI-Komponente angeschlossen, kann sie auf dieses reagieren. Dazu wird von JControl/Wombat beim Auftreten eines ActionEvents die Methode onActionEvent(ActionEvent event) aufgerufen. In deren Implementierung kann nun eine anwendungsspezifische Aktion ausgeführt werden.
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.wombat.Button; |
| 2 | import jcontrol.ui.wombat.Container; |
| 3 | import jcontrol.ui.wombat.Frame; |
| 4 | import jcontrol.ui.wombat.Label; |
| 5 | import jcontrol.ui.wombat.event.ActionEvent; |
| 6 | import jcontrol.ui.wombat.event.ActionListener; |
| 7 | |
| 8 | /** |
| 9 | * <p>This example demonstrates how to handle |
| 10 | * events within the GUI framework JControl/Wombat. |
| 11 | * This program needs the image resource |
| 12 | * 'mouse.jcif'.</p> |
| 13 | * |
| 14 | * <p>(C) DOMOLOGIC Home Automation GmbH 2003-2005</p> |
| 15 | */ |
| 16 | public class WombatEventHandlingExample |
| 17 | extends Frame implements ActionListener { |
| 18 | // the Label |
| 19 | Label label; |
| 20 | // the right Button |
| 21 | Button button_right; |
| 22 | |
| 23 | /** |
| 24 | * Create two buttons and a label and add an ActionListener. |
| 25 | */ |
| 26 | public WombatEventHandlingExample() { |
| 27 | // create the Buttons |
| 28 | Button b1 = new Button("Left Button", 2, 10, 60, 13); |
| 29 | button_right = new Button("Right Button", 66, 10, 60, 13); |
| 30 | |
| 31 | // add the ActionListener |
| 32 | b1.setActionListener(this); |
| 33 | button_right.setActionListener(this); |
| 34 | |
| 35 | // create a content pane |
| 36 | Container content = new Container(); |
| 37 | this.setContent( content); |
| 38 | |
| 39 | // add the Buttons to the Frame |
| 40 | content.add(b1); |
| 41 | content.add(button_right); |
| 42 | |
| 43 | // create the Label |
| 44 | label = new Label("Please press a button!", 0, 30, 128, 10, |
| 45 | Label.STYLE_ALIGN_CENTER); |
| 46 | content.add(label); |
| 47 | } |
| 48 | |
| 49 | /** |
| 50 | * This is the event handler. When a component fires an |
| 51 | * ActionEvent for us, this method is invoked. |
| 52 | */ |
| 53 | public void onActionEvent(ActionEvent event) { |
| 54 | // check whether this is a BUTTON_PRESSED event |
| 55 | if (event.type == ActionEvent.BUTTON_PRESSED) { |
| 56 | |
| 57 | // recognize event's source by using getActionCommand() |
| 58 | if ( "Left Button".equals(event.command)) |
| 59 | label.setText("You pressed the left button!"); |
| 60 | |
| 61 | // recognize event's source by using getSource() |
| 62 | if (event.source == button_right) |
| 63 | label.setText("The right button was hit!"); |
| 64 | } |
| 65 | } |
| 66 | |
| 67 | /** |
| 68 | * Instantiate and show the main frame. |
| 69 | */ |
| 70 | public static void main(String[] args) { |
| 71 | new WombatEventHandlingExample().setVisible(true); |
| 72 | } |
| 73 | } |
Die ActionListener-Instanz zum Empfangen von ActionEvents ist in dem Beispiel in vorigem Abschnitt die Klasse WombatEventHandlingExample 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:
| ... | |
| 16 public class WombatEventHandlingExample | |
| 17 extends Frame implements ActionListener { | |
| ... | |
| 31 // add the ActionListener | |
| 32 b1.setActionListener(this); | |
| 33 button_right.setActionListener(this); | |
| ... | |
| 52 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.
Die Klasse ActionEvent enthält drei Datenfelder, die der Anwendung eine nähere Zuordnung ermöglichen: type, command and source.
int type: Dieses Datenfeld enthält den Typen des ActionEvents. Tabelle 1 listet die möglichen Werte auf:
| Wert | 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. |
jcontrol.ui.wombat.event.ActionEvent.type
String command: Über den command-String können UI-Komponenten einem ActionEvent Informationen mit auf den Weg geben, die vom Empfänger ausgelesen und verwertet werden können. Um welche Information es sich handelt, ist Komponenten-abhängig. Bei Buttons wird beispielsweise die Beschriftung übermittelt. Beachten Sie aber, dass das command auch null sein kann.ActionProducer source: Dieses Datenfeld enthält eine Referenz auf das Objekt, welches das ActionEvent ausgelöst wird.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.type). Dann soll entschieden werden, ob der linke oder der rechte Button gedrückt wurde. Der linke Button wird dabei mit Hilfe von event.command anhand seiner Beschriftung identifiziert, der rechte dagegen durch einen Aufruf von event.source. Letztere Technik erscheint zwar zunächst eleganter, setzt aber voraus, dass eine Referenz 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.
| ... | |
| 53 public void onActionEvent(ActionEvent event) { | |
| 54 // check whether this is a BUTTON_PRESSED event | |
| 55 if (event.type == ActionEvent.BUTTON_PRESSED) { | |
| 56 | |
| 57 // recognize event's source by using getActionCommand() | |
| 58 if ( "Left Button".equals(event.command)) | |
| 59 label.setText("You pressed the left button!"); | |
| 60 | |
| 61 // recognize event's source by using getSource() | |
| 62 if (event.source == button_right) | |
| 63 label.setText("The right button was hit!"); | |
| 64 } | |
| 65 } | |
| ... |
Welche Arten von ActionEvents durch die verschiedenen Komponenten von JControl/Wombat 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.