Einführung in die OOP mit Java Das Event-Hanlding
Übersicht Event - Handling Das im JDK 1.1 Grundlagen Ereignistypen Ereignisquellen Adapterklassen für den Nachrichtenverkehr Variante1: Implementierung eines EventListener-Interfaces Variante2: Adapter und Innere Klassen Variante3: Adapter und Anonyme Klassen Variante4: Trennung von GUI und Anwendungscode
Grundlagen Kommunikation zwischen Betriebssystem und Anwendungsprogramm hauptsächlich durch versenden von Nachrichten Ereignisse: Mausklicks, Bewegungen des Mauszeigers, Tastatureingaben oder Veränderungen an der Größe oder Lage des Fensters
Grundlagen Bei der Verarbeitung des Nachrichtenverkehrs sind zwei verschiedene Arten von Objekten beteiligt Ereignisquellen (EventSources): Auslöser der Nachricht, z.b. ein Button der betätigt wird Ereignisempfänger (EventListener): Empfänger der Nachricht, kann jedes beliebige Objekt sein
Grundlagen Die Ereignisempfänger müssen sich bei den Ereignisquellen anmelden, damit sie benachrichtigt werden Dazu dienen spezielle Methoden z.b. addmouselistener(mouselistener) removemouselistener(mouselistener)
Grundlagen Vorteil: Es verringert den Nachrichten Verkehr, da nur Nachrichten verschickt werden, wenn sich Empfänger angemeldet haben Es erlaubt eine klare Trennung zwischen Programmcode zur Oberflächengestaltung und solchem zur Implementierung der Anwendungslogik
Ereignistypen Low-Level-Ereignisse
Ereignistypen Klasse EventObject public Object getsource() Klasse MouseEvent Klick- und Drag-Ereignisse Mausbewegungen Mit getid() kann das Programm herausfinden, um welche Art von Ereignis es sich handelt punlic int getid()
Ereignisempfänger (EventListeners)
Ereignisquellen (EventSources) Fenster, Dialogelemente oder Programmobjekte Sendet nur ein Ereignis wenn sich ein Empfänger registriert hat Registrierung über spezielle Methoden z.b. addmouselistener( )
Ereignisquellen (EventSources) Unterstützt das Multicasting von Ereignissen Daraus Resultiert, das Ereignisempfänger alle zugehörigen Methoden implementieren müssen Ein "MouseListener" z. B. alle fünf Methoden. Das wird dadurch erzwungen, dass im Interface "MouseListener" alle fünf Methoden als abstrakte Methoden aufgeführt sind
Adapterklassen Eine Adapterklasse in Java ist eine Klasse, die ein vorgegebenes Interface mit leeren Methodenrümpfen implementiert. Adapterklassen werden verwendet, wenn aus einem Interface lediglich ein Teil der Methoden benötigt wird Zu jedem Low-Level-Ereignisempfänger gibt es eine passende Adapterklasse
Implementierung eines EventListener-Interfaces public class Event1 extends JPanel implements MouseListener { private int count = 0; Event1() {addmouselistener(this); public void paintcomponent(graphics g) { super.paintcomponent(g); g.drawstring("counter: " + count, 20, 20); public static void main(string[] args) { JFrame window = new JFrame("Event1"); window.setsize(160, 100); window.setlocation(100, 100); window.setdefaultcloseoperation(jframe.exit_on_close); window.getcontentpane().add(new Event1()); window.setvisible(true); public void mouseentered(mouseevent me) {count++;repaint(); public void mouseclicked(mouseevent me) { public void mouseexited(mouseevent me) { public void mousepressed(mouseevent me) { public void mousereleased(mouseevent me) {
Implementierung eines EventListener-Interfaces Die Verbindung der Ereignisquelle mit dem Ereignisempfänger erfolgt durch den Aufruf der Methode addmouselistener(this); Die Klasse "Event1" meldet sich selbst als Ereignisempfänger an Alle Mausereignisse werden dadurch an die Klasse Event1 weitergeleitet und führen zum Aufruf der Methoden des Interfaces MouseListener
Implementierung eines EventListener-Interfaces Nachteil: Für jeden Ereignistyp muss eine passende Listener-Klasse registriert werden, dadurch werden schnell viele leere Methodenrüpfe in der Fensterklasse auftreten Höchstens für kleine Programme geeignet
Adapter und Innere Klassen public class Event2 extends JPanel { private int count = 0; Event2() { addmouselistener(new MyMouseListener()); public void paintcomponent(graphics g) { super.paintcomponent(g); g.drawstring("counter: " + count, 20, 20); public static void main(string[] args) { JFrame window = new JFrame("Event2"); window.setsize(160, 100); window.setlocation(100, 100); window.setdefaultcloseoperation(jframe.exit_on_close); window.getcontentpane().add(new Event2()); window.setvisible(true); //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - class MyMouseListener extends MouseAdapter { public void mouseentered(mouseevent me) { count++; repaint();
Adapter und Innere Klassen Eine Instanz von "MyMouseListener" wird angelegt und als Ereignisempfänger angemeldet addmouselistener(new MyMouseListener()) Die innere Klasse überschreibt die Methode "mouseentered" der Adapterklasse class MyMouseListener extends MouseAdapter { public void mouseentered(mouseevent me) { count++; repaint();
Adapter und Innere Klassen Vorteil: Es werden keine unnützen Methodenrümpfe erzeugt, da nur die tatsächlich benötigten Methoden implementiert werden müssen
Adapter und Anonyme Klassen public class Event3 extends JPanel { private int count = 0; Event3() { addmouselistener(new MouseAdapter() { public void mouseentered(mouseevent me) { count++; repaint(); ); public void paintcomponent(graphics g) { super.paintcomponent(g); g.drawstring("counter: " + count, 20, 20); public static void main(string[] args) { JFrame window = new JFrame("Event3"); window.setsize(160, 100); window.setlocation(100, 100); window.setdefaultcloseoperation(jframe.exit_on_close); window.getcontentpane().add(new Event3()); window.setvisible(true);
Adapter und Anonyme Klassen Im Konstruktor wird eine Kurzschreibweise eingesetzt addmouselistener(new MyMouseListener()); zusammen mit der Definition class MyMouseListener extends MouseAdapter { public void mouseentered(mouseevent me) { count++; repaint(); wird ersetzt durch: addmouselistener( new MouseAdapter() { public void mouseentered(mouseevent me) { count++; repaint(); );
Adapter und Anonyme Klassen Vorteil: Verminderter Aufwand, denn es muss keine separate Klassendefinition angelegt werden Empfiehlt sich vor allem, wenn sehr wenig Code für den Ereignisempfänger benötigt wird
Trennung von GUI- und Anwendungscode public class Listing2805{ public static void main(string[] args){ MainFrameCommand cmd =new MainFrameCommand(); MainFrameGUI gui = new MainFrameGUI(cmd); class MainFrameGUI extends Frame{ public MainFrameGUI(KeyListener cmd) { super("nachrichtentransfer"); setbackground(color.lightgray); setsize(600,300); setlocation(200,100); setvisible(true); addkeylistener(cmd); public void paint(graphics g) { g.setfont(new Font("Serif",Font.PLAIN,36)); g.drawstring("zum Beenden bitte ESC drücken...",10,100); class MainFrameCommand extends KeyAdapter{ public void keypressed(keyevent event){ Frame source = (Frame)event.getSource(); if (event.getkeycode() == KeyEvent.VK_ESCAPE){ source.setvisible(false); source.dispose(); System.exit(0);
Trennung von GUI- und Anwendungscode Vorwiegend für größere Programme geeignet Für kleiner Programme, oder solche mit wenig Ereigniscode, sollte eher eine der vorherigen Varianten gewählt werden
Noch Fragen
Danke für ihre Aufmerksamkeit