Advanced   Java   Services
Applet Grundlagen
Back Next Up Home

Elementares


Im Gegensatz zu einer Applikation ist ein Applet ein Javaprogramm, das in eine HTML-Seite eingebettet ist und vom Browser aufgerufen wird, wenn dieser die HTML-Datei abarbeitet. Genauer gesagt, enthält die HTML-Datei einen Verweis auf eine class-Datei. Neben diesem Verweis befindet sich noch eine Größenangabe für eine rechteckige Fläche, die vom Browser für das Applet reserviert wird. Mit Hilfe einer Javaumgebung versucht dann der Browser, dieses Programm zu laden und innerhalb dieser Fläche darzustellen. Dazu braucht der Browser notwendigerweise eine Javaumgebung. MS-InternetExplorer hat die Unterstützung für Applets seit der Version 1.1 eingestellt, es ist aber keine Problem, über ein plug-in dem Internet Explorer eine zur Verfügung zu stellen, siehe JavaUmgebung . Netscape oder Mozilla etwa haben von Haus aus eine neuere Javaumgebung.

Ein Applet ist ein Panel


Betrachtet man die AWT-Klassenhierarchie, sieht man, daß ein Applet eine Unterklasse von Panel ist. Das für ein Applet voreingestellte Layout ist also wie bei einem Panel FlowLayout. Das vergißt man immer wieder gerne, wenn man eine Application in ein Applet verandeln will, da Frame Borderlayout als DefaultLayout hat. Verwendet man ein JApplet, so entfällt diese Überlegung. Ein JApplet benützt ebenso wie ein JFrame ein JRootpane als Container. JFrame und JApplet haben damit das gleiche objektorientierte Design.

Das Applet-Tag


Als Minimalinformation muß der Browser den Namen der class-Datei des Applets und die zu reservierende Größe erhalten

<applet code="MyApplet.class" width=400 height=300>
Text an dieser Stelle wird vom Browser nicht angezeigt
</applet>

Text zwischen dem Anfangs- und Endetag wird vom Browser nicht angezeigt. Falls ein Applet nicht gefunden wird erscheint in der Statuszeile ein Text wie "Applet MyApplet not inited", die in HTML reservierte Fläche bleibt dunkelgrau und ein rollover mit der Maus bringt, falls man einen deutschsprachigen Browser benutzt die Meldung "Fehler beim Laden des Applets".

Aufbau und Lebenszyklus


Da der Browser für die Darstellung eines Applets eine Fläche reserviert, die er aus dem Applet-Tag erfährt, hat ein Applet immer eine graphische Oberfläche, es gibt also keine Konsolanwendungen. Meldungen mit System.out.println() werden vom Browser einfach verschluckt. Zum Austesten sind aber solche Meldungen trotzdem sinnvoll, denn der Appletviewer zeigt Konsolausgaben an. Des weiteren muß eine AppletAnwendung immer von der Klasse Applet abgeleitet werden. Ein Applet braucht auch keine main()-Methode, da der Browser mit Hilfe der JavaUmgebung direkt ein Objekt instanziert und dann eine Reihe von StandardMethoden aufruft, über die jedes selbstgeschrieben Applet über Vererbung verfügt. Durch die Vererbung ist sichergestellt, daß jede AppletAnwendung diese Methoden besitzt. Die Methoden init(), start(), stop() und destroy() werden vom Browser in einer bestimmten Reihenfolge aufgerufen und bestimmen den Lebenszyklus eines Applets.

Aufbau eines Applets

import java.awt.* ;
import java.applet.* ;

public class MyApplet extends Applet
{
   public MyApplet()
   {
      // Der Konstruktor wird meist weggelassen
      // Initialisierungen werden für gewöhnlich in der init()-Methode erledigt
   }

   public void init()
   {
      // Der Browser ruft diese Methode unmittelbar nach dem Konstruktor
      // und nur ein einziges Mal
   }

   public void start()
   {
      // Diese Methode wird zum erstenmal nach init() aufgerufen,
      // dann wieder nach der stop()-Methode, falls der Betrachter
      // im Browser wieder zu der Appletfläche zurückkehrt
   }

