7.2.5 | Kommunikation zwischen Browser und Applet |
Applet und Browser können untereinander kommunizieren. Wie ein Browser über den Aufruf von Methoden des Lebenszyklus mit einem Applet kommuniziert, wurde schon im letzten Abschnitt gezeigt.
Ein Applet besitzt aber auch die Möglichkeit, mit dem Browser zu kommunizieren. Ein Applet kann:Diese Kommunikation wird über das Interface AppletContext abgewickelt. AppletContext wird aber nicht vom Applet, sondern vom Browser bzw. Appletviewer implementiert. Den AppletContext der jeweiligen Umgebung erhält man durch Aufruf der von der Klasse Applet bereitgestellten Methode getAppletContext().
- eine neue URL im Browser anzeigen,
- die Statuszeile des Browsers verändern,
- Nachrichten mit Applets austauschen, die sich auf derselben HTML-Seite befinden.
AppletContext enthält alle Methoden, die zur Kommunikation mit dem Browser notwendig sind. Im folgenden werden die einzelnen Methoden ausführlicher beschrieben.
Ein Applet besitzt die Möglichkeit, die Daten einer neuen URL in den Browser zu laden. Dies kann man z. B. zur Implementierung eines Navigators anwenden. Eine andere Anwendungsmöglichkeit ist die Implementierung einer Imagemap. In einem Applet kann man den Statustext je nach Mausposition ändern (siehe nächster Abschnitt) und bei Mausdruck anschließend eine neue URL anzeigen. Hierzu verwendet man die Methode showDocument() des AppletContext. showDocument() gibt es in zwei Varianten:Hierzu ein Beispiel: Ein Browser soll in zwei Frames unterteilt werden. Ein Browser-Frame dient zum Anzeigen der HTML-Seiten, die Informationen enthalten; der zweite Frame enthält ein Applet, das zum Navigieren verwendet wird.
showDocument(URL) Zeigt die Daten der angegebenen URL im Browser an. showDocument(URL, String) Zeigt die Daten der angegebenen URL in dem als String übergebenen Browser-Frame. Diese Methode kann allerdings nur bei einem Browser angewendet werden, der Frames darstellen kann (z. B. der Netscape Navigator). Die einzelnen Werte für String sind der Referenz zu entnehmen.
Das Navigations-Applet besitzt zwei Buttons. Jeder der Buttons repräsentiert eine HTML-Seite. Drückt man einen Button, wird die entsprechende Seite in den Informations-Frame geladen.
Das Anzeigen eines Dokuments wird durch folgende zwei Zeilen vorgenommen:URL page = new URL(getCodeBase(), "FirstPage.html"); getAppletContext().showDocument(page, "data");Obiger Code wird ausgeführt, wenn der Button gedrückt wurde, der die Seite SecondPage.html laden soll.
Zuerst wird ein Exemplar der Klasse URL erzeugt. Dies ist notwendig, da einer der Parameter von showDocument() vom Typ URL ist. Die Klasse URL wird im Abschnitt 13.1 ausführlich erklärt.
Danach werden die Daten der URL mit der Methode showDocument() angezeigt. Die URL und den Namen des Browser-Frames, in dem die Daten angezeigt werden sollen, übergibt man als Parameter. In diesem Fall wird die Datei FirstPage.html im Frame mit dem Namen »data« angezeigt.
An dieser Stelle wird nur auf das Anzeigen der Daten eingegangen. Für die Behandlung der Ereignisse und für das Erstellen der Buttons wird auf das Kapitel 9 verwiesen.Für diejenigen, die mit dem Umgang mit Browser-Frames nicht so vertraut sind, folgt an dieser Stelle der Aufbau der Seite, die in den Browser geladen wird:
<HEAD> <TITLE>A Java-Navigator</TITLE> </HEAD> <FRAMESET ROWS="15%, 85%"> <FRAME SRC="ShowDocumentDemo.html" NAME="navigator"> <FRAME SRC="FirstPage.html" NAME="data"> </FRAMESET>Obiger HTML-Code erzeugt innerhalb des Browsers zwei Frames, die durch einen horizontalen Balken voneinander getrennt sind. Die beiden Frames besitzen folgende Merkmale:Hier das komplette Listing des Applets, das in der Seite ShowDocumentDemo.html eingebunden ist:
- Der obere Frame nimmt 15% der Fläche ein, besitzt den Namen navigator und zeigt das Dokument ShowDocumentDemo.html an. In ShowDocumentDemo.html ist das Navigations-Applet eingebunden.
- Der untere Frame nimmt 85% der Fläche ein, besitzt den Namen data und zeigt das Dokument FirstPage.html an. In diesem Frame wird zwischen verschiedenen Seiten hin und her geschaltet.
import java.applet.Applet; import java.awt.*; import java.awt.event.*; import java.net.*; public class ShowDocumentDemo extends Applet implements ActionListener { public void init() { // Erzeugen und Hinzufügen der Buttons Button first, second; first = new Button("first page"); second = new Button("second page"); add(first); add(second); first.addActionListener(this); second.addActionListener(this); } public void actionPerformed(ActionEvent e) { URL page; // Ist der Button 'first page' gedrückt? if ("first page".equals(e.getActionCommand())) { try { // Erzeugen der URL und Anzeigen des Dokumentes page = new URL(getCodeBase(), "de/dpunkt/" +"applets/showdocument/FirstPage.html"); getAppletContext().showDocument(page, "data"); } catch (MalformedURLException ex) { ex.printStackTrace(); } } // Ist der Button 'second page' gedrückt? if ("second page".equals(e.getActionCommand())) { try { page = new URL(getCodeBase(), "de/dpunkt/" +"applets/showdocument/SecondPage.html"); getAppletContext().showDocument(page, "data"); } catch (MalformedURLException ex) { ex.printStackTrace(); } } } }Mit showDocument() kann man nicht nur HTML-Seiten anzeigen lassen, sondern auch Sound, Grafiken oder andere Dokumente. Damit sie angezeigt werden, müssen allerdings die MIME-Types des Browsers richtig konfiguriert sein. In Abschnitt 13.1.1 wird detailliert beschrieben, wie die Erkennung eines Dokuments anhand seines MIME-Typs funktioniert.
Der Browser zeigt in seiner Statuszeile Informationen über einen Ladevorgang oder die Adresse eines Links an. Applets können dies auch. Wenn mehrere Grafiken in ein Applet geladen werden, ist es z. B. sinnvoll, dem Benutzer Informationen über den Fortschritt des Ladezustands mitzuteilen, da dies unter Umständen sehr lange dauern kann. Ebenso können auch Adressen von Links aus Applets in der Statuszeile angezeigt werden. Wie man einen Link mit showDocument() realisieren kann, wurde bereits im letzten Abschnitt gezeigt.Eine andere interessante Variante ist die Darstellung einer Laufschrift in der Statuszeile, indem man nacheinander jeweils denselben Text mit unterschiedlicher Anzahl führender Leerzeichen anzeigt.
Zur Anzeige eines Textes in der Statuszeile wird die Methodepublic void showStatus(String)verwendet. Die Anwendung wird an einem sehr einfachen Applet demonstriert, um nicht zuviel Wissen vorauszusetzen. Das Applet soll eine Begrüßungsmeldung ausgeben, wenn die Maus in das Applet bewegt wird. Verlässt die Maus das Applet, erscheint eine Abschiedsmeldung in der Statuszeile. Zum Nachlesen der in diesem Applet verwendeten Ereignisabarbeitung wird auf das Kapitel 9 verwiesen.
Der Begrüßungstext wird mit der ZeileshowStatus("Welcome to this Applet");ausgegeben. Die Ausgabe der Abschiedsmeldung erfolgt analog.
Da showStatus() eine Methode ist, die wie getImage() und getAudioClip() auch, direkt in der Klasse Applet definiert ist, ist es nicht nötig, sie über den AppletContext aufzurufen:import java.applet.Applet; import java.awt.event.*; import java.awt.*; public class StatusDemo extends Applet implements MouseListener { public void init() { // Der Hintergrund des Applets wird // zur besseren Unterscheidung 'rot' gesetzt setBackground(Color.red); addMouseListener(this); } public void mouseEntered(MouseEvent e) { // Ausgabe der Begrüßungsmeldung, wenn die Maus in // das Applet hinein bewegt wird showStatus("Welcome to this Applet"); } public void mouseExited(MouseEvent e) { // Ausgabe der Abschiedsmeldung, wenn die Maus aus // dem Applet heraus bewegt wird showStatus("Good bye"); } public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public void mouseClicked(MouseEvent e) {} }
Applets, die sich auf derselben HTML-Seite befinden, können direkt untereinander kommunizieren. Die Kommunikation zwischen zwei Applets, die sich auf verschiedenen HTML-Seiten befinden, ist im Netscape Navigator ab Version 3 ebenfalls über einen Umweg möglich: Netscape bietet die Möglichkeit der Kommunikation zwischen Applets und JavaScript. Mit JavaScript ist es möglich, Applets anzusprechen, die sich in beliebigen Browser-Frames und somit auch in unterschiedlichen HTML-Seiten befinden. Ein Applet ist nun in der Lage, eine JavaScript-Funktion aufzurufen, die den Aufruf an ein Applet weiterleitet, das sich auf einer anderen HTML-Seite befindet. Die Kommunikation zwischen zwei Applets innerhalb von Java wird durch zwei Methoden des Interface AppletContext ermöglicht:Hierzu sollte erwähnt werden, dass die Methode getApplet() bei einigen Browsern (z. B. Netscape Navigator 2.0x) nicht funktioniert, weil sie diese Methode nicht implementieren. Um ein Applet unabhängiger zu gestalten, ist es deshalb besser, andere Applets über die Methode getApplets() zu kontaktieren. Kann man auf das Exemplar eines anderen Applets zugreifen, so besitzt man die Möglichkeit, dessen Methoden aufzurufen.
Applet getApplet(String name) Liefert das Applet-Objekt des durch name bezeichneten Applets. name ist der Name, der dem <APPLET>-Tag als Wert des NAME-Attributs übergeben wird. Enumeration getApplets() Liefert eine Aufzählung aller Applet-Objekte, die auf der Seite erreichbar sind. Dies schließt das Applet, das diese Methode aufruft, mit ein.
Dies wird nun an einem kleinen Beispiel demonstriert. Das Beispiel besteht aus zwei Applets. Immer wenn man auf eines der beiden Applets klickt, wird im anderen Applet die Zahl der Klicks ausgegeben. Der für die Kommunikation relevante Code wird bei der Abarbeitung des Mausklicks ausgeführt:public void processMouseEvent(MouseEvent e) { if (e.getID() == MouseEvent.MOUSE_CLICKED) { // Prüfen, ob schon ein Applet gefunden wurde if (applet == null) // Versuch, das andere Applet direkt über seinen // Namen anzusprechen applet = getAppletContext().getApplet(otherAppletName); if (applet == null) { // Abfragen aller Applets auf der Seite Enumeration applets = getAppletContext().getApplets(); // Suchen des zu kontaktierenden Applets in der Liste System.out.println(applets); while(applets.hasMoreElements() && (! appletfound)) { applet = (Applet)applets.nextElement(); if (applet instanceof Espresso) appletfound = true; } } else appletfound = true; // Wenn das Applet gefunden wurde, // wird dessen Methode TouchMe aufgerufen. if (appletfound) ((Espresso)applet).touchMe(appletName); } super.processMouseEvent(e); }Das Applet definiert einen Verweis applet, welcher das Exemplar des anderen Applets aufnehmen soll. Ist er null, muss das Exemplar angefordert werden. Zuerst wird mitapplet = getAppletContext().getApplet(otherAppletName);der direkte Weg versucht. otherAppletName ist ein String, der den Namen des anderen Applets enthält. Schlägt dieser Versuch fehl, wird getApplets() aufgerufen:Enumeration applets = getAppletContext().getApplets();In diesem Fall wird als Ergebnis eine Aufzählung aller erreichbaren Applets geliefert. In welcher Reihenfolge die Applets innerhalb der Aufzählung auftreten ist nicht spezifiziert und kann sich von Browser zu Browser ändern. Während der Internet Explorer 4.0 z. B. die Applets in der Reihenfolge liefert, in der sie in der HTML-Seite definiert wurden, verwendet der Netscape Navigator 4.0 hierfür die umgekehrte Reihenfolge. Deshalb sollte man sich auch nicht auf diese Reihenfolge verlassen, wenn man portable Applets schreiben will. Eine Aufzählung wird in Java durch das Interface Enumeration repräsentiert. Das Interface Enumeration ist in Abschnitt 16.1.5 näher erklärt.
Material zum Beispiel
- Quelltexte:
Aus der gelieferten Aufzählung muss man nun zuerst das Applet herausfinden, das kontaktiert werden soll. Hierzu muss man den Namen der Klasse kennen, von der das Applet erzeugt wurde.if (applet instanceof Coffee) appletfound = true;Für jedes Applet in der Aufzählung wird geprüft, ob es ein Exemplar dieser Klasse ist. Bei diesem Beispiel soll die Klasse Coffee kontaktiert werden. Ist das gesuchte Applet gefunden, können dessen Methoden aufgerufen werden, z. B. die Methode touchMe() des Applets »Coffee«:((Coffee)applet).touchMe(appletName);Das gelieferte Objekt muss zuerst durch einen Cast umgewandelt werden, damit man die entsprechende Methode aufrufen kann, weil die Klasse Applet die Methode touchMe() nicht besitzt.