Funktionalität des
Balonfeldes |
Das
BallonFeld
ist das Pendant zur
Ampel.
Ihre Funktionalität ist jedoch um einiges komplexer. Da wir aber
mittlerweile gewohnt sind UML-Notationen zu lesen, sollte der prinzipielle
Aufbau des BallonFeldes
kein Problem sein. Auch die meisten Attribute und Methoden lassen sich,
wegen ihrer sprechenden Bezeichner leicht verstehen.
Die Attribute im Einzelnen:
qudrat,
kQuadrat
und ballon
sind Instanzen der Klassen
Quadrat,
kQuadrat
und Ballon.
figur ist vom Typ Figur und wird zur späten Bindung benutzt, d.h. erst zur
Laufzeit entscheidet es sich, ob
figur eine Instanz von z.B.
Quadrat
oder KQuadrat
etc. ist. Das Runnable-'Objekt'
wird wie gehabt beim Erzeugen des Objektes
dieserThread
diesem über den Konstruktor übergeben.
dieserThread
wird benutzt um das Warten zwischen Verschwinden des Quadrats und dem
Auftauchen des wachsenden Ballons zu organisieren.
Die Methoden werden im Quelltext
erläutert.
|
Download:
BallonFeld.java |
package tauglichkeitstester.test;
import tauglichkeitstester.figur.*;
import java.awt.*;
import javax.swing.*;
public class BallonFeld {
protected Quadrat quadrat;
protected Ballon ballon;
protected KQuadrat kQuadrat;
private Figur figur;
private int xMitte, yMitte;
private Runnable warteRun;
private Thread dieserThread;
public BallonFeld(int xMitte, int yMitte, int breite) {
this.xMitte = xMitte;
this.yMitte = yMitte;
int d = breite/10; // Rahmenbreite
int bMin = breite/4;
int seiteQuadrat = bMin + (int)(Math.random()*(breite - bMin - 2*d));
// Quadrat und Ballon zufällig aus der Mitte rücken
int dx = (int)((1 - 2*Math.random())*(xMitte - seiteQuadrat/2 - d));
int dy = (int)((1 - 2*Math.random())*(yMitte - seiteQuadrat/2 - d));
quadrat = new Quadrat(xMitte-dx, yMitte-dy, seiteQuadrat, Color.green);
ballon = new Ballon(xMitte+dx, yMitte+dy, Color.red);
kQuadrat = new KQuadrat(xMitte, yMitte, seiteQuadrat,
quadrat.getFarbe(), ballon);
//figur ist nicht referenziiert, was durch das Setzen auf
//null verdeutlicht wird.
figur = null;
warteRun = new Runnable() {
public void run() {
warte(2000);
}
};
}
//Beim Aufruf dieser Methode wird der Thread gestartet und
//damit die Methode run() in warteRun ausgeführt, die ihrerseits
//die Methode warten mit dem Parameter 2000 aufruft.
//figur ist mit einem Quadrat-Objekt instanziiert, so dass, wenn
//für figur die Methode zeigeDich(Graphics g) augerufen wird, ein
//ein Quadrat gezeichnet wird.
public void starten() {
figur = quadrat;
dieserThread = new Thread(warteRun);
dieserThread.start();
}
//Nach 2 Sekunden beginn der Ballon zu wachsen
//Wenn der Ballon gestartet ist, wird figur mit diesem
//Ballon instanziiert. Wird jetzt zeigeDich(Graphics g) für figur
//aufgerufen, so wird der wachsende Ballon gezeichnet.
private void warte(int millisekunden) {
Thread thread = Thread.currentThread();
while (dieserThread == thread) {
try {
Thread.sleep(2000);
}
catch(InterruptedException e) {
return;
}
if (dieserThread != null) {
dieserThread = null;
ballon.start();
figur = ballon;
}
}
}
//diese Methode wird aufgerufen, wenn das Wachsen des Ballons
//gestoppt werden soll: der Thread wird angehalten und beendet
//und figur wird schliesslich mit kQuadrat instanziiert, so dass jetzt
//wird für figur zeigeDich(Graphics g) aufgerufen ein KQuadrat-Objekt
//gezeichnet.
public void stoppen() {
if (dieserThread != null) {
dieserThread.interrupt();
dieserThread = null;
}
ballon.stop();
ballon.setMittelpunkt(xMitte, yMitte);
figur = kQuadrat;
}
//liefert die prozentuale Abweichung
public int ergebnis() {
return (int) Math.round((quadrat.getSeite() - 2.0
*ballon.getRadius())*100.0/quadrat.getSeite());
}
//Die Methode zeigeDich für das BallonFeld, je nachdem,
//durch welches Objekt figur instanziiert wurde, wird ein Quadrat-, ein
//Ballon- oder ein KQuadrat-Objekt gezeichnet.
public void zeigeDich(Graphics g) {
if (figur != null) {
figur.zeigeDich(g);
}
}
}
|