5 Beispiel Applet

 

5.1 Grundlegende Arbeitsweise eines Applets

Applets sind Java-Programme, die auf einem Internet / Intranet-Server gespeichert sind. Sie werden auf verschiedene Client-Plattformen heruntergeladen und dort in einer Java Virtual Machine (JVM) ausgeführt, die von dem auf dem Client-Rechner ausgeführten Browser bereitgestellt wird.

Um ein Applet in einer Webseite zu integrieren benötigt man ein sogenanntes <APPLET>-Tag. In diesem <APPLET>-Tag stehen Informationen, die die JVM benötigt, um das Applet auszuführen.

Bevor das Applet gestartet wird prüft das Klassenlademodul in der JVM welche Klassen benötigt werden. Beim Klassenladevorgang werden die Klassendateien überprüft um sicher zu sein, daß es sich um gültige Klassendateien und nicht um bösartigen Code handelt. Ist der Klassenladevorgang erfolgreich abgeschlossen wird das Applet ausgeführt.

Benutzer, die ein Programm aus dem Internet herunterladen und ausführen, wollen sicher sein, daß dieses Programm keine bösartigen Aktionen ausführt wie z. B. das Formatieren der Festplatte oder das Öffnen von Verbindungen für "nicht vertrauenswürdige" Rechner. Deshalb erfolgt die Verteilung und Ausführung unter Aufsicht eines Security Managers, der Applets daran hindern kann, Aufgaben auszuführen.

Da der Security Manager viele Aktivitäten, die bei einer "normalen" Anwendung selbstverständlich sind nicht zuläßt, muß der Entwickler eines Applets sich im Vorfeld Gedanken darüber machen, welche Einschränkungen der Security Manager verursacht.

Standardmäßig werden alle Applets als "nicht vertrauenswürdig" betrachtet und von bestimmten Aktivitäten ausgeschlossen. Dazu zählen:

Es gibt weitere Aktivitäten (z. B. die Ausführung von Programmen auf lokalen Systemen, um Zeit zu sparen), die für Anwendungsentwickler selbstverständlich, in Applets jedoch nicht erlaubt sind. In jedem brauchbaren Java-Buch werden die Einschränkungen und eventuelle Lösungen aufgelistet, denen Applets unterliegen. [JBulider3]

 

 

5.2 Eigenschaften des Beispiel Applets


Abb. 5.1: Screenshot von der Benutzeroberfläche des Beispiel Applets

Das Beispiel Applet in dieser Diplomarbeit soll jedem Anwender zeigen, wie sich die Synchronisation von Threads auswirkt. Zur besseren Übersicht wurde der Programmcode, den die einzelnen Threads ausführen einfach gehalten.
Bei diesem Applet hat man die Möglichkeit drei Zähler und eine grafische Animation zu starten. Die drei Zähler des Applets und die grafische Animation sind unterschiedlich realisiert worden.

Der 1. Zähler ( Counter genannt ) ist durch eine einfache Klasse mit dem Namen Counter implementiert worden. Diese Klasse wird nicht als Thread ausgeführt sondern als "normaler" Programmcode.

Der 2. Zähler ( Thread 1 genannt ) ist durch die Klasse CountingThread implementiert worden. Diese Klasse wurde jedoch von der Klasse Thread abgeleitet und die run() Methode mit dem Programmcode des Zählers überschrieben. Dieser Zähler wird daher als Thread ausgeführt.

Der 3. Zähler ( Thread 2 genannt ) ist durch die Klasse CountingThreadRunnable implementiert worden. Diese Klasse besitzt das Interface Runnable und die run() Methode wurde mit dem Programmcode des Zählers überschrieben. Dieser Zähler wird daher als Thread ausgeführt.

Die grafische Animation ( Thread 3 genannt ) ist durch die Klasse ImageCanvas implementiert worden. Diese Klasse wurde von der Klasse Canvas abgeleitet und besitzt das Interface Runnable und die run() Methode wurde mit dem Programmcode für die grafische Animation überschrieben. Die grafische Animation wird auch als Thread ausgeführt.

Thread 3 soll eine Belastung des Systems verursachen, damit das Verhalten des Applets auch unter verschiedenen Bedingungen beobachtet werden kann.
Die eventuelle Synchronisation findet, mit Ausnahme der "Synchronisation durch Priorität", zwischen Thread 1 und Thread 2 statt.

 

