9.2.6 | Event-Adapter |
In den meisten von EventListener abgeleiteten Interfaces ist mehr als eine Methode definiert. Will man nun einem Objekt die Fähigkeit verleihen, EventListener für ein bestimmtes Ereignis zu sein, so ist es notwendig, wirklich alle Methoden zu implementieren, die im entsprechenden EventListener-Interface definiert sind. Das ist auch dann der Fall, wenn nur eine dieser Methoden benötigt wird. Hierzu ein kleines Beispiel zur Behandlung von Maus-Events:import java.applet.Applet; import java.awt.*; import java.awt.event.*; public class MouseListenerDemo extends Applet implements MouseListener { public void init() { setBackground(Color.blue); addMouseListener(this); } public void mouseClicked(MouseEvent e) { getAppletContext().showStatus( "click at x:"+e.getX()+" y:"+e.getY()); } public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} }Wie das Beispiel zeigt, muss man für die Reaktion auf Maus-Ereignisse alle Methoden implementieren, die im Interface MouseListener definiert sind. Auch wenn, wie in diesem Fall, eigentlich nur eine Methode benötigt wird.
Um dies zu umgehen, werden so genannte Event-Adapter definiert. Ein Event-Adapter ist eine Klasse, die bereits Dummy-Implementierungen für alle in einem EventListener-Interface definierten Methoden enthält. Durch Ableiten einer Unterklasse von einem Event-Adapter ist es nur noch notwendig, die Methoden zu überschreiben, die tatsächlich benötigt werden. Die Klasse, in der das Ereignis ausgelöst wird, kann in der Regel nicht direkt von einer Event-Adapter-Klasse abgeleitet werden, da sie in vielen Fällen bereits von einer anderen Komponente abgeleitet ist.
Deshalb ist meist die Definition einer Hilfsklasse für die Reaktion auf ein Ereignis notwendig. Diese Hilfsklasse wird von dem benötigten Event-Adapter abgeleitet. Dem Konstruktor dieser Hilfsklasse kann man einen Verweis auf das Objekt übergeben, in dem die eigentliche Reaktion auf das Ereignis stattfindet. Die benötigten Methoden des Event-Adapters werden anschließend so implementiert, dass beim Auftreten eines Ereignisses aus der Event-Behandlungsmethode der Hilfsklasse eine Methode des reagierenden Objektes aufgerufen wird.Das Prinzip der Event-Adapter ist in Abbildung 9.3 veranschaulicht. Die Ereignisquelle hält einen Verweis auf den Event-Adapter. Der Event-Adapter implementiert alle Methoden, die im entsprechenden EventListener-Interface definiert sind. Von einer solchen Adapter-Klasse kann man nun eine eigene Klasse ableiten, die nur noch die benötigten Methoden implementiert. Durch diese Vorgehensweise müssen wirklich nur die Methoden des EventListener-Interfaces implementiert werden, die tatsächlich gebraucht werden.
Der Code für das letzte Beispiel sieht mit einem Event-Adapter folgendermaßen aus:import java.applet.Applet; import java.awt.*; import java.awt.event.*; public class MouseAdapterDemo extends Applet { public void init() { setBackground(Color.blue); addMouseListener(new MyMouseAdapter(this)); } public void showPoint(int x, int y) { getAppletContext().showStatus("click at x:" +x+" y:"+y); } } class MyMouseAdapter extends MouseAdapter { protected MouseAdapterDemo demo; public MyMouseAdapter(MouseAdapterDemo demo) { this.demo = demo; } public void mouseClicked(MouseEvent e) { demo.showPoint(e.getX(), e.getY()); } }
In diesem Fall implementiert nicht direkt die Hauptklasse des Applets das MouseListener-Interface, sondern es wird eine Hilfsklasse MyMouseAdapter eingeführt, die von der Klasse MouseAdapter abgeleitet ist. MouseAdapter enthält Dummy-Implementierungen für alle in MouseListener definierten Methoden. Deshalb ist es möglich, in MyMouseAdapter nur die Methode zu implementieren, die im Programm benötigt wird. Dem Konstruktor der Adapterklasse wird ein Verweis auf die Hauptklasse des Applets übergeben.
Da die Klasse MyMouseAdapter die Funktion des Listeners übernimmt, muss sie auch bei der Ereignisquelle registriert werden. Das geschieht in der init()-Methode des Applets:addMouseListener(new MyMouseAdapter(this));Die Ereignisquelle ist in diesem Fall das Applet selbst. Als Event-Listener wird eine neues Exemplar von MyMouseAdapter erzeugt und der Methode addMouseListener(MouseListener) übergeben.
Wird eine Maustaste gedrückt, so wird die Adapterklasse davon unterrichtet. Die Methode mouseClicked(MouseEvent) kann nun so implementiert werden, dass eine Methode der Applet-Klasse aufgerufen wird:public void mouseClicked(MouseEvent e) { demo.showPoint(e.getX(), e.getY()); }