   public void stop()
   {
      // Diese Methode kann der Browser rufen, wenn der Benutzer den
      // DarstellungsBereich des Applets verläßt, aber nicht die HTML-Datei
      // Kehrt der Betrachter zum Appletbereich zurück, ruft der Browser wierder start()
   }

   public void destroy()
   {
      // verläßt der Benutzer die HTML-Datei, ruft der Browser diese Methode
   }

   public void paint(Graphics g)
   {
      //Diese Methode wird für graphische Spielereien gebraucht
   }

} // end MyApplet

Bis auf paint() werden diese Methoden als Leerhüllen von Applet geerbt. Ein einfaches Applet etwa braucht nur die init()-Methode und nicht mehr. Verwendet ein Applets Threads, so werden diese gerne in start() erzeugt und in stop() aufgeräumt. Baut ein Applet eine (z. Bsp. Datenbank-) Verbindung zum Server auf, so wird diese gerne in init() aufgebaut und sollte dann spätestens in destroy() wieder geschlossen werden. Wann allerdings ein Browser die stop()-Methode aufruft ist Sache des Browsers, er könnte beim Verlassen der Applet-Stelle im HTML-File auch die stop()-Methode nicht aufrufen und das Applet einfach weiterlaufen lassen.

Lebenszyklus eines Applets


Der Appletviewer


Ein Applet soll zwar in einem Browser laufen, aber zum Debuggen ist ein Browser ungeeignet, da die Fehlermeldungen der Statuszeile in der Regel völlig unzureichend sind. Oft erscheinen Meldungen wie "Applet not inited" oder "Class not found", die zum debuggen keine Hilfe sind. So werden etwa auch keine Exceptions, die geworfen werden, gemeldet. Hier hilft uns der Appletviewer, eine kleine Application, mit der man Applets starten kann. Der Appletviewer verfügt über ein Konsolfenster, auf das er im Fehlerfall Ausgaben macht.

Der Appletviewer wird von der Konsole aus gestartet und erwartet als Parameter eine HTML-Datei. Diese Datei muß zumindest das Applet-Tag enthalten. Der Appletviewer extrahiert daraus den Namen der Klasse und die Größe und stellt das Applet in einem Fenster dieser Größe dar. Das folgende kleine Applet soll in einer TextArea "Hello World" ausgeben und hat einen kleinen Fehler.

Vorsicht:
Beim Appletviewer läßt sich die Größe des Applets beliebig verändern, dies entspricht nicht der Situation in einem Browser, wo die Größe des Rechtecks im Applettag festgelegt wird.

import java.awt.* ;
import java.applet.* ;

public class HelloWorldApplet extends Applet
{
   private TextArea tear ;

   public void init()
   {
      setLayout( new BorderLayout() );
      add(tear);
      tear.append("Hello World");
   }
}

Das Kompilieren macht keine Probleme. Eine simple HTML-Datei dazu kann folgendermaßen aussehen.

<html>
<head>
<title>A Simple Applet<title>
</head>

<body>
<h2>A Simple Applet</h2>
<br>
<applet code="HelloWorldApplet.class" width=400 height=200>
</applet>
<body>
</html>

Wir nennen die Datei HelloWorld.html. Leider läuft das Applet nicht. In der Statuszeile erscheint die Meldung "Applet HelloWorldApplet not inited", das war's. Wir rufen den Appletviewer auf

appletviewer HelloWorld.html

Das Applet läuft (natürlich) auch nicht, aber auf der Konsole erscheint die Meldung NullPointerException mit genauer Angabe des Klassennamens, der Methode und der Zeilennummer des Quelltextes. Jetzt können wir den Fehler sofort beheben. Natürlich haben sie schon beim Durchlesen des Codes erkannt, daß die TextArea nicht initialisiert wurde...

ASCII-Editoren wie etwa TextPad oder UltraEdit integrieren den Appletviewer und ermöglichen so einen Aufruf aus dem Editor heraus.


Austesten eines Applets