Die Oberfläche des Applets kann in vier Hauptbereiche unterteilt werden :

Folgende Arten der Synchronisation können ausgewählt werden:

Zusätzlich zu diesen Bereichen findet man am unteren rechten Rand noch zwei Buttons. Der Button "Alle Threads anhalten" bzw. "Alle Threads weiterführen" dient dazu, alle laufenden Threads anzuhalten oder weiterzuführen, ohne das die Synchronisation unterbrochen wird. Jeder Thread arbeitet nach der Unterbrechung so weiter wie vorher. Der "RESET" Button versetzt die Threads und das Ausgabefeld wieder in den Startzustand.

Führt man das Applet im Browser aus, wird die maximale Priorität der Threads vom System so begrenzt, daß wichtige Systemprozesse weiter arbeiten können und somit das System lauffähig bleibt (siehe Kapitel 2.6).
Wird das Applet in einem Appletviewer ausgeführt besteht diese Begrenzung nicht. In so einem Fall kann die Priorität bis auf das Maximum (Prioritätswert 10) eingestellt werden. Hierbei ist darauf zu achten, daß die Lauffähigkeit des Systems bei der Vergabe von zu hohen Prioritäten eingeschränkt oder sogar gestoppt wird.

 

5.3 Klassen des Applets

Die Klassen, Konstruktoren und Methoden des Beispiel Applets werden in diesem Kapitel genauer erläutert. Im Source-Code befinden sich zusätzliche Erläuterungen, so daß nicht alle Attribute der Klassen hier aufgelistet werden.

Auf eine zusätzliche Visualisierung durch UML (Unified Modeling Language) Diagramme, wie z.B. einem Klassendiagramm, wurde ebenfalls verzichtet.

 

5.3.1 Die Klasse Applet1.java

Die Klasse Applet1 ist von der Klasse Applet abgeleitet und besitzt die Interfaces ActionListener und FocusListener. Diese Klasse erzeugt die Eingabemaske. Die Hauptkomponenten dieser Oberflächen sind die zahlreichen Eingabefelder (javax.swing.JTextField), Bezeichner für die Oberfläche (javax.swing.JLabel) und die Aktionsknöpfe (javax.swing.JButton).

Diese Komponenten werden hier nicht eingehender erläutert, da sie im Source-Code kommentiert sind.

 

Attribute:


private boolean sync 
	Variable für Synchronisation durch Ereignisse.


private boolean syncjoin
	Variable zur Synchronisation auf das Ende eines Threads.
 

private CountingThread thread1
	Objekt für Thread 1.


private Thread thread2, thread3 
	Objekte für Thread 2 und Thread 3.


private Runnable rthread, bthread    
	Runnable Objekte für die Klassen mit dem Interface Runnable.


private int[] thindex = new int [3]
	Thread Index um festzuhalten welcher Thread gestartet wurde.


private String sleepthread1 
private String sleepthread2  
     	Variable um sleep-Zeit zu speichern, wenn durch Priorität synchronisiert wird.


private Steuerung steuer = new Steuerung(false)
	Objekt um die Threads anzuhalten und wieder auszuführen. 


private Beenden stop2 = new Beenden(false)
private Beenden stop3 = new Beenden(false)
  	stop2 ist ein Objekt der Klasse Beenden und dient dazu dem Thread 2 
	anzuzeigen, das er seine run() Methode beenden soll. stop3 ist für Thread 3.


private Syncprio syncprio 
	Diese Objekt dient zur Synchronisation durch Priorität.


private IntJTextField jTextFieldA[] = new IntJTextField[13]
	Feld für 13 Textfelder (Eingabefelder).


MeineTextArea textArea1 
	Ausgabefeld für alle Threads und Zusatzinformationen.


Methoden:

public String getParameter(String key, String def) 
	Parameterwert zum Starten des Applets holen.


public Applet1() 
	Das Applet konstruieren.


public void init() 
	Das Applet initialisieren.


private void jbInit() 
	Initialisierung der Komponenten.


public String getAppletInfo() 
	Applet-Informationen werden geholt.


public String[][] getParameterInfo()
	Parameter-Infos holen.


public static void main(String[] args) 
 	 Main-Methode


public void actionPerformed(ActionEvent e)
	ActionPerformed, der ausgeführt wird sobald ein Button betätigt wird.


