Dezentrale Kontrolle: Aktive Objekte Aktive Objekte Die Klasse AnimatorThread Aktivierung Objekte beobachten Die Java-Klasse Thread Passive Objekte Bieten Dienste auf Abruf an: - eine Zahl von der Konsole lesen - Daten im Bahälter speichern - eine Zufallszahl liefern Oft dient ein Interface als "Bedienungsanleitung": Benutzende Klasse Interface kennt Dienstleisterklasse implementiert Objekte sind passiv, sie tun nur etwas, wenn sie (genauer: ihre Methoden) gerufen werden - dienstleister.liesZahl(); - dienstleister.add("Montag"); (c)schmiedecke 06 Inf1-7a: Animation 2 Aktive Objekte • Bälle in BallWorld verhalten sich anders: • Sie reagieren zwar auf Impulse (Klick), aber sie haben vor allem ein Verhalten ohne Impulse von außen. • Das allgemeine Benutzungsschema ist gleich BallWorld Ball, Animate kennt implementiert Exploder • aber Ball-Objekte verhalten sich anders! (c)schmiedecke 06 Inf1-7a: Animation 3 Wie kommt es zur Objekt-Aktivität? Modell • Prozedurale Programmierung: Call-Center • Objekte scheinen aktiv zu sein, • reagieren aber auf Stimuli des rufenden Prozesses Der BallWorld-Prozess ruft in einer Endlosschleife die act()- Method aller Ball-Objekte Modell Service • • • • OO-Programmierung: Objekte sind unabhängige, interagierende Einheiten Sie handeln selbständig (reagieren zusätzlich auf Stimuli) Jeder Ball hat seinen eigenen Prozess, der in einer Endlosschleife act() ruft. (c)schmiedecke 06 Inf1-7a: Animation 4 Counter und Timer (c)schmiedecke 06 Inf1-7a: Animation 5 Gemeinsames Interface public interface Incrementor { public void increment(); public void reset(); public int getValue(); } public class Counter implements Incrementor { protected int value = 0; public void increment() { value++; } public void reset() { value = 0; } public int getValue() { return value; } } Aufruf z.B. durch Knopfdruck public class Timer extends Counter implements Animate { public void act() { increment(); } } Der einzige (c)schmiedecke 06 Inf1-7a: Animation Unterschied 6 Prozesse und Threads ... wer ruft act()? Ein Prozess ist ein Ausführer, der vom Betriebssystem gestartet und kontrolliert wird. An Ausführer, der innerhalb eines Prozesses gestartet und kontrolliert wird, heißt Thread ("Lebens-Faden"). Threads in Java sind Instanzen der Klasse Thread . Ein Thread-Object kann gestartet werden. Dann ist es "lebendig" und kann andere Objekte animieren (z.B. act() aufrufen). (c)schmiedecke 06 Inf1-7a: Animation 7 AnimatorThread animiert Timer act! AnimatorThread – Objekt (hat eigenen Thread) (c)schmiedecke 06 "animiert" passives Objekt vom Typ Animate (ohne eigenen Thread) Inf1-7a: Animation 8 AnimatorThread animiert Exploder-Ball act! Exploder AnimatorThread – Objekt (hat eigenen Thread) (c)schmiedecke 06 "animiert" passives Objekt vom Typ Animate (ohne eigenen Thread) Inf1-7a: Animation 9 Die Klasse AnimatorThread (cs101) Animator Thread Animate kennt implementiert Animiertes Objekt Jede Instanz von AnimatorThread hat einen eigenen Thread. Im Konstruktor wird sie an ein (passives) Animate-Objekt gekoppelt, das sie dann "animiert": Sobald die Instanz gestartet ist, ruft sie act() in einer Endlosschleife. Animate timer = new Timer(); AnimatorThread timerThread = new AnimatorThread(timer); timerThread.startExecution(); Animate :timerxBall = new Exploder(); Animate :timer AnimatorThread timerThread = newimplementiert AnimatorThread(xBall); Thread kennt timerThread.startExecution(); (c)schmiedecke 06 Inf1-7a: Animation 10 Die Klasse AnimatorThread package cs101.lang; public class AnimatorThread extends Thread { public AnimatorThread(Animate animatedObject); public public public public void void void void startExecution(); stopExecution (); suspendExecution (); resumeExecution (); //Endlosschleife //endgültig //vorübergehend //nach supend public void setSleepMinInterval(long millis); public void setSleepRange(long millis); } (c)schmiedecke 06 Inf1-7a: Animation 11 Start "von außen" public class BallWorld extends World{ // ... // method is called when button is pressed public void startExploder() { // create and launch ball Exploder xBall = new Exploder(); this.addBall(xBall); // animate ball AnimatorThread explThread = new AnimatorThread(xBall); explThread.startExecution(); } //... } (c)schmiedecke 06 Inf1-7a: Animation 12 Start "von innen" class Throbber implements Ball, Animate { World world; // Animation in the constructor public Throbber(World world) { this(); // initialize x, y, radius this.world = world; // create and grasp your own thread AnimatorThread throbThread = new AnimatorThread(this); throbThread.startExecution(); } public void act() { // called by throbThread } //... } (c)schmiedecke 06 Inf1-7a: Animation 13 Activer Timer public class Timer extends Counter implements Animate { private AnimatorThread timerThread; public Timer () { timerThread = new AnimatorThread(this); timerThread.startExecution(); } public void act() { increment(); } } (c)schmiedecke 06 Inf1-7a: Animation 14 Verzögerter Start public class Timer extends Counter implements Animate { private AnimatorThread timerThread; public Timer () { timerThread = new AnimatorThread(this); } public void init() { timerThread.startExecution(); } public void act() { init() wird für increment(); Aktionen verwendet, die } } (c)schmiedecke 06 Inf1-7a: Animation zu Beginn 1x gerufen werden sollen. 15 Ausgaben im GUI machen: public class VisibleTimer extends Timer { private AnimationGUI gui; public VisibleTimer(AnimationGUI gui){ super(); this.gui = gui; } public void increment() { super.increment(); gui.updateTimer(value); // value im GUI anzeigen } public void reset() { super.reset(); gui.updateTimer(0); } } (c)schmiedecke 06 // im GUI 0 anzeigen Inf1-7a: Animation 16 AnimationGUI steht im DownloadBereich. Alles andere können Sie selbst schreiben. Die Klasse AnimationGUI (nur für Neugierige...) zeichnet die Benutzerschnittstelle (das GUI) instanziiert VisibleCounter und VisibleTimer ruft bei Knopfdruck deren Methoden increment() und reset() definiert die Ausgabe-Methoden updateCounter() und updateTimer(), die in VisibleCounter und VisibleTimer bei jedem increment() oder reset()gerufen werden. Die Knöpfe "pause" and "cont." rufen die Timer-Methoden pause() und continue(), die Sie noch implementieren müssen Hinweis: Es ist allgemein üblich, die main-Methode in die GUI-Klasse zu setzen. (c)schmiedecke 06 Inf1-7a: Animation 17 Objekt-Beobachtung (zwei aktive Objekte beteiligt) public class CountingMonitor implements Animate { Objekt im private Counter whoToMonitor; Konstruktor private AnimatorThread mover; kennenlernen public CountingMonitor(Counter whoToMonitor ) { this.whoToMonitor = whoToMonitor; this.mover = new AnimatorThread( this ); this.mover.startExecution(); } public void act() { Console.println( "The timer says " + whoToMonitor.getValue() ); test it! } } Timer timer = new Timer(); // interner Start CountingMonitor monitor = Animation new CountingMonitor(timer); (c)schmiedecke 06 Inf1-7a: 18 Wieviele Threads sind möglich? Beliebig viele. Ein Objekt kann beliebig viele Threads starten. Ergebnis: Ein "Baum" von laufenden Threads Das Programm endet erst, wenn alle Threads beendet sind! (c)schmiedecke 06 Inf1-7a: Animation 19 Java Standard-Threads package java.lang; Interface Runnable { public void run(); } // vgl. Animate public class Thread { // vgl. AnimatorThread public Thread(Runnable runnerObject); public void start(); public boolean isAlive(); public void interrupt(); public void join(); static void sleep(long millis) throws InterruptedException; static void yield(); // ... }(c)schmiedecke 06 Inf1-7a: Animation 20 Java Thread -- AnimatorThread Gleiches Konzept: wenn Sie mit AnimatorThread umgehen können, dann auch mit Thread Das animierte Objekt muss Runnable implementieren (statt Animate) Runnable ticker; // hat eine run()-Methode Thread tickerthread = new Thread(ticker); tickerThread.start(); // ruft run(), aber NUR EINMAL Thread hat keine Endlosschleife! Sie muss ggf. in der run()-Methode implementiert werden. (c)schmiedecke 06 Inf1-7a: Animation 21 Was passiert beim Programmstart? Das Betriebssystem startet die VM als neuen Prozess Die VM startet einen neuen Thread, in dem es die main-Methode aufruft (c)schmiedecke 06 Inf1-7a: Animation 22 Mit aktiven Objekten kann man viel mehr Spaß haben als mit passiven!