Universität Potsdam Institut für Informatik Sommersemester 2014 Programmierung Lehrblatt Woche 11 1 Applets In den letzten Wochen haben Sie die graphische Programmierung kennengelernt. Um Java-Programme direkt im Internet-Browser ausführen zu können, muss man diese als Applets programmieren. Dementsprechend müssen sie Unterklasse von Applet aus dem Paket java.applet sein. 1.1 Applets und HTML-Dokumente Applets werden mittels eines <APPLET>-Tags in HTML-Seiten eingebunden. Man kann sie über die HTML-Seite mit einem Browser oder alternativ mit dem Applet-Viewer betrachten. Diesen ruft man mit dem Kommando appletviewer datei.html für eine Datei datei.html auf. Wie man ein Applet mit dem Namen HalloInternet in ein HTML-Dokument einbindet zeigt das folgende Beispiel: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <HTML> <HEAD> <TITLE> Ein Applet - Tester </TITLE> </HEAD> <BODY> <P> Hier ist das Applet : </P> <APPLET code = " HalloInternet . class " width = " 200 " height = " 200 " > </APPLET> <P> Ende des Applets ... </P> </BODY> </HTML> 1 1.2 Wichtige Methoden der Applet-Klasse Wie bei Frames wird die Programmlogik von Applets nicht von der main-Methode abgearbeitet. Das Abarbeiten des Haupt-Codes übernehmen andere Methoden: init() Die Methode init wird automatisch nach dem Laden des Applets ausgeführt. start() Die Methode start() wird direkt nach init und bei jedem Reload oder jeder Deiconifizierung des Viewers aufgerufen. stop() Die Methode stop() wird beim Verlassen der Internetseite (oder bei einem Reload vor start()) oder bei der Iconifizierung des Viewers ausgeführt. destroy() Die Methode destroy() wird beim Entfernen des Applets aus dem Viewer ausgeführt. paint(Graphics g) Die Methode paint(Graphics g) zeichnet im Graphik-Kontext g das AppletFenster neu. 1 2 3 p u b l i c void paint ( Graphics g ) { g . drawString ( " Hallo Internet " , 50 , 50); } Achtung: Graphics ist eine Klasse im Paket java.awt. 1. Arbeiten Sie mit der Java-API1 ! Nennen Sie alle Oberklassen (in der richtigen Reihenfolge) von Applet, beginnend mit Component! 2. Programmieren Sie ein Applet HalloInternet.java, das den String „Hallo Internet“ ausgibt, und binden Sie es in ein Dokument AppletTester.html ein. (Das Dokument befindet sich im Ordner /home/rlehre/W11.) Variieren Sie die Position des ausgegebenen Strings. a) Welche Pakete müssen importiert werden? b) Von welcher Klasse muss HalloInternet abstammen? 1 http://docs.oracle.com/javase/7/docs/api/java/applet/Applet.html 2 1.3 Einlesen von Parametern Die Interaktion von Applets erfolgt mit dem HTML-Dokument und nicht mit dem Nutzer. Dadurch kann der Effekt des Applets angepasst werden, ohne die .class-Datei zu verändern. Paramter werden innerhalb der <APPLET>-Tags definiert: 1 2 3 <APPLET CODE = " ... " WIDTH = " ... " HEIGHT = " ... " > <PARAM NAME = " TEXT " VALUE = " ... " > </APPLET> Mit Hilfe der Methode String getParameter(String) erfolgt das Einlesen dieser Parameter. Für gewöhnlich prüft man das Vorhandensein des Parameters mit dem Namen TEXT durch den folgenden Code: 1 2 3 4 String text ; i f (( text = getParameter ( " TEXT " )) == n u l l ) { text = " Nicht definiert ! " ; } 3. Kopieren Sie HalloInternet.java in ParamString.java und verändern sie die Klasse dahingehend, dass der auszugebende String als Parameter eingelesen wird. 4. Nutzen Sie die Methode init() um die Hintergrundfarbe des Applets anzupassen. Zusatzaufgabe: Erstellen Sie ein Applet, das graphisch ein Balkendiagramm mit zwei Säulen darstellt. Es soll durch zwei Parameter definiert werden. 3 2 Multithreading Jedes Java-Programm ist implizit ein Thread. In Java können mehrere Threads erzeugt werden, die dann nebenläufig arbeiten. Threads sind Objekte der Klasse java.lang.Threads und sind: wie Programme: ein Thread ist eine sequenzielle Folge von Anweisungen wie Prozesse: mehrere Threads des gleichen Programms können parallel zueinander laufen anders als Prozesse: Threads des gleichen Programms benutzen den gleichen Speicherbereich, was zum Informationsaustausch genutzt werden kann. Das Zusammenspiel der Threads muss im Programm selber organisiert werden. Das Java-Programm läuft immer solange bis alle seine Threads beendet sind. 2.1 Wichtige Methoden von Threads Ähnlich wie Applets, haben Threads bestimmte eigene Methoden: void run() „Hauptprogramm“ des Threads; enthält dein eigentlichen Anweisungsteil, der nach Aktivierung des Threads, durch den Aufruf der start-Methode, ausgeführt wird. void start() startet den Thread durch den Aufruf von run(). (run() sollte niemals direkt aufgerufen werden!) Thread Thread.currentThread() liefert den aktuellen Thread zurück void Thread.sleep(long ms) lässt den aktuellen Thread ms Millisekunden pausieren void join(Thread t) wartet auf das Ende von Thread t void yield() der aktuelle Thread lässt anderen Threads den Vortritt 4 2.2 Erzeugen von Threads Um Threads zu erzeugen, gibt es zwei Möglichkeiten: 1) Unterklasse von Thread 2) Implementation von Runnable class T extends Thread { ... public void run() { ... } ... } class XYZ { ... T t = new T(...); t.start(); } class R implements Runnable { ... public void run() { ... } ... } class XYZ { ... Thread t = new Thread(new R(...)); t.start(); } 3. Kopieren Sie sich aus dem Ordner /home/rlehre/W11 die Dateien Thread1.java, Thread2.java und ThreadDemo.java. Analysieren Sie diese Dateien und testen Sie sie. 4. Nennen Sie eine Gemeinsamkeit und einen Unterschied von Multitasking und Multithreading. Gemeinsamkeit: Unterschied: 5. Geben Sie den vollständigen Programmcode (einschließlich der Exception-Behandlung) an, um die Ausführung eines Thread um 2,5 Sekunden zu unterbrechen: 5 2.3 Zustände von Threads In Abbildung 1 werden die verschiedenen Zustände aufgezeigt, die ein Thread durchlaufen kann. Abbildung 1: Zustände eines Threads Wie alle Objekte, werden Threads durch den Aufruf des Konstruktors mittels new() erzeugt . Durch den Aufruf von start() werden sie in den Zustand rechenwillig gesetzt. Im Zustand rechenwillig können verschiedene Zustände erreicht werden. Im Normalfall wartet der Thread darauf, dass ihm vom Scheduler Rechenzeit zugewiesen wird, wodurch jener in den Zustand rechnend versetzt wird. Nach Ablauf der Rechenzeit wird der Thread vom Scheduler wieder in den Zustand rechenwillig versetzt. Der gleiche Übergang geschieht auch, wenn während der Ausführung des Threads der Aufruf von yield() ausgeführt wird. Mit der Methode sleep() kann man den Thread in den Zustand schlaf end überführen. Nach Ablauf der übergebenen Zeit wechselt der Thread zurück in den zustand rechenwillig . 6. Programmieren Sie eine Unterklasse InThread von Thread. Dabei ist ein InThread ein Thread, der in einer Endlosschleife wiederholt auf der Konsole die Aufforderung „Bitte geben Sie Ihren Vornamen ein!“ ausgibt und dann einen String von der Standardeingabe (Tastatur) einliest. 7. Testen Sie InThread in einer Applikation UseInThread, die ein Exemplar von InThread erzeugt, startet und nach einer Wartezeit von 10 Sekunden den aktuellen Wert des Datenelements von InThread ausdruckt. 6 8. Kopieren Sie die Datei Blinker.java aus dem Verzeichnis /home/rlehre/W11 und analysieren Sie diese. a) Warum kann die Klasse Blinker nicht Unterklasse von Thread sein? b) Welche Methoden gehören zur Klasse Applet? c) Welche Methoden gehören zum Interface Runnable (zur Klasse Thread)? 9. Programmieren Sie ein Applet IOThread, das neben InThread einen Thread startet, dessen run-Methode in IOThread implementiert ist, und der im Appletfenster im Abstand von 2 Sekunden den von InThread eingelesenen Vornamen an wechselnden Positionen ausgibt. Solange noch kein Vorname eingelesen wurde, soll der String „Hallo“ an diesen Positionen ausgegeben werden. Beide Threads sollen solange laufen, bis das Applet endgültig beendet wird. 2.4 Synchronisation – Monitore Wenn sich ein Thread mit einem anderen Thread synchronisiert oder auf benötigte Ressourcen warten muss, dann kommt ein Thread in den Zustand blockiert . Mittels dem Schlüsselwort synchronized wird ein Objekt obj für einen Thread reserviert, bis der Anweisungsblock (geschützter Bereich) verlassen wird: ... synchronized (obj) { ... } ... oder: synchronized ResultType method(...) { ... } ist kurzform für ResultType method(...) { synchronized (this) { ... } } 7 Abbildung 2: Synchronisation von Threads 2.5 Synchronisation – Datenübergabe Wenn ein Objekt obj reserviert ist, dann • löst obj.wait() die Reservierung und blockiert den aktuellen Thread • löst obj.notify() die Blockierung des wartenden Threads Beispiel: synchronized (obj) { ... // obj vorbereiten obj.wait(); // auf Ergebnis in obj warten ... // Ergebnis weiterverarbeiten } ... synchronized (obj) { ... // rechnen, Ergebnis in obj ablegen obj.notify(); // Fertigmeldung } 10. Analysieren Sie mit dem Dozenten die Dateien Lager.java, Lieferant.java und LagerDemo.java. 11. Zusatzaufgabe 1: Programmieren Sie eine Applikation. Diese Applikation soll in einem Fenster laufen. Das Fenster soll einen Button mit der Aufschrift „Fang mich!“ haben. Das betätigen des Buttons soll das Fenster schließen. Mittels der Methode setLocation(int, int) soll der Button nach einer zufälligen Zeit an eine andere Stelle gesetzt werden. 12. Zusatzaufgabe 2: Ändern Sie das Programm aus Zusatzaufgabe 1 derart ab, dass es keine Unterklasse von Frame ist. Dazu müssen Sie ein Frame-Objekt erzeugen und die entsprechenden Methoden des Frames über das Frame-Objekt aufrufen. 8