void thread1start()
	Eigene Methode um Thread 1 zu erzeugen und ggf. zu starten.


void thread2start()
	Eigene Methode um Thread 2 zu erzeugen und ggf. zu starten.
 

void jButton1_actionPerformed(ActionEvent e)
	Methode, die durch Betätigung eines Buttons ausgeführt wird, um die Priorität
	von Thread 1 herabzusetzen.


void jButton2_actionPerformed(ActionEvent e)
    	Methode, die durch Betätigung eines Buttons ausgeführt wird, um die Priorität
	von Thread 1 heraufzusetzen.


void jButton3_actionPerformed(ActionEvent e)	
	Methode, die durch Betätigung eines Buttons ausgeführt wird, um die Priorität
	von Thread 2 herabzusetzen.


void jButton4_actionPerformed(ActionEvent e)
 	Methode, die durch Betätigung eines Buttons ausgeführt wird, um die Priorität
	von Thread 2 heraufzusetzen.
  
   
void jButton5_actionPerformed(ActionEvent e)
	Methode, die durch Betätigung eines Buttons ausgeführt wird, um die Priorität
	von Thread 3 herabzusetzen.
    

void jButton6_actionPerformed(ActionEvent e)
                Methode, die durch Betätigung eines Buttons ausgeführt wird, um die Priorität 
                von Thread 3 heraufzusetzen.


public void focusLost(FocusEvent e)
                Methode des FocusListener wird ausgeführt sobald ein Objekt den Focus verliert. 

public void focusGained(FocusEvent e)
	Methode des FocusListener wird ausgeführt sobald ein Objekt den Focus erhält.
 

public boolean test()
	Methode, die kontrolliert, ob alle Textfelder in ihrem Wertebereich sind.
  

public void setsync()
   	Diese Methode stellt fest ob die Ausgabe synchronisiert werden soll.


void groupBox1_itemStateChanged(ItemEvent e)  
                Methode wird ausgeführt, wenn durch Ereignisse synchronisiert werden soll. 
                Sie setzt dann die entsprechenden Parameter.
 

void groupBox2_itemStateChanged(ItemEvent e)
                Methode wir ausgeführt, wenn durch die Priorität synchronisiert werden soll. 
                Sie setzt dann die entsprechenden Parameter.


void groupBox3_itemStateChanged(ItemEvent e)
                Methode wird ausgeführt, wenn auf das Ende des zweiten Threads  
                synchronisiert wird. Sie setzt dann die entsprechenden Parameter.


void groupBox4_itemStateChanged(ItemEvent e)
	Methode wird ausgeführt, wenn nicht synchronisiert werden soll.
	Sie setzt dann die entsprechenden Parameter.


void jTextFieldA11_actionPerformed(ActionEvent e)
	Methode wird ausgeführt, wenn eine Eingabe im Textfeld 11 
                erfolgte. Dieses Eingabefeld bestimmt die Anzahl der Ausgaben.


void jTextFieldA12_actionPerformed(ActionEvent e)
	Methode wird ausgeführt, wenn eine Eingabe im Text Feld 12
                erfolgte. Dieses Eingabefeld bestimmt die Anzahl der Schleifen.


class Applet1_jTextFieldA11_actionAdapter implements
					java.awt.event.ActionListener 
	Klasse des action_Adapter für das Eingabefeld 11


public void actionPerformed(ActionEvent e) 
	Methode des action_Adapter für das Eingabefeld 11


class Applet1_jTextFieldA12_actionAdapter implements 
					java.awt.event.ActionListener    
	Klasse des action_Adapter für das Eingabefeld 12


public void actionPerformed(ActionEvent e) 
	Methode des action_Adapter für das Eingabefeld 12

 

5.3.2 Die Klasse Beenden.java

Diese Klasse dient dazu, die Thredas 2 und 3, die mit Hilfe des Interfaces Runnable erstellt wurden, zu beenden. Durch ein Objekt dieser Klasse können die beiden Threads "erfragen" ob sie sich beenden sollen.

 

Konstruktor:

public Beenden(boolean wert)
                Beim Erzeugen des Objekts muß der Anfangswert übergeben werden.

 

Attribut:

private boolean stop
	Speichert den Wert des Objektes.

Methoden:


public void set(boolean wert)
	Methode um den Wert des Objektes zu ändern.
 

