Upload
others
View
8
Download
0
Embed Size (px)
Citation preview
Eventhandling in Java
Bisher:
� OO-Grundlagen,
� Programmablauf,
� Zeichenmoglichkeiten,
� Anordnung von Bedienelementen.
Was fehlt?
Interaktivitat !!!
– OO-Graphics in Java – Eventhandling in Java 144
Worauf ein Programmreagieren muss
Low-Level:
� Tastatureingaben,� Maus-Ereignisse,� Timer-Ereignisse.
High-Level:
� Fenster schliessen/offnen,� Grossenveranderungen,� Knopf auf Bildschirm gedruckt,� Text editiert,� �����
– OO-Graphics in Java – Eventhandling in Java 145
Java 1.1 vs. Java 1.0
Achtung (wichtige Warnung):
Das Eventhandling von Java 1.1 unter-scheidet sich wesentlich vom Event-handling in Java 1.0.
Java 1.0 Stil ist in Java 1.1 zwar nochmoglich, aber nicht empfohlen (depre-cated).
Im folgenden wird Java 1.1 Stil vermit-telt.
Java 1.1 wird von Netscape 4.06, vonInternet Explorer 4.01 und von Hotjava(Sun Browser) unterstutzt.
– OO-Graphics in Java – Eventhandling in Java 146
Event
Event: Das Eintreten eines Ereignisses, auf welches das Pro-gramm reagieren muss (z.B. Tastendruck, Mausbewegung, ����� ).
Event-Quelle: Events werden immer dem Component-Objekt zu-geordnet, in dem sie entstehen — der “Event-Quelle”.
Event-Objekt: Das Auftreten eines Events ist verbunden mit derErzeugung eines Objektes. Dieses Objekt gehort einer der Unter-klassen von AWTEvent an. Es enthalt alle notwendigen Informatio-nen uber das Event.
Event-Listener: Component-Objekte speichern eine Liste vonEventListener-Objekten ab. Dies sind Objekte, die uber das Auf-treten eines Events “benachrichtigt” werden sollen. Die ListenerObjekte sind jeweils spezialisiert auf bestimmte Event-Klassen.
Event-Action: Beim Auftreten eines Events veranlasst die Event-
Quelle den Aufruf einer standardisierten (dem Event zugeord-
neten) Methode bei allen fur diesen Event-Typ angemeldeten
Listener-Objekten. Der Aufruf dieser Methoden ist dem Event
selbst gleichzusetzen!
– OO-Graphics in Java – Eventhandling in Java 147
Das awt.event package
1995-7, Charles L. Perkins http://rendezvous.com/java
Objectjava.lang
java.awt.event
ComponentListener
FocusListener
KeyListener
MouseListener
MouseMotionListener
WindowListener
ActionListener
AdjustmentListener
ItemListener
EventObjectjava.util
AWTEventjava.awt-events
EventListenerjava.util
ActionEvent
AdjustmentEvent
ComponentAdapter
ComponentEvent
FocusAdapter
FocusEvent
InputEvent
ItemEvent
KeyAdapter
KeyEvent
MouseAdapter
MouseEvent
MouseMotionAdapter
PaintEvent
WindowAdapter
WindowEventSerializablejava.io-objects
AWTEventMulticaster
Objectjava.lang
Event
EventDispatchThreadlocal to package
Threadjava.lang
EventQueue
EventQueueItemlocal to package
EventObjectjava.util
AWTEvent
Serializablejava.io-objects
java.awt-eventss
ContainerListener
TextListener
ContainerAdapter
ContainerEvent
TextEvent
– OO-Graphics in Java – Eventhandling in Java 148
Event-Objekte
AWTEvent-Objekt � ���
����� ist ein Objekt welches das Auftreten eines Ereig-nisses beschreibt,
����� enthalt alle notwendigen Informationen, die dasEreignis betreffen (Wo? Wann? Wer? ��� � ),
����� ist quasi ein Brief von der Ereignisquelle an alleInteressenten.
����� besitzt zahlreiche Unterklassen, die spezia-lisierte Ereignisse beschreiben (MouseEvent,MouseMotionEvent, KeyEvent, WindowEvent,ActionEvent, � ��� )
– OO-Graphics in Java – Eventhandling in Java 149
Event Zyklus in Java-1.1
Erzeugung: Component-Objekte sind die Event-Quellen. Tritt ein zu einer Component gehoriges Ereig-nis auf (z.B. “Knopf-gedruckt” auf einem Button oder“Mouse-Drag” in einer Canvas), so wird ein entspre-chendes AWTEvent-Objekt erzeugt.
Verschicken: Jede Component hat eine Liste vonEventListener-Objekten. An diese wird das AWTEvent“verschickt” (d.h. bestimmte Methoden werden aufgeru-fen).
Verarbeitung: Die EventListener-Objekte mussenMethoden definieren, die auf das Verschicken des Er-eignisses reagieren konnen. Ein EventListener kannein Event als “abgearbeitet” markieren.
Consumed: Ein AWTEvent-Objekt ist “aufgebraucht”(consumed), wenn es an alle potentiellen Listener ver-schickt wurde.
– OO-Graphics in Java – Eventhandling in Java 150
Was passiert, wenn ein Knopfgedruckt wird ?
Press Me Knopf mittels Maus aktiviert
ButtonMouseclick veranlasst den
Button ein AWTEvent:
ActionEvent
zu erzeugen.
Dies Event wird an alle
ActionEventListener
des Buttons geschickt
listener.actionPerformed(event)
event
ActionEventHat alle Information
bzgl. Event- u.Eventquelle
und einen Identifier
der ausgefuehrten
Aktion.
MyAction-Listener
implementiert die Methode
actionPerformed()
in welcher festgelegt ist,
was bei Eintreten des
Events passieren soll
Die Klasse MyActionListener ist das einzige selbst-geschriebene Objekt in diesem Beispiel.
– OO-Graphics in Java – Eventhandling in Java 151
MyActionListener
Im selbst geschriebenen Code von MyActionListenerist festgelegt, was beim Auftreten eines ActionEventsgeschehen soll.
Die Klasse MyActionListener implementiert das In-terface ActionListener.
Dies erzwingt, dass in der Klasse MyActionListenerdie Methode actionPerformed implementiert ist.
Source-Code Gerust:
import java.awt.event.*;
public class MyActionListener implements ActionListener{
public void actionPerformed(ActionEvent e){.....
}.....
}
– OO-Graphics in Java – Eventhandling in Java 152
Event � Methodenaufruf
Ein Eventist der Aufruf einer Methode
in einem EventListener.
Bei dem Methodenaufruf wirdein Objekt der Klasse
AWTEvent als Parameter ubergeben.
Das AWTEvent-Objekt enthaltweitere Information uberdas eingetretene Event.
– OO-Graphics in Java – Eventhandling in Java 153
Programm-Beispiel furActionEvent
Ziel: Ein Button, der eine Zahlvariable hochzahlt undderen Inhalt auf dem Bildschirm anzeigt.
Code fur das Applet:
import java.awt.*; // verwendete Packagesimport java.awt.event.*;import java.applet.*;
public class CountApplet extends Applet {
public int count=0;public Label label = new Label("0");
public void init() {
setLayout(new FlowLayout());Button b = new Button("Press Me");b.addActionListener(new MyActionListener(this)); // <---ADD LISTENERadd(b);add(label);
}}
Hier werden in der Initialisierung lediglich der Button und das
Label zum Anzeigen bereitgestellt. Der Button erhalt einen
selbstdefinierten ActionListener namens MyActionListener.
– OO-Graphics in Java – Eventhandling in Java 154
Der Code furMyActionListener
Der Listener MyActionListener erhoht beim Auftre-ten des ActionEvents die Zahlervariable count des Ap-plets. Dann veranlasst er, dass der zugehorige Text er-zeugt wird, und erzwingt ein repaint des Applets.
Code fur den Listener:
import java.awt.event.*;
public class MyActionListener implements ActionListener{private CountApplet app;MyActionListener(CountApplet app) {this.app=app;
}
public void actionPerformed(ActionEvent e){app.count++;String s=(new Integer(app.count)).toString();app.label.setText(s);app.label.invalidate(); // Layout ist ungultigapp.validate(); // erzwinge neues Layoutapp.repaint(); // Zeichenanforderung
}}
Press Me 5
– OO-Graphics in Java – Eventhandling in Java 155
Erweiterte Version zum Auf- undAbzahlen
public class CountApplet extends Applet {
public int count=0;public Label label = new Label("0");public void init() {
setLayout(new FlowLayout());Button b1 = new Button("Increment");b1.addActionListener(new MyActionListener(1,this));Button b2 = new Button("Decrement");b2.addActionListener(new MyActionListener(-1,this));add(b1);add(b2);add(label);
}}
public class MyActionListener implements ActionListener{CountApplet app;private int step;MyActionListener(int st,CountApplet app) {this.app =app; step=st;
}
public void actionPerformed(ActionEvent e){app.count=app.count+step;String s=(new Integer(app.count)).toString();app.label.setText(s);app.label.invalidate();app.validate();app.repaint();
}}
Increment Decrement 5
– OO-Graphics in Java – Eventhandling in Java 156
Ubergabe von Information
Im Beispiel des Applets CountApplet kam es ledig-lich darauf an, dass uberhaupt ein ActionEvent auf-trat. Es wurde keine Information aus dem Event-Objektentnommen.
(In unserer “Briefmetapher”: Allein das Eintreffen desBriefes loste die Reaktion (hochzahlen) aus. Der Briefmusste gar nicht erst gelesen werden.)
Oftmals ist es allerdings notwendig, die im Eventubergebene Information abzufragen. Als “Informations-behalter” stellt AWTEvent diverse spezialisierte Unter-klassen bereit.
– OO-Graphics in Java – Eventhandling in Java 157
Count-Applet mit Lesen desEvents
Die folgende Increment/Decrement-Version stellt durchLesen der Button-Beschriftung fest, ob ab- oder auf-gezahlt werden soll.
Code des MouseListeners:
import java.awt.event.*;
public class MyActionListener implements ActionListener{private CountApplet app;MyActionListener(CountApplet app){this.app=app;
}
public void actionPerformed(ActionEvent e){if (e.getActionCommand().equals("Increment")) {//<<<< LESEN
app.count=app.count+1;}if (e.getActionCommand().equals("Decrement")) {//<<<< LESEN
app.count=app.count-1;}
String s=(new Integer(app.count)).toString();app.label.setText(s);app.label.invalidate();app.validate();app.repaint();
}}
– OO-Graphics in Java – Eventhandling in Java 158
Unterklassen von AWTEvent
Object
AWTEvent
ActionEvent
AdjustmentEvent
ComponentEvent
ItemEvent
TextEvent
ContainerEvent
FocusEvent
InputEvent
PaintEvent
WindowEvent
MouseEvent
KeyEvent
nicht instantiierbares abstraktes Objekt
instantiierbares Objekt
Die Unterklassen von AWTEvent sind spezialisierte“Datenbehalter”, fur die verschiedenen Ereignisse.
– OO-Graphics in Java – Eventhandling in Java 159
Beispiel: Methoden vonMouseEvent (I)
MouseEvent hat in der Klassenhierarchie die Position
AWTEvent � ComponentEvent � InputEvent � MouseEvent
MouseEvent besitzt u.a. die folgenden Methoden:
getClickCount(): Anzahl der Mouseclicks.
getPoint(): � x � y � -Position des Events relativ zur “Quell-component”.
getX(): x-Komponente des Events relativ zur “Quell-component”.
getY(): y-Komponente des Events relativ zur “Quell-component”.
isPopupTrigger(): Erzeugt das Event ein Pop-Up-Menu?
translatePoint(int, int): Verandert das Koordinatensystem des Events.
– OO-Graphics in Java – Eventhandling in Java 160
Beispiel: Methoden vonMouseEvent (II)
Die Oberklassen vom MouseEvent stellen zudem u.a.folgende Methoden zur Verfugung:
InputEvent:
getModifiers(): Liefert Modifizier-Flags fur das Ereignis.
getWhen(): Systemzeit zu der das Ereignis stattfand.
isAltDown(), isControlDown(), isMetaDown(), isShiftDown():
Wurden modifizierende Tasten gedruckt?
ComponentEvent:
getComponent(): Quell-Component, die das Event verursacht hat.
AWTEvent:
getID(): Event-Typ
Event: getSource(): Event-Quelle
– OO-Graphics in Java – Eventhandling in Java 161
Listener
Listener �����
����� sind Interfaces welche bestimmte Ereignisklas-sen gegeneinander abgrenzen (z.B. die Klasseder ActionEvents, MouseEvents, � ��� ),
����� legen Methoden fest, auf die man fur eineEreignisklasse reagieren konnen muss (z.B.actionPerformed() fur ActionEvents),
����� hat folgende Unterinterfaces:ActionListener, AdjustmentListener, ComponentListener,
ContainerListener, FocusListener, ItemListener,
KeyListener, MouseListener, MouseMotionListener,
TextListener, WindowListener.
����� Components-Objekte sind mit addXListener-Methoden ausgestattet, mittels derer einXListener angemeldet werden kann(z.B. addActionListener(myListener) ummyListener als ActionListener anzumelden).
– OO-Graphics in Java – Eventhandling in Java 162
Methoden der Listener
Listener Methoden mogliche Components
ActionListener actionPerformed ButtonListMenuItemTextField
AdjustmentListener adjustmentValueChanged ScrollbarComponentListener componentHidden Component
componentMovedcomponentResizedcomponentShown
ContainerListener componentAdded ContainercomponentRemoved
FocusListener focusGained ComponentfocusLost
ItemListener itemStateChanged CheckboxCheckboxMenuItemChoiceList
KeyListener keyPressed ComponentkeyReleasedkeyTyped
MouseListener mouseClicked ComponentmouseEnteredmouseExitedmousePressedmouseReleased
MouseMotionListener mouseDragged ComponentmouseMoved
TextListener textValueChanged TextComponentWindowListener windowActivated Window
windowClosedwindowClosingwindowDeactivatedwindowDeiconifiedwindowIconifiedwindowOpened
– OO-Graphics in Java – Eventhandling in Java 163
Beispiel: Ein Draw-Applet(erste Version)
Aufgabe: Ein Applet DrawApplet, welches eine Zei-chenoberflache besitzt, auf die man mit der Mauszeichnen kann. Das Zeichnen soll nur bei gedruckterMaustaste erfolgen.
Erster Ansatz (Applet -Code):
import java.awt.*;import java.awt.event.*;import java.applet.*;
public class DrawApplet extends Applet {
public Canvas canv = new Canvas();
public void init() {
setLayout(new BorderLayout());canv.setSize(400,400);canv.setBackground(Color.blue.darker());canv.setForeground(Color.yellow);add("Center",canv);MyMouseListener listener = new MyMouseListener();canv.addMouseListener(listener);canv.addMouseMotionListener(listener);
}}
– OO-Graphics in Java – Eventhandling in Java 164
Der MouseListener (I)
import java.awt.*;import java.awt.event.*;
public class MyMouseListener implements MouseListener,MouseMotionListener{
public Point p=new Point(0,0);
MyMouseListener() {}
public void mouseClicked(MouseEvent e){}public void mouseEntered(MouseEvent e){}public void mouseExited(MouseEvent e){}public void mouseMoved(MouseEvent e){}public void mouseReleased(MouseEvent e){}
public void mousePressed(MouseEvent e){p= new Point(e.getPoint());
}
public void mouseDragged(MouseEvent e){Canvas canv = (Canvas)e.getSource();Graphics g = canv.getGraphics();g.drawLine(p.x,p.y,e.getX(),e.getY());p= new Point(e.getPoint());
}}
Ein mouseDragged Ereignis bewirkt sofortiges Malenauf derappleteigenen Canvas canv.
– OO-Graphics in Java – Eventhandling in Java 165
Kritik an der ersten Version
Die gemalte Zeichnung ist nirgends abgespeichert.
Ein paint (welches vom Window-Manager jederzeitgeschickt werden kann) bewirkt ein sofortiges Loschender Zeichnung.
Abhilfe:
� Die Zeichnung wird irgendwo gespeichert (entwederals bitmap oder in Form der Koordinaten der gemal-ten Linienstucke).
� Man schreibt eine Unterklasse MyCanvas der vomAWT bereitgestellten Klasse Canvas. Die Unterklas-se MyCanvas besitzt eine eigene paint()-Methode,die fur das Malen der bisherigen Zeichnung sorgt.
– OO-Graphics in Java – Eventhandling in Java 166
Draw-Applet zweite Version
Code fur DrawApplet und fur MyCanvas:
import .....public class DrawApplet extends Applet {
public MyCanvas canv = new MyCanvas(); // <<<< AENDERUNG !!!!
public void init() {setLayout(new BorderLayout());canv.setSize(400,400);canv.setBackground(Color.blue.darker());canv.setForeground(Color.yellow);add("Center",canv);MyMouseListener listener= new MyMouseListener(canv);//<<< AENDERUNGcanv.addMouseListener(listener);canv.addMouseMotionListener(listener);
}}
import java.awt.*;import java.util.*;
public class MyCanvas extends Canvas {
public Vector startpoints = new Vector(); // Lokaler Speicherpublic Vector endpoints = new Vector(); // Lokaler Speicher
public void paint(Graphics g) { // Zeichenmethodefor (int i=0;i<startpoints.size();i=i+1){
Point p1=(Point)startpoints.elementAt(i);Point p2=(Point)endpoints.elementAt(i);g.drawLine(p1.x,p1.y,p2.x,p2.y);
}}
}
– OO-Graphics in Java – Eventhandling in Java 167
Der MouseListener (II)
import .....
public class MyMouseListener implements MouseListener,MouseMotionListener{
private MyCanvas canv; // <<<< AENDERUNG !!!!public Point p=new Point(0,0);
MyMouseListener(MyCanvas a){ // <<<< AENDERUNG !!!!canv=a;
}
public void mouseClicked(MouseEvent e){}public void mouseEntered(MouseEvent e){}public void mouseExited(MouseEvent e){}public void mouseMoved(MouseEvent e){}public void mouseReleased(MouseEvent e){}
public void mousePressed(MouseEvent e){p= new Point(e.getPoint());
}
public void mouseDragged(MouseEvent e){canv.startpoints.addElement(p); // Abspeichern statt Zeichnenp= new Point(e.getPoint());canv.endpoints.addElement(p); // Abspeichern statt Zeichnencanv.repaint(); // Zeichnen erzwingen
}}
Der wesentliche Unterschied gegenuber der ersten Version be-steht darin, dass nicht mehr direkt auf einer Canvas gemaltwird. Vielmehr wird die Zeicheninformation nur noch durchMyMouseListener in MyCanvas abgespeichert und von ihr bei Be-darf gemalt.
– OO-Graphics in Java – Eventhandling in Java 168
Kritik an der zweiten Version
Der Bildschirm flackert !!!
Durch die geanderte Zeichenstrategie ist nun bei je-dem einzelnen mouseDragged Ereignis der (schrittwei-se) Aufbau der kompletten Zeichnung zu sehen.
Die geschieht im allgeneinen zwar sehr schnell, ist beiaufwendigeren Zeichnungen aber als Flackern wahr-nehmbar.
Abhilfe: Einfuhrung von double-buffering.
� Der Bildaufbau erfolgt unsichtbar im Hintergrund aufeinem eigens dafur bereitgestellten Stuck Speicher(bitmap).
� Die notwendigen Anderungen konnen alle lokal inder Klasse MyCanvas vorgenommen werden.
– OO-Graphics in Java – Eventhandling in Java 169
Double buffering
Vordergrund Bildaufbau
kopieren
Das neue Bild wird auf einer bitmap (im Speicher) ge-malt. Erst, wenn das Bild fertig ist, wird es im sichtbarenFenster dargestellt.
– OO-Graphics in Java – Eventhandling in Java 170
MyCanvas mit double-buffering
public class MyCanvas extends Canvas {
public Vector startpoints = new Vector();public Vector endpoints = new Vector();
int oldw, oldh;Image backImage; //HintergrundbildGraphics backG; //Graphics von backImage
public void paint(Graphics g) {
Dimension d = getSize();if (d.width != oldw || d.height != oldh ) { //Neuer Speicher notwendig?
if (backImage != null) backImage.flush();backImage = createImage(d.width,d.height);backG = backImage.getGraphics();oldw = d.width;oldh = d.height;
}backG = backImage.getGraphics();backG.setColor(getBackground()); //Alles im Hintergrund malenbackG.fillRect(0,0,oldw,oldh);backG.setColor(getForeground());for (int i=0;i<startpoints.size();i=i+1){
Point p1=(Point)startpoints.elementAt(i);Point p2=(Point)endpoints.elementAt(i);backG.drawLine(p1.x,p1.y,p2.x,p2.y);
}g.drawImage(backImage,0,0,this); //nach vorne kopieren
}
public void update(Graphics g) { //muss ueberschrieben werden paint(g);}
}
– OO-Graphics in Java – Eventhandling in Java 171
Checkbox — CheckboxGroup
Oft ist es notwendig mehrere Schalter zu erzeugen,mittels derer man zwischen verschiedenen Betriebs-zustanden des Programmes umschalten kann.
Der folgende Code erzeugt Radio-Button Verhalten:
import java.applet.Applet;import java.awt.*;
public class CheckBoxApplet extends Applet {
public void init() {
setBackground(Color.lightGray);
Panel controls = new Panel(new GridLayout(1,3));
CheckboxGroup cg = new CheckboxGroup();
Checkbox a = new Checkbox("First" );a.setCheckboxGroup(cg);Checkbox b = new Checkbox("Second" );b.setCheckboxGroup(cg);Checkbox c = new Checkbox("Third" );c.setCheckboxGroup(cg);a.setState(true);
controls.add(a);controls.add(b);controls.add(c);add(controls);
}}
– OO-Graphics in Java – Eventhandling in Java 172
Eventhandling bei Radio-Buttons
Aufgabe: Drei Knopfe mit Radio-Button Verhalten sol-len jeweils individuellen Text im Fenster anzeigen.
import java.applet.Applet;import java.awt.*;
public class CheckBoxApplet extends Applet {
public void init() {
setBackground(Color.lightGray);
Label label = new Label("?????????????????");label.setFont(new Font("Helvetica",Font.BOLD,36));
Panel controls = new Panel(new GridLayout(1,3));
MyCheckboxGroup cg = new MyCheckboxGroup();
MyCheckbox a = new MyCheckbox("First","Erster",label);a.setCheckboxGroup(cg);MyCheckbox b = new MyCheckbox("Second","Zweiter",label );b.setCheckboxGroup(cg);MyCheckbox c = new MyCheckbox("Third","Dritter",label );c.setCheckboxGroup(cg);a.setState(true);
controls.add(a);controls.add(b);controls.add(c);add(controls);add(label);
}}
– OO-Graphics in Java – Eventhandling in Java 173
Code fur MyCheckbox
import java.awt.*;
public class MyCheckbox extends Checkbox {
String pt;Label l;
private MyCheckbox() {}
public MyCheckbox(String text, String printText, Label label) {setLabel(text);pt=printText;l=label;
}
public void deselect( ) { // Hier darf man eigenes} // Verhalten spezifizieren
public void select( ) { // Hier darf man eigenesl.setText(pt); // Verhalten spezifizieren
}}
Die Checkbox wird mit einem select/deselect-Mechanismus ausgestatted. Die Steuerung dieses Me-chanismus wird von der CheckboxGroup ubernommen.
(Hiermit wird zwar das interne Eventhandling umgan-gen, dies ist jedoch sinnvoll. Auf diese Weise wird eindeselect-Verhalten ermoglicht.)
– OO-Graphics in Java – Eventhandling in Java 174
Code fur MyCheckboxGroup
import java.awt.*;import java.awt.event.*;
class MyCheckboxGroup extends CheckboxGroup {
public synchronized void setSelectedCheckbox(Checkbox checkbox) {Checkbox c2 =getSelectedCheckbox();if (c2 != null && c2 instanceof MyCheckbox) {
((MyCheckbox)c2).deselect();}super.setSelectedCheckbox(checkbox);((MyCheckbox)checkbox).select();
}}
Die setSelectedCheckbox-Methode wird vom AWTbeim Drucken eines Knopfs der Buttongroup aufgeru-fen.
Dies ist eine geeignete Stelle um den select/deselect-Mechanismus einzufugen, indem wir das “normale”Verhalten der Methode setSelectedCheckbox ausder Klasse CheckboxGroup mit unserem speziellenVerhalten uberschreiben.
– OO-Graphics in Java – Eventhandling in Java 175