Obwohl ein Applet formal einfacher aufgebaut ist wie eine Applikation, kann die Entwicklung einigen Aufwand kosten. Wenn das Applet kompilierbar ist, sollte man es zuerst im Appletviewer testen. Treten hier keine Laufzeitfehler mehr auf, so testet man das Applet mit mindestens zwei Browsern, meist sind dies InternetExplorer und Netscape. Will man Applets haben, die auch in älteren Browsern laufen, die kein plug-in benutzen, so muß man zurückgehen auf die erste JavaVersion 1.0 . Aber in dieser Version gab es weder eine schöne Ereignisbehandlung noch die Möglichkeit, ein eigenes look and feel zu verwenden. Die andere Möglichkeit, ist, dem Benutzer nahezulegen, ein plug-in für den Browser zu verwenden.

Was darf ein Applet


Die Antwort lautet: wenig, und das ist gut so...
Aus Sicherheitsgründen sind die Möglichkeiten eines Applets stark eingeschränkt. So hat ein Applet auf lokale Daten werder lesenden noch schreibenden Zugriff. Auch kann ein Applet keine Programme auf dem Client starten. Ein Applet kann jedoch mit dem Server, von dem es der Browser ausliest und startet Verbindung aufnehmen und hat dort lesenden Zugriff auf Dateien in seinem eigenen Verzeichnis. Über den Umweg einer serverseitigen Anwendung, also einem Servlet oder einem CGI-Perlscript etwa kann ein Applet auch schreibend auf serverseitige Daten zugreifen, indem es dem Servlet oder dem CGI-Script seinen Schreibwunsch mitteilt, ein direkter serverseitiger Schreibzugriff ist dagegen nicht möglich.

Auslesen der SystemProperties

Auch vom lokalen Rechner erfährt ein Applet sehr wenig. Eine Applikation etwa kann mit Hilfe der statischen Methode getProperties() der Klasse System einiges über den lokalen Rechner erfahren. Von den rund 50 Einträgen in der Propertiestabelle darf ein Applet nur 9 (wenig informative) Einträge Auslesen. Schon der Aufruf der obigen Methode führt zu einer java.security.AccessControlException. Ein Applet kann lediglich die Methode getProperty(String propertyName) aufrufen. Das folgende Applet liest die neun möglichen Properties aus und versucht den Pfad der JavaUmgebung zu ermitteln, was nicht gelingt.

import java.awt.* ;
import java.applet.* ;

public class SystemPropertiesApplet extends Applet
{
   private TextArea tear = new TextArea() ;

   public void init()
   {
      setLayout( new BorderLayout() );
      tear.setEditable(false);
      add(tear, BorderLayout.CENTER);

      String prop;
      prop = System.getProperty("java.vendor");
      tear.append("java.vendor :   " +prop + "\n");

      prop = System.getProperty("java.vendor.url");
      tear.append("java.vendor.url :  " + prop + "\n");

      prop = System.getProperty("java.version");
      tear.append("java.version :  " + prop + "\n");

      prop = System.getProperty("java.class.version");
      tear.append("java.class.version :  " + prop + "\n");

      prop = System.getProperty("os.arch");
      tear.append("os.arch :  " + prop + "\n");

      prop = System.getProperty("os.name");
      tear.append("os.name :  " + prop + "\n");

      prop = System.getProperty("file.separator");
      tear.append("file.separator :  " + prop + "\n");

      prop = System.getProperty("path.separator");
      tear.append("path.separator :  " + prop + "\n");

      prop = System.getProperty("line.separator");
      if (prop.equals("\n") )
         tear.append("line.separator :  \\n \n");   // unix
      else if (prop.equals("\r\n") )
         tear.append("line.separator :  \\r\\n \n");  // windows
      else if (prop.equals("\r") )
         tear.append("line.separator :  \\r \n");  // mac
      else
         tear.append("line.separator :  kein standard line separator \n");

      try
      {
         prop = System.getProperty("java.home");
         tear.append(prop + "\n");
      }
      catch(java.security.AccessControlException ex)
      {
         tear.append(ex + "\n");
      }

   }

}  // end class

Das Applet kann z.Bsp. die folgende Ausgabe machen:

java.vendor :   Sun Microsystems Inc.
java.vendor.url :  http://java.sun.com/
java.version :  1.4.2
java.class.version :  48.0
os.arch :  x86
os.name :  Windows 2000
file.separator :  \
path.separator :  ;
line.separator :  \r\n
java.security.AccessControlException:
access denied (java.util.PropertyPermission java.home read)



Der AppletContext


