gui

Werbung
Learning By Doing
Ereignissteuerung (Events)
ereignisgesteuert
m
m
-
-
prozedural
r a m
u
l a
g
r o
-P
m
f
r a m
u
l a
g
r o
a b
P
g
l a
r o
a b
m
-
P
f
u
l a
g
r o
a b
r a m
C a llb a c k m e th o d e
P
f
u
l a
g
r o
a b
r a m
m
U n te rp ro g ra m m
(M eth o d e )
P
a b
f
r a m
u
l a
g
r o
-P
a b
f
m
Event
kann irgendwo auftreten
u
an fest codierter Stelle
r a m
Unterprogrammaufruf
f
H a u p tp ro g ra m m
H a u p tp ro g ra m m
Wann immer der Event auftritt, führe möglichst bald aus ...
Learning By Doing
TimerEvent (UML-Diagramm)
im Delegations-Eventmodell
<interface>
TimerListener
Garantieerklärung:
timeElapsed() existiert!
timeElapsed()
LoResAlarmTimer
has-a
TimerListener timerListener
addTimerListener()
...
Event!
Aufruf von timerListener.timeElapsed()
implements
DigitalWatch
LoResAlarmTimer timer
int time
Implementierung der
Callbackmethode
DigitalWatch()
timeElapsed()
main()
has-a
Registrierung der
Callbackmethode
Registrierung:
Übergeben einer Referenz der Klasse, welche die Callbackmethode enthält,
an den Eventhandler, der die Callbackmethode bei jedem Event aufruft.
Zur Registrierung
der
Callbackmethode
Learning By Doing
// DigitalWatch.java
import ch.aplu.util.*;
import java.awt.Font;
public class DigitalWatch
implements TimerListener
{
private int seconds = 0;
private boolean isBell = true;
private LoResAlarmTimer timer =
new LoResAlarmTimer(1000000L);
private GPanel panel = new GPanel();
public DigitalWatch()
{
panel.font(new Font(
"Arial", Font.PLAIN, 200));
timer.addTimerListener(this);
while (true)
{
if (isBell)
{
{
isBell
isBell =
= false;
false;
panel.clear();
panel.text(0.3, 0.4,
0.4,
panel.text(0.3,
Integer.toString(seconds));
seconds++;
seconds++;
}
}
}
}
Implementierung
"DigitalWatch implementiert einen TimerListener"
Registrierung
"Dieser TimerListener wird beim Eventhandler registriert"
Eventloop
Callbackmethode
public boolean timeElapsed()
{
isBell = true;
return true;
}
public static void main(String[] args)
{
new DigitalWatch();
}
}
Learning By Doing
// WbzEx11.java
import java.awt.event.*;
import java.awt.Color;
import ch.aplu.util.*;
Mausevents
Interface
MouseListener
mouseClicked()
mouseEntered()
mouseExited()
mousePressed()
mouseReleased()
Innere Klasse
hat Zugriff
Callbackmethode
implements
MouseAdapater
void mouseClicked(MouseEvent e) {}
void mouseEntered(MouseEvent e) {}
void mouseExited(MouseEvent e) {}
void mousePressed(MouseEvent e) {}
void mouseReleased(MouseEvent e) {}
public class WbzEx11
{
class MyMouseAdapter extends MouseAdapter
{
public void mousePressed(MouseEvent evt)
{
Color c = new Color((float)Math.random(),
(float)Math.random(),
(float)Math.random());
Stern stern = new Stern(p, 50, c);
stern.moveAt((int)p.toWindowX(evt.getX()),
(int)p.toWindowY(evt.getY()));
stern.showMe();
}
}
private GPanel p = new GPanel(0, 500, 0, 500);
is-a
MyMouseAdapater
void mousePressed(MouseEvent e)
{
...
}
public WbzEx11()
{
p.addMouseListener(new MyMouseAdapter());
}
Registrierung
public static void main(String[] args)
{
new WbzEx11();
}
}
Learning By Doing
// WbzEx11a.java
Anonyme Klassen
import java.awt.event.*;
import java.awt.Color;
import ch.aplu.util.*;
public class WbzEx11a
{
private GPanel p = new GPanel(0, 500, 0, 500);
public WbzEx11a()
{
p.addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent evt)
{
Color c = new Color((float)Math.random(),
(float)Math.random(),
(float)Math.random());
Stern stern = new Stern(p, 50, c);
stern.moveAt((int)p.toWindowX(evt.getX()),
(int)p.toWindowY(evt.getY()));
stern.showMe();
}
});
}
Registrierung
Anonyme Klasse
abgeleitet von MouseAdapter
public static void main(String[] args)
{
new WbzEx11a();
}
}
Learning By Doing
// WbzEx12.java
Buttonevents
Innere Klasse, implementiert
ActionListener
import java.awt.event.*;
import javax.swing.*;
import ch.aplu.turtle.*;
public class WbzEx12
{
private class ButtonActionAdapter
implements ActionListener
{
public void actionPerformed(ActionEvent evt)
{
Object source = evt.getSource();
if (source == runButton)
state = States.RUNNING;
if (source == stopButton)
State switch
state = States.STOPPED;
if (source == quitButton)
state = States.QUITTING;
}
}
Zustände (Aufzählungstyp)
aktueller Zustand
private enum States {STOPPED, RUNNING, QUITTING};
private States state = States.STOPPED;
Instanzvariablen
private JButton runButton = new JButton("Run");
private JButton stopButton = new JButton("Stop");
private JButton quitButton = new JButton("Quit");
public WbzEx12()
Learning
{
Turtle t = new Turtle();
JPanel jp = t.getPlayground();
Buttonevents
By Doing
jp.add(runButton);
jp.add(stopButton);
jp.add(quitButton);
jp.validate();
Buttons in der
Komponente
anzeigen
ButtonActionAdapter adapter = new ButtonActionAdapter();
runButton.addActionListener(adapter);
stopButton.addActionListener(adapter);
quitButton.addActionListener(adapter);
Registrierung
while (state != States.QUITTING)
{
switch(state)
{
case STOPPED:
Prozessor freiwillig anderen abgeben
Thread.yield();
break;
Event loop
case RUNNING:
t.forward(10).left(10);
break;
}
}
System.exit(0);
}
public static void main(String[] args)
{
new WbzEx12();
}
}
// WbzEx12a.java
Buttonevents
(J2SE 1.4)
Simulation des Enum-Typs
Verwendung durch Vorstellen
des Interface-Bezeichners
Schon viel besser als
state = 2
state-Variable als
"dekorierter" int
Learning By Doing
import java.awt.event.*;
import javax.swing.*;
import ch.aplu.turtle.*;
public class WbzEx12a
{
interface State
{
int QUITTING = 0;
int STOPPED = 1;
int RUNNING = 2;
}
private class ButtonActionAdapter
implements ActionListener
{
public void actionPerformed(ActionEvent evt)
{
Object source = evt.getSource();
if (source == runButton)
state = State.RUNNING;
if (source == stopButton)
state = State.STOPPED;
if (source == quitButton)
state = State.QUITTING;
}
}
private int state = State.STOPPED;
private JButton runButton = new JButton("Run");
private JButton stopButton = new JButton("Stop");
private JButton quitButton = new JButton("Quit");
public WbzEx12a()
{
Learning
Turtle t = new Turtle();
JPanel jp = t.getPlayground();
Buttonevents
jp.add(runButton);
jp.add(stopButton);
jp.add(quitButton);
jp.validate();
(J2SE 1.4)
ButtonActionAdapter adapter =
new ButtonActionAdapter();
runButton.addActionListener(adapter);
stopButton.addActionListener(adapter);
quitButton.addActionListener(adapter);
Verwendung durch Vorstellen
des Interface-Bezeichners
while (state != State.QUITTING)
{
switch(state)
{
case State.STOPPED:
Thread.yield();
break;
case State.RUNNING:
t.forward(10).left(10);
break;
}
}
System.exit(0);
}
public static void main(String[] args)
{
new WbzEx12a();
}
}
By Doing
GUI-Muster
// WbzEx13.java
import java.awt.*;
import javax.swing.*;
import ch.aplu.util.*;
Learning By Doing
public class WbzEx13 extends JPanel
{
private int count = 0;
JPanel als Grafik-Fenster
public WbzEx13()
{
JFrame f = new JFrame("Frame Window");
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(this);
f.setBounds(50, 50, 550, 550);
f.setVisible(true);
}
JFrame als umfassendes Fenster
Aktion beim Klicken des Close-Buttons
Füge das JPanel in das JFrame
Position und Grösse des JFrames
Zeige das JFrame mit Inhalt
paintComponent() wird bei jedem
System-Trigger aufgerufen
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawOval(0, 0, 500, 500);
g.drawString("WBZ-Kurs \"Java im Unterricht\"", 180, 250);
Graphics2D g2D = (Graphics2D)g;
g2D.setStroke(new BasicStroke(8));
Line2D.Double line = new Line2D.Double(20, 300, 480, 300);
g2D.draw(line);
System.out.println(count++);
Aufruf überschr. Methode aus JPanel
Zeichnen mit dem Graphics-Context
Text als Grafik
Hole Graphics2D-Context
Neue Linieneigenschaft (Dicke)
Linie als Objekt
Zeichne Grafikobjket
Indikator für Aufruf von paintComponent
}
public static void main(String[] args)
{
Console.init();
new WbzEx13();
}
}
Herunterladen