public boolean get()
 	Methode um den Wert des Objektes abzufragen.

 

5.3.3 Die Klasse Counter.java

Diese Klasse ist ein Zähler, der einen übergebenen Wertebereich durchläuft.

 

Konstruktor:

public Counter(MeineTextArea textArea1)
	Beim Erzeugen wird die Text Area übergeben, auf die die Ausgabe erfolgen soll.
 

Attribute:

private int start       
	Startwert des Zählers.

private int finish      
	Ende des Zählers.

private long time       
	Zeit, die der Zähler zwischen den Zählerschritten "schlafen" soll.

MeineTextArea textArea1  
	TextArea für die Ausgabe.

	

Methode:

public void setcounter (int from, int to, long zeit)
	Daten für den Zähler werden übernommen und der Zähler wird
                ausgeführt.

5.3.4 Die Klasse CountingThread.java

Diese Klasse ist von Thread abgeleitet und beinhaltet einen Zähler, der somit als Thread ausgeführt wird.

 

Konstruktor:

public CountingThread(Syncprio syncprio,MeineTextArea textArea1,
		      Steuerung steuer,JLabel jLabel12)
	Beim Erzeugen werden Objekte von anderen Klassen übergeben.
                Diese Objekte werden zur Steuerung und Ausgabe des Threads benötigt.

 

Attribute:

private int start
private int finish 
private long time
	Variablen wie bei der Klasse Counter


private boolean stop     
	Variable für eigene "stop"-Methode des Threads


MeineTextArea textArea1
	TextArea für Ausgabe.


Steuerung steuer
	Steuerobjekt zum Überprüfen, ob der Thread anhalten soll.


Syncprio syncprio
	Steuerobjekt für Synchronisation durch Priorität.


JLabel jLabel12
	Ausgabefeld der Priorität

 

Methoden:


public void meinstop()
	Modifizierte "stop"-Methode.


public void setcountingthread(int from, int to,long zeit)
	Methode um die Daten für den Zähler zu übernehmen.
 
public void joinset(Thread thread)
                Modifizierte "start"-Methode. Sie dient zum Starten, wenn auf das Ende eines 
                andern Thread gewartet werden soll.

 

public void run()
       run() Methode des Threads.

 

5.3.5 Die Klasse CountingThreadRunnable.java

Diese Klasse beinhaltet ebenfalls ein Zähler. Sie besitzt das Interface Runnable wodurch der Programmcode ebenfalls als Thread ausgeführt wird.

 

Konstruktor:

 

public CountingThreadRunnable(JLabel jLabel13,Syncprio syncprio,
                              Beenden stop2,Steuerung steuer, 
                              MeineTextArea textArea1,
                              int from, int to,long zeit)	
               Beim Erzeugen werden Objekte von anderen Klassen und die Daten für den 
               Zähler übernommen. Die Objekte dienen der Steuerung und der Ausgabe des Zählers.

Attribute:

private int start
private int finish 
private long time
	Variablen wie bei der Klasse Counter


Beenden stop
	Objekt zum Beenden des Threads


MeineTextArea textArea1
	TextArea für Ausgabe.


Steuerung steuer
	Steuerobjekt zum Überprüfen, ob der Thread anhalten soll.


Syncprio syncprio
	Steuerobjekt für Synchronisation durch Priorität.


JLabel jLabel13
	Ausgabefeld der Priorität.
	

Methode:


public void run()
	run() Methode des Interfaces Runnable.

 

5.3.6 Die Klasse ImageCanvas.java

Diese Klasse ist abgeleitet von der Klasse Canvas und besitzt das Interface Runnable.Sie wird für die grafische Animation benötigt, die ebenfalls als Thread ausgeführt wird.

 

Konstruktor:

public ImageCanvas(Image images[],Steuerung steuer,Beenden stop3,
		       Syncprio syncprio)
	Es wird ein Feld, das die Bilder enthält und Objekte anderer Klassen, übergeben.

Attribute:

private Image images[] 
	Feld für die Bilder, die ausgegeben werden sollen.


private int currentimage 
	Variable für Bild.


Beenden stop
	Objekt zum Beenden des Threads


Steuerung steuer
	Steuerobjekt zum Überprüfen, ob der Thread anhalten soll.


Syncprio syncprio
	Steuerobjekt für Synchronisation durch Priorität.

Methode:


public void paint(Graphics g)
	Methode zum Zeichnen des Bildes.


public void update(Graphics g)
	Methode zum Zeichnen des Bildes.


public void run()
	run() Methode des Interfaces Runnable.

 

5.3.7 Die Klasse IntJTextField.java

Diese Klasse ist abgeleitet von der Klasse JTextField.

Einige Methoden wurden ergänzt bzw. der Konstruktor so verändert, daß die Objekte Eingabefelder mit einem festen Wertebereich sind.

 

Konstruktor:

public IntJTextField (int min, int max)
	Konstruktor der Klasse dem beim Erzeugen des Objektes der erlaubte
	Wertebereich der Eingabe übergeben wird.

Attribute:


private int low        
	Untere Grenze des Wertebereiches.


private int high       
	Obere Grenze des Wertebereiches

 

Methoden:


public boolean isValid() 
	Methode um festzustellen, ob die Eingabe des Objektes ein Int-Wert im 
	erlaubten Wertebereich ist.


public int getValue()
	Methode zum Auslesen des Textfeldes.

 

5.3.8 Die Klasse MeineTextArea.java

Die Klasse ist von der Klasse TextArea abgeleitet und dient zur synchronisierten und nicht synchronisierten Ausgabe der Threads.

 

Konstruktor:

public MeineTextArea()
	Parameterloser Konstruktor
 

Attribute:


private String buffer
	Buffer für die Ausgabe.


private int soll       
	Anzahl der "soll" Ausgaben.


private int anzahl    
	Anzahl der "ist" Ausgaben


boolean th1       
	Variable die bei einer Synchronisation durch Ereignisse angibt welcher Thread
	den Monitor erhält.


boolean sync     
	Variable die angibt ob eine Synchronisation durch Ereignisse stattfinden soll.

 

Methoden:


public void set(boolean syncronisieren,int anzahl)
	Methode zum Starten und Beenden der Synchronisation durch Ereignisse.


public synchronized void put1 (String ausgabe)
	Synchronisierte Methode für die Ausgabe von Thread 1


public synchronized void put2 (String ausgabe) 
	Synchronisierte Methode für die Ausgabe von Thread 2
 

public synchronized void put (String ausgabe)
	Synchronisierte Methode für die Ausgabe von allgemeinen Informationen.

5.3.9 Die Klasse Steuerung.java

Über ein Objekt dieser Klasse können die Threads angehalten und zu einem beliebigen Zeitpunkt weitergeführt werden.

 

Konstruktor:

public Steuerung(boolean wert)
	Beim Erzeugen des Objektes muß der Anfangswert übergeben werden. 
 

Attribute:


private boolean halt
	Diese Variable zeigt an ob die Threads anhalten sollen oder nicht.

Methoden:


public void setanhalten ()
	Methode um der Wert des Objektes auf true zu setzen.
 

public synchronized void weiter()
	Methode um den Wert des Objektes auf false zu setzen.
 

public synchronized void anhalten ()
                Methode bei dessen Ausführung ein Thread angehalten wird, 
                wenn das "Steuerugsobjekt" true ist.

 

5.3.10 Die Klasse Syncprio.java

Ob eine Synchronisation durch die Priorität stattfindet, wird durch ein Objekt dieser Klasse angezeigt. Die benötigten Schleifen um das System zu belasten gehören auch zu dieser Klasse.

 

Konstruktor:


public Syncprio(boolean wert, int schleifen)
	Die Schleifenzahl und ob eine Synchronisation durch die Priorität erfolgen soll
	wird beim Erzeugen festgelegt.
 

Attribute:


private boolean sync
	Zeigt an ob synchronisiert werden soll


private int schleifen
	Gibt an wie oft die Threads die Methode "zeit()" aufrufen sollen.

Methoden:


public void setschleifen(int schleifen)
	Methode mit der die Schleifenzahl verändert werden kann.
 

public int getschleifen()
	Methode über die die Schleifenzahl erfragt werden kann.
 

public void setsync(boolean wert)
	Methode über die festgelegt wird ob eine Synchronisation durch die Priorität 
	erfolgen soll oder nicht.
 

public boolean getsync()
	Methode über die erfragt werden kann ob eine Synchronisation durch die 
	Priorität erfolgen soll.
 

public synchronized int zeit()
	Methode um bei einer Synchronisation durch die Priorität das System zu 
	belasten.