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