Eyes - Institut für Informatik
Transcription
Eyes - Institut für Informatik
Schwerpunkte • Ereignisbehandlung (Event Handling) • Vom Problem zum Programm • SW-Architektur: Programme mit graphischer Nutzeroberfläche 15. Ereignisse (Events) • Ein Beispiel zu Events, Applets und Graphics • Ereignisse: erzeugen und behandeln … ist so ähnlich wie Ausnahmen erzeugen und behandeln Java-Beispiel: EyesApplet.java Eyes.java • API-Klassen: - MouseMotionListener - MouseEvent - Applet - Graphics K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 20015/16 Version: 1. Feb. 2016 Java-Programmbeispiel: Quellen K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 2 Aufgabe Man entwickle ein Applet, in dem Augenpaare dem Cursor (der von der Maus bewegt wird) folgen. Basierend auf einer Idee von S.N. Kamin, M.D. Mickunas, E.M. Reingold: „An introduction to computer science – Using Java“, McGraw-Hill, 1st und 2nd Edition, 1998, 2002 Cursor bewegt (Ereignis) Æ Position des Cursors abfragen Æ Pupillen neu zeichnen K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 3 K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 4 Ereignisgesteuerte Programmausführung Ereignis Besonderes Vorkommnis außerhalb des Programms … (Hardware) • Tastatur betätigt (z. B. Enter-Taste) • Maus bewegt / Taste betätigt • graphisches Nutzerinterface bedient (z.B. Button gedrückt) „Normale“ Programmsteuerung: mit main() oder init() gestartet und beendet ein Algorithmus A Eingabe Ausgabe (z.B. Quicksort, Maus im Labyrinth) Ereignisgesteuerte Programmsteuerung: Programmausführung: viele „kleine“ Algorithmen werden aktiviert … löst bestimmte Reaktion des Programms aus. Initialisieren (z. B. Oberfläche aufbauen) • Ausgabe des Grad-Celsius-Wertes (TempApplet.java) • Veränderte Augenpaare (Eyes.java, EyesApplet.java) Button drücken Maus bewegen Enter-Taste betätigen … A3 A4 • Graphisches Objekt erscheint o. ä. A0 K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 5 Ereignisgesteuertes Programm: Ereignisschleife A1 main() oder init() K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 A2 Ai – „kleine“ Algorithmen6 Zur Anforderungsdefinition Man entwickle ein Applet, in dem Augenpaare dem Cursor (der von der Maus bewegt wird) folgen. Button gedrückt? JVM steuert die Ereignisschleife: beobachtet, ob Ereignis auftritt Maus bewegt? Enter-Taste betätigt? behandeln Zu klärende Probleme: A1 Anzahl Augenpaare *) Platzierung der Augen *) Abmessungen für Pupille und Augapfel *) In welchen zeitlichen Abständen soll die Blickrichtung verändert werden? behandeln A2 behandeln A3 (laufend/kontinuierlich: in kleinster möglicher Zeiteinheit) behandeln … K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 A4 *) Feste Werte nach Programmstart, aber durch Konstanten im Programm leicht modifizierbar 7 K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 8 Software-Architektur: Grundprinzip Software–Architektur: UML Augenpaar zeichnen Programme mit graphischer Oberfläche Komponenten für Nutzeroberfläche (Applet–Klasse) Komponenten für den inhaltlichen Teil (Augenpaar zeichnen) EyesApplet Eyes - left, right : Point - leftPupil, rightPupil : Point - EYE_RADIUS, PUPIL_RADIUS: int Eyes (p: Point) stare (cursor: Point) gerichtet! Eyes strikte Trennung Nutzeroberfläche Architekturfehler: Vermischung beider Komponenten K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 Prinzip: Nutzeroberfläche kennt Anwendung - nicht umgekehrt 9 EyesApplet init ( ) paint (Graphics g) mouseMoved (MouseEvent e) mouseDragged (MouseEvent e) K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 Klasse 'E y e s' 10 Klasse ‚EyesApplet' • Grundlagen: Zum Zeichnen eines Augenpaares Rechtes / linkes Auge: jeweils Mittelpunkt von Augapfel und Pupille sowie Radius Eyes Zustand Verhalten - Ereignisbehandlung (Klasse MouseMotionListener) - Applets (Klasse Applet) - left, right : Point - leftPupil, rightPupil : Point - EYE_RADIUS, PUPIL_RADIUS: int Erzeuge Augenpaar mit Position p (Anfangszustand) Eyes (p: Point) stare (cursor: Point) Welche Zustandsänderung durch stare? - nicht durch das Programm! Initialisierung (beim Programmstart) Aufruf bei Mausbewegung Zeichne Augenpaar in Richtung 'cursor' (stare = (an)starren) Aufruf bei Mausbewegung mit gedrückter Maus-Taste (drag) Volle V ll F Form: stare(g: Graphics, cursor:Point) K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 • Aufruf aller Methoden durch Interpreter 11 Direkt nach init() aufgerufen: beide Augenpaare malen lassen. EyesApplet } init ( ) Anfangszustand paint (Graphics g) mouseMoved (MouseEvent e) mouseDragged (MouseEvent e)*) *) nicht benötigt (technisches Detail) K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 12 Ereignisgesteuertes Programm: Ereignisschleife public class Eyes { private Point left, right, leftPupil, rightPupil; private final int EYE_RADIUS = 30,PUPIL_RADIUS = 10; import java.awt.*; import java.applet.*; import java.awt.event.*; Button gedrückt? JVM steuert die Ereignisschleife Maus bewegt? Enter-Taste betätigt? public Eyes(Point c) { left = new Point(c.x-EYE_RADIUS-3, c.y); right = new Point(c.x+EYE_RADIUS+3, c.y); } public class EyesApplet extends Applet implements MouseMotionListener { Point cursor; Eyes e1, e2; behandeln private void fillCircle (Graphics g, Point center, int radius) { g.fillOval(center.x-radius, center.y-radius, 2*radius, 2*radius); } public void init () { // Register the Listener. addMouseMotionListener(this); setSize(500,400); setBackground(Color.LIGHT_GRAY); e1 = new Eyes(new Point (63,30)); // center of one eye e2 = new Eyes(new Point (437,30)); // center of the other cursor = new Point(250, 2000); // initial cursor } behandeln mouseMoved (MouseEvent e) behandeln public void stare (Graphics g, Point cursor) { // Draw the white eyes g.setColor(Color.WHITE); fillCircle(g, left, EYE_RADIUS); fillCircle(g, right, EYE_RADIUS); // Draw the pupils g.setColor(Color.black); leftPupil = compute (cursor, left); fillCircle(g, leftPupil, PUPIL_RADIUS); rightPupil = compute (cursor, right); fillCircle(g, rightPupil, PUPIL_RADIUS); public void paint(Graphics g) { e1.stare(g, cursor); e2.stare(g, cursor); } behandeln … } private Point compute (Point cursor, Point eye) { double d = Math.sqrt((cursor.x-eye.x)*(cursor.x-eye.x) + (cursor.y-eye.y)*(cursor.y-eye.y)); int r = EYE_RADIUS - PUPIL_RADIUS; return new Point (eye.x + (int)((cursor.x-eye.x)*r/d), eye.y + (int)((cursor.y-eye.y)*r/d)); } public void mouseMoved (MouseEvent e) { cursor = e.getPoint(); repaint(); } public void mouseDragged (MouseEvent e) {} } K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 13 Ereignisbehandlung (Event Handling) } K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 Vererbungshierarchie der Ereignisklassen (Auszug aus dem Java-API) Besondere externe Vorkommnisse außerhalb des Programms: Signale der Umgebung an Programm EventObject • Tastatur betätigt (z. B. Enter-Taste) • Maus bewegt / Taste betätigt • graphisches Nutzerinterface bedient (z.B. Button gedrückt) AWTEvent ActionEvent ComponentEvent … führen zur Bildung eines Ereignis-Objekts. InputEvent • Objekt einer Event-Klasse (vgl. Ausnahme-Objekte erzeugt bei Laufzeitfehlern) KeyEvent MouseEvent K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 Quelle: Maus vgl. Ausnahmebehandlung (exceptions) 15 ... ... Art: MouseEvent getPoint ( ) : Point . . . 14 K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 Quelle: z.B. Enter–Taste (Temperatur–Applet) 16 Analogie: Ausnahmen - Ereignisse (Events) API-Klasse ‚MouseEvent' Zur Laufzeit: besondere Situation An event which indicates that a mouse action occurred in a component… Signal der Umgebung (periphere Geräte: Æ Tastatur / Maus) Laufzeitfehler erzeugt static int MOUSE_CLICKED Ausnahmeobjekt The "mouse clicked" event. Event-Objekt getMessage() ... static int MOUSE_MOVED The "mouse moved" event. getPoint() ... Art: NumberFormat Details: a1 StackTrace: … Point getPoint() Art: MouseEvent b e h a n d e l t durch Returns the x,y position (curser) of the event relative to the source component. Objekt einer Unterklasse der Interface-Klasse 'EventListener' try-catch (Teil des Java - API) K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 17 K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 18 API-Klasse (Interface) ‚MouseMotionListener' (Interface terface e-)Komponenten e -)K )Komponenten zur Behandlung Be eh handlung von v Ereignissen: EventListener erer r-Hierarchie The listener interface for receiving mouse motion events on a component. (For clicks and other mouse events, use MouseListener.) EventListener ActionListener KeyListener WindowListener MouseMotionListener …Listener: beobachten Ereignisse und reagieren void mouseDragged(MouseEvent e) Invoked when a mouse button is pressed on a component and then dragged. Ereignis übergeben ... void mouseMoved(MouseEvent e) behandelt: MouseMotionEvents … durch festgelegte Methodenaufrufe. K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 Invoked when the mouse cursor has been moved onto a component but no buttons have been pushed. behandelt: ActionEvents (vgl. Temperatur–Applet) 19 K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 20 Auswertung von MouseEvents durch MouseMotionListener Technik und Ablauf der Ereignisbehandlung class EyesApplet extends Applet implements MouseMotionListener { 1. 5. public void mouseMoved (MouseEvent e) { cursor = e.getPoint(); repaint(); } ... 1. 2. 3. 4. } Aufrufreihenfolge bei Maus-Bewegung Æ Objekt e vom Typ MouseEvent gebildet; e enthält Informationen über Position des Cursors. Æ Aufruf mouseMoved(e) Æ neue Position der Maus abgefragt: e.getPoint Æ repaint(): ruft paint() erneut auf – Augen jetzt neu gemalt K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 Hardware schickt Signal an Betriebssystem Java-VM-Maschine empfängt Signal vom Betriebssytem Java-VM-Maschine erzeugt Ereignis-Objekt e Java-VM-Maschine sendet Botschaft an Objekt der Ereignisbehandlung (d.h. durch Aufruf einer Methode): z.B. mouseMoved(e) 5. Ereignisbehandlungsmethode wertet Ereignis-Objekt aus und reagiert, z.B. e.getPoint(); repaint(); 21 K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 22 SW-Architektur: erweiterte Sicht (API) public class Eyes { Component paint(…) repaint() addMouseMotionListener(…) setSize(…) setBackground(…) + > 100 weitere <<interface>> MouseMotionListener mouseMoved(…) mouseDragged(…) addMouseMotionListener(this): Das Applet wird als Objekt registriert, das bei Mausbewegungen informiert werden soll, d. h. dann reagieren kann. private Point left, right, leftPupil, rightPupil; private final int EYE_RADIUS = 30,PUPIL_RADIUS = 10; Container import java.awt.*; import java.applet.*; import java.awt.event.*; paint(Graphics g) + 50 weitere public class EyesApplet extends Applet implements MouseMotionListener { Point cursor; Eyes e1, e2; Panel Mehrfachvererbung: ein Applet, das auf Events reagieren kann private void fillCircle (Graphics g, Point center, int radius) { g.fillOval(center.x-radius, center.y-radius, 2*radius, 2*radius); } public void init () { // Register the Listener. addMouseMotionListener(this); setSize(500,400); setBackground(Color.LIGHT_GRAY); e1 = new Eyes(new Point (63,30)); // center of one eye e2 = new Eyes(new Point (437,30)); // center of the other cursor = new Point(250, 2000); // initial cursor } addNotify() Applet init() + 21 weitere public void stare (Graphics g, Point cursor) { // Draw the white eyes g.setColor(Color.WHITE); fillCircle(g, left, EYE_RADIUS); fillCircle(g, right, EYE_RADIUS); // Draw the pupils g.setColor(Color.black); leftPupil = compute (cursor, left); fillCircle(g, leftPupil, PUPIL_RADIUS); rightPupil = compute (cursor, right); fillCircle(g, rightPupil, PUPIL_RADIUS); public void paint(Graphics g) { e1.stare(g, cursor); e2.stare(g, cursor); } EyesApplet init() paint() mouseMoved(…) mouseDragged(…) public Eyes(Point c) { left = new Point(c.x-EYE_RADIUS-3, c.y); right = new Point(c.x+EYE_RADIUS+3, c.y); } In EyesApplet definierte und benutzte Methoden aufgeführt } private Point compute (Point cursor, Point eye) { double d = Math.sqrt((cursor.x-eye.x)*(cursor.x-eye.x) + (cursor.y-eye.y)*(cursor.y-eye.y)); int r = EYE_RADIUS - PUPIL_RADIUS; return new Point (eye.x + (int)((cursor.x-eye.x)*r/d), eye.y + (int)((cursor.y-eye.y)*r/d)); } public void mouseMoved (MouseEvent e) { cursor = e.getPoint(); repaint(); } public void mouseDragged (MouseEvent e) {} } K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 23 } K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 24 Klasse 'Eyes': das Problem ? Klasse 'Eyes': das Problem ? (für das Zeichnen des Auges) (für das Zeichnen des Auges) Augapfel mit fester Lage Augapfel mit fester Lage das Problem: geg.: Augapfel + Cursorposition ges.: Wo liegt die Pupille ? Mittelpunkt ÆSatz des Pythagoras ÆÄhnliche Dreiecke Cursor Cursor K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 25 K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 Klasse 'Eyes': das Problem ? public class Eyes { private Point left, right, leftPupil, rightPupil; private final int EYE_RADIUS = 30,PUPIL_RADIUS = 10; E: Mittelpunkt des Auges (Eye) E import java.awt.*; import java.applet.*; import java.awt.event.*; C: Cursor-Punkt r (zu berechnen) d d = (C.x - E.x)2 + (C.y - E.y)2 public void stare (Graphics g, Point cursor) { // Draw the white eyes g.setColor(Color.WHITE); fillCircle(g, left, EYE_RADIUS); fillCircle(g, right, EYE_RADIUS); // Draw the pupils g.setColor(Color.black); leftPupil = compute (cursor, left); fillCircle(g, leftPupil, PUPIL_RADIUS); rightPupil = compute (cursor, right); fillCircle(g, rightPupil, PUPIL_RADIUS); public void paint(Graphics g) { e1.stare(g, cursor); e2.stare(g, cursor); } P.x = E.x + (C.x - E.x) * r / d } private Point compute (Point cursor, Point eye) { double d = Math.sqrt((cursor.x-eye.x)*(cursor.x-eye.x) + (cursor.y-eye.y)*(cursor.y-eye.y)); int r = EYE_RADIUS - PUPIL_RADIUS; return new Point (eye.x + (int)((cursor.x-eye.x)*r/d), eye.y + (int)((cursor.y-eye.y)*r/d)); } public void mouseMoved (MouseEvent e) { cursor = e.getPoint(); repaint(); } P.y = E.y + (C.y - E.y) * r / d K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 private void fillCircle (Graphics g, Point center, int radius) { g.fillOval(center.x-radius, center.y-radius, 2*radius, 2*radius); } public void init () { // Register the Listener. addMouseMotionListener(this); setSize(500,400); setBackground(Color.LIGHT_GRAY); e1 = new Eyes(new Point (63,30)); // center of one eye e2 = new Eyes(new Point (437,30)); // center of the other cursor = new Point(250, 2000); // initial cursor } P: Mittelpunkt der Pupille r = Differenz der Radien public Eyes(Point c) { left = new Point(c.x-EYE_RADIUS-3, c.y); right = new Point(c.x+EYE_RADIUS+3, c.y); } public class EyesApplet extends Applet implements MouseMotionListener { Point cursor; Eyes e1, e2; P 26 C public void mouseDragged (MouseEvent e) {} } 27 } K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 28 fillCircle : Kreis mit 'radius' um 'center'-Punkt stare und compute private void fillCircle (Graphics g, Point center, int radius) { malt Kreis in Quadrat (Oval in Rechteck) Malt Augenpaar neu: • Alte Position der Pupille: schwarz Æ weiß • Pupille blickt in Richtung ‚cursor‘ (schwarz) g.fillOval(center.x-radius, center.y-radius, 2*radius, 2* radius); public void stare (Graphics g, Point cursor) } Länge und Breite des Rechtecks linker oberer Eckpunkt Umsetzung der geometrischen Grundlagen: Berechnet Punkt P (Mittelpunkt der Pupille) radius center y private Point compute (Point cursor, Point eye) x K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 29 API-Klasse ‚Graphics' K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 30 Dynamische Sicht auf 'EyesApplet' The Graphics class is the abstract base class for all graphics contexts that allow an application to draw onto components … Eyes MouseMotionListener EyesApplet init () paint (g) mouseMoved (e) void drawRect(...) Draws the outline of the specified rectangle. bei Start bei Ereignis g: Graphics Graphics-Objekt: generiert für jedes Applet e: MouseEvent Java-Interpreter JVM abstract void fillOval(int x, int y, int width, int heigth) Fills an oval bounded by the specific rectangle with the current color K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 Applet Betriebssystem 31 K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 generiert bei Ereignis 32 Klasse EyesApplet: Aufruf der Methoden public class EyesApplet extends Applet implements MouseMotionListener { Point cursor; Eyes e1, e2; 0. Programm anwenden und vollständig verstehen (Java-API) Applet: initialisiert und registriert als MouseMotionListener 1. Platzierung der Augen verändern public void init () {...} direkt nach init() aufgerufen public void paint(Graphics g) { e1.stare(g, cursor); e2.stare(g, cursor); automatischer Aufruf bei Maus-Bewegung } public void mouseMoved (MouseEvent e) { cursor = e.getPoint(); repaint(); liefert physische Mausposition } public void mouseDragged (MouseEvent e) Mögliche Aufgaben zur Vertiefung 2. Andere Abmessungen: Größe von Pupille und Augapfel 3. Statt zwei Augenpaaren: vier … 4. Dynamische Erzeugung von neuen Augenpaaren (Maustasten) 5. Erscheinungsbild neu: Augenlid benötigt: MouseMotionListener MouseListener 6. Auf Maustastendruck: Augenlider schließen sich {...} • Zu jedem Applet generiert JVM ein Graphics-Objekt g zum Malen im Applet • Alle Methoden: durch JVM-Maschine aufgerufen K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 33 K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 35 K. Bothe, Institut für Informatik, HU Berlin, GdP, WS 2015/16 34