Axel Rogat
Objektorientiertes Programmieren mit C++ und JAVA
 
29.4: Browser-Zusammenarbeit Kapitel 29 30.1: Graphics 
 
  29.5 Kommunikation zwischen Applets  
 

Wenn mehrere Applets im selben HTML-Dokument erscheinen, laufen sie "gleichzeitig". Im Browser werden sie in dieselbe Seite integriert, der Appletviewer erzeugt ein eigenes Fenster für jedes Applet. Diese Applets können miteinander kommunizieren. Die grundlegenden Methoden dazu sind folgende (aus AppletContext):

Applet getApplet(String name);

Diese Methode liefert eine Referenz auf das Applet, das imo <APPLET>-Tag der Namen name bekommen hat. Gibt es kein solches, wird null zurückgegeben. Es ist nicht definiert, was passiert, wenn der Name mehrfach vergeben wurde.

Enumeration getApplets();

Hier werden Referenzen auf alle Applets auf der aktuellen Seite in eine Enumeration verpackt.

Wenn danach nun die Applets gegenseitig ihre Referenzen kennen, können sie einfach dadurch miteinander kommunizieren, daß sie Methoden der jeweils anderen Applets aufrufen.

Das Interface Enumeration stammt aus java.util und dient insbesondere bei Collections als Ersatz für die fehlende Möglichkeit, sich elementweise zu durchlaufen:

interface java.util.Enumeration { boolean hasMoreElements(); Object nextElement(); // throws NoSuchElementException };
Beispiel: So gibt ein Applet sich selbst und seine Brüder auf derselben Seite auf die JAVA-Konsole (z.B. von Netscape) aus:
Enumeration theApplets=getApplets(); while (theApplets.hasMoreElements()) System.out.println(theApplets.nextElement());
Die Ausgabe ist zum Beispiel:
imgtest[0,0,512x384,invalid,hidden,layout=java.awt.FlowLayout] balls[0,0,512x512,invalid,hidden,layout=java.awt.FlowLayout] enumtest[0,0,512x384,invalid,hidden,layout=java.awt.FlowLayout]
Achtung: Eventuell liefern die Browser nur Informationen über solche Applets, die die gleiche CODEBASE wie das aktuelle haben, oder schränken den Zugriff auf andere Applets noch weiter ein.

Vorsicht: Browser legen meist zunächst alle Applet-Objekte zur aktuellen Seite an und initialisieren sie danach. Die Enumeration enthält dann alle Applets, diese brauchen aber noch nicht initialisiert zu sein. Beim Appletviewer ist noch nicht einmal garantiert, daß (zu Beginn) die Enumeration schon vollständig ist. Wenn man die Anzahl aller Applets im voraus kennt, sollte man Code einbauen, der darauf wartet, daß auch alle erzeugt (und ggf. initialisiert) sind.

Beispiel: Wir plazieren 4 Applets unserer Klasse commtest im Format 2×2 auf eine HTML-Seite. Wenn in ein Applet mit der Maus geklickt wird, wird nicht in das getroffene, sondern in das nächste Applet an der Stelle des Mausklicks ein schwarzer Fleck gemalt.

Enumerations, wie getApplets() eine liefert, können nur einmal durchlaufen werden. Daher füllen wir sie in einen Vector um. Bei der Gelegenheit wandeln wir die gelieferten Objekte mit einem Cast in commtest um. Falls das Applet dann keines von unserer Klasse ist, wird eine ClassCastException ausgelöst. Solch ein fremdes Applet nehmen wir nicht in den Vector auf.

Das Auswerten des Mausklicks geschieht in der Methode mouseDown(), genaueres dazu im Kapitel über Events. Es wird dann die Methode drawSpot() des nächsten Applets aufgerufen.

Ein passendes HTML-Dokument ist folgendes:

<HTML> <HEAD><TITLE> Applet Communication Test</TITLE></HEAD> <BODY BGCOLOR=black>

<CENTER><TABLE><TR> <TD><APPLET CODE=commtest WIDTH=128 HEIGHT=128></APPLET></TD> <TD><APPLET CODE=commtest WIDTH=128 HEIGHT=128></APPLET></TD> </TR><TR> <TD><APPLET CODE=commtest WIDTH=128 HEIGHT=128></APPLET></TD> <TD><APPLET CODE=commtest WIDTH=128 HEIGHT=128></APPLET></TD> </TR></TABLE></CENTER>

</BODY> </HTML>

Es folgt der Quelltext unserer Klasse commtest:
public class commtest extends Applet { private Vector brothers=new Vector(); private int mynum,x,y; public void init() { Enumeration enum=getAppletContext().getApplets(); int i=0; while (enum.hasMoreElements()) { try { commtest ct=(commtest)enum.nextElement(); brothers.addElement(ct); if (ct==this) mynum=i; ++i; } catch (ClassCastException e) { } } } public boolean mouseDown(Event event, int x, int y) { ((commtest)brothers.elementAt((mynum+1)%brothers.size())) .drawSpot(x,y); return true; } public void drawSpot(int x, int y) { this.x=x; this.y=y; repaint(); } public void paint(Graphics gc) { gc.fillOval(x,y,10,10); } }
 
29.4: Browser-Zusammenarbeit Startseite 30.1: Graphics 
 
© 1998 Axel Rogat