Eine bessere Möglichkeit für ein Applet, etwas über die nähere Umgebung zu erfahren, ist das Interface AppletContext. Hier ein simples Applet, das nur den Namen der Klasse ausgibt, die dieses Interface implementiert.

import java.awt.*;
import java.applet.*;

public class AppletContextDemo extends Applet
{
   private Label label = new Label("", Label.CENTER);

   public void init()
   {
      setLayout( new BorderLayout());
      label.setBackground( new Color(220,230,240) );
      add(label);
      AppletContext ac = getAppletContext() ;
      label.setText(ac.getClass().getName() );
   }
} // end class

Ihr AppletContext

Wo ist diese Klasse versteckt ?

Falls der Appletviewer benützt wird, meldet sich als Kontext die Klasse "sun.applet.AppletViewer". Sie befindet sich im JavaArchiv "rt.jar" . rt.jar findet man auf WindowsSystemen unter einem Pfad analog zu "C:\Programme\Java\j2re1.4.2\lib" .
Falls der Browser ein plug-in benützt findet sich eine Implementierung dieser Klasse im JavaArchiv "plugin.jar", das z.B. bei Windowssystemen ebenfalls unter "C:\Programme\Java\j2re1.4.2\lib" zu finden ist.

Der AppletContext wird oft indirekt benützt. So stützen sich die Methoden getAudioClip(), getImage() und showStatus() aus der Klasse Applet auf den AppletContext, wie ein Blick in den Quelltext der Klasse Applet zeigt:

public void showStatus(String msg)
{
   getAppletContext().showStatus(msg);
}

public Image getImage(URL url)
{
   return getAppletContext().getImage(url);
}
public AudioClip getAudioClip(URL url)
{
   return getAppletContext().getAudioClip(url);
}

Eine weitere Situation, in der man den AppletContext braucht ist, wenn man aus dem Applet heraus zu einer anderen Webadresse weiterleiten will. dazu benötigt man die Methode showDocument(URL url) aus AppletContext, siehe hierzu das spätere Kapitel Eine andere website laden.

Der AppletContext wird auch gebraucht, wenn ein Applet herausfinden will, ob sich noch weitere Applets im gleichen HTML-File tummeln. Mit den Methoden getApplet() und getApplets() erfährt man von der Existenz evtl. weiterer Applets, siehe Kommunikation zwischen Applets.

Eine Application in eine Applet verwandeln


Natürlich gibt es kein starres Schema, aber einige allgemeine Regeln kann man doch aufstellen.


JApplets


Die Unterklasse JApplet hat keine neuen spezifischen Appletmethoden, und damit in dieser Beziehung keine zusätzlichen Fähigkeiten gegenüber der Klasse Applet. Der wesentliche Unterschied liegt im Design der Klasse. Wie die Swingklassen JDialog, JFrame, JInternalFrame und JWindow enthält ein JApplet einen RootPaneContainer, also ein Objekt vom Typ JRootPane. deswegen werden Komponenten nicht zum JApplet hinzugefügt, sondern zum ContentPane des RootPaneContainers, also

nicht :         jApplet.add(child)

sondern :   jApplet.getContentPane().add(child);


Außerdem ist zu beachten, daß das ContentPane per default ein BorderLayout besitzt. Da auch JFrame einen RootPaneContainer benützt, ist die Umwandlung einer JApplication in ein JApplet einfacher als die Umwandlung einer Application in ein Applet. Durch die Klassen ImageIcon und JLabel ergeben sich auch Vorteile beim Laden und Darstellen von Bildern, siehe Darstellen von Bildern.


Hybriden (Applet + Application in einem)


Es ist nicht schwer eine Applet zu konstruieren, das auch als Application läuft. Dabei werden zwei Eigenschaften konsequent genutzt. Erstens ist ein Applet ist ein (spezielles) Panel und zweitens wird die main()-Methode vom Browser ignoriert, es gibt also keine Fehlermeldung, falls sie doch vorhanden ist. Damit ergibt sich der folgende Aufbau:

import java.awt.*;
import java.applet.*;
import java.awt.event.*;

public class Hybrid extends Applet
{
   Label label = new Label("Ich bin ein Hybrid");

   public void init()
   {
      setBackground( new Color(220,230,240) );
      add(label);
   }

   public static void main(String args[])
   {
      Frame f = new Frame();
      Applet applet = new Hybrid1();
      applet.init();
      f.add(applet);
      f.setBounds(100,100,300,200);
      f.setTitle("The Applicationside of the Hybrid");
      f.addWindowListener( new WindowAdapter()
         {
            public void windowClosing(WindowEvent e)
            {
               System.exit(0);
            }
         }
      );
      f.setVisible(true);

   } // end main

} // end Hybrid class

Natürlich kann man die Initialisierungen in main() in eine eigene Methode legen, die muß dann aber statisch sein, wenn man sie aus main() heraus rufen will.

Hybridapplet


Für ein JApplet ist es noch einfacher, auch als JApplication zu erscheinen. Da sowohl JApplet als auch JFrame ein JRootpane verwenden ersetzt man einfach ein Contentpane durch ein anderes.

import java.awt.*;
import javax.swing.*;

public class JHybrid extends JApplet
{
   Container conPane = getContentPane();
   JLabel label = new JLabel("Ich bin ein JHybrid", SwingConstants.CENTER);

   public void init()
   {
      label.setForeground( new Color(210,0,0) );
      conPane.add(label);
   }

   public static void main(String args[])
   {
      JFrame f = new JFrame();
      JApplet applet = new JHybrid();
      applet.init();
      f.setContentPane(applet.getContentPane());
      f.setBounds(100,100,300,200);
      f.setTitle("The JApplicationside of the JHybrid");
      f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
      f.setVisible(true);
   } // end main

} // end JHybrid class

JHybridapplet



Zusammenfassung



Die Klasse Applet (Auszug aus der API)


Konstruktor
Applet()Wird vom Browser gerufen
Wichtige Methoden
ReturntypName der Methode
Lebenszyklus
void
 
init()
Called by the browser or applet viewer to inform this applet that it has been loaded into the system.
void
 
start()
Called by the browser or applet viewer to inform this applet that it should start its execution.
void
 
stop()
Called by the browser or applet viewer to inform this applet that it should stop its execution.
void
 
destroy()
Called by the browser or applet viewer to inform this applet that it is being reclaimed and that it should destroy any resources that it has allocated.
boolean
 
isActive()
Determines if this applet is active.
Information über Server und Client
AppletContext
 
getAppletContext()
Determines this applet's context, which allows the applet to query and affect the environment in which it runs.
URL
 
getCodeBase()
Gets the base URL.
URL
 
getDocumentBase()
Gets the URL of the document in which this applet is embedded.
Laden von Bildern und Sounds
AudioClip
 
getAudioClip(URL url)
Returns the AudioClip object specified by the URL argument.
AudioClip
 
getAudioClip(URL url, String name)
Returns the AudioClip object specified by the URL and name arguments.
static AudioClip
 
newAudioClip(URL url)
Get an audio clip from the given URL.
void
 
play(URL url)
Plays the audio clip at the specified absolute URL.
void
 
play(URL url, String name)
Plays the audio clip given the URL and a specifier that is relative to it.
Image
 
getImage(URL url)
Returns an Image object that can then be painted on the screen.
Image
 
getImage(URL url, String name)
Returns an Image object that can then be painted on the screen.
Information aus der HTML-Datei abholen, Zugriff auf die Statuszeile
String
 
getParameter(String name)
Returns the value of the named parameter in the HTML tag.
void
 
showStatus(String msg)
Requests that the argument string be displayed in the "status window".


Das Interface AppletContext (Auszug aus der API)


Wichtige Methoden
ReturntypName der Methode
Applet
 
getApplet(String name)
Finds and returns the applet in the document represented by this applet context with the given name.
Enumeration
 
getApplets()
Finds all the applets in the document represented by this applet context.
AudioClip
 
getAudioClip(URL url)
Creates an audio clip.
Image
 
getImage(URL url)
Returns an Image object that can then be painted on the screen.
void
 
showDocument(URL url)
Replaces the Web page currently being viewed with the given URL.
void
 
showDocument(URL url, String target)
Requests that the browser or applet viewer show the Web page indicated by the url argument.
void
 
showStatus(String status)
Requests that the argument string be displayed in the "status window".

top Back Next Up Home