27.9 Die Klasse BallonFeld
 
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);
    }
  }
}
Download:
JBallonFeldDemo. java
Mit der Klasse JBallonFeldDemo.java lässt sich die Klasse BallonFeld testen.
   
zu 27.10 Übungen
zur Startseite www.pohlig.de  (C) MPohlig 2004