7.4 | Applets mit Applikationen vereinigt
|
Generell ist es nicht erforderlich, Applets von Applikationen zu trennen.
Ein Applet kann gleichzeitig eine Applikation sein und umgekehrt.
Die Unterscheidung ist lediglich von den Methoden abhängig, die implementiert werden, und
von der Klasse, von der die Hauptklasse abgeleitet wird.
Wenn die Anforderungen eines Applets und einer
Applikation erfüllt sind, kann man das Programm sowohl in einem Browser als auch
von der Konsole aus starten.
Hierzu muss das Programm
Die Parameter, die ein
Applet von der HTML-Seite erhält, können bei einer Applikation
durch die Kommandozeile übergeben werden, um auch eine
einheitliche Schnittstelle des Programms nach außen zu definieren.
Der Parameterzugriff bei Applikationen erfolgt bei dieser Vorgehensweise
über den Parameter von main(), bei Applets hingegen über die Methode getParameter().
Folgendes Programm ist wohl eine der einfachsten Formen einer Applikation,
die auch als Applet gestartet werden kann:
import java.applet.Applet;
public class AppletApplicationDemo extends Applet {
// Aufruf beim Start als Applikation
public static void main(String args[]) {
// Zuerst wird eine Instanz der Klasse angelegt
// und anschließend der Name der Programm-Art ausgegeben.
AppletApplicationDemo universalprogram =
new AppletApplicationDemo();
universalprogram.whoamI("applicaton");
}
// Aufruf beim Start als Applet
public void init() {
// Hier ist ein direkter Aufruf von 'whoamI' möglich
whoamI("applet");
}
public void whoamI(String program){
// Ausgabe der Programm-Art
System.out.println("You've startet an "+program);
}
}
Startet man das Programm von der Konsole aus, wird in
main() ein Exemplar der Hauptklasse erzeugt. Der Verweis auf das Exemplar befindet sich innerhalb von main(). Somit kann über dieses Exemplar
auf die Methoden und Datenelemente der Klasse, in der sich main()
befindet, zugegriffen werden.
Ist das Exemplar erzeugt, wird whoamI()
mit dem Argument application aufgerufen. Dort wird der Text
auf der Standardausgabe angezeigt.
Der Umweg über das Exemplar ist notwendig,
um whoamI() nicht static definieren
zu müssen.
Beim Start als Applet ist der Ablauf analog. In diesem Fall muss jedoch nicht
erst ein Exemplar der eigenen Klasse angelegt werden, und
whoamI() wird der Text applet übergeben.
Auf diese Weise ist gewährleistet, dass man anhand des ausgegebenen Textes
immer sagen kann, wie das Programm gestartet wurde.
In diesem Fall übernimmt init() die
Rolle, die main() in einer Applikation besitzt.
Für ein Applet wird durch die Attribute WIDTH und
HEIGHT Platz auf der HTML-Seite reserviert, der
als Grundlage zum Informationsaustausch mit dem Benutzer dient.
In diesem Platz können entweder Grafiken angezeigt oder
eine grafische Benutzeroberfläche erzeugt werden.
Eine
Applikation besitzt diese Funktionalität nicht.
Um dennoch eine gemeinsame Schnittstelle zwischen einem
Applet und einer Applikation zu schaffen, die grafische
Elemente enthält,
kann man die zu zeichnenden oder
anzuzeigenden Elemente in einem Fenster darstellen, wenn
das Programm als Applikation gestartet wird.
Möchte man Anwendungen mit grafischen Oberflächen entwickeln,
die sowohl als Applet als auch als Applikation gestartet werden können,
sollte man zusätzlich ein paar Dinge beachten. Im Folgenden wird dem
Kapitel 8 etwas vorgegriffen und lediglich kurz
auf die Unterschiede zwischen Applets und Applikationen mit grafischer Oberfläche
eingegangen.
Beim Start der Anwendung als Applikation werden die Oberflächenelemente
in einem Frame untergebracht. Beim Start als Applet wird
die grafische Oberfläche direkt innerhalb des Applets im Browser
aufgebaut.
Folgendes Programm ist eine einfache Anwendung mit grafischer Oberfläche, die
sowohl als Applet als auch als Applikation ausgeführt werden kann:
import java.applet.Applet;
import java.awt.*;
public class AppletApplicationGUIDemo extends Applet {
// Aufruf beim Start als Applikation
public static void main(String args[]) {
Frame f = new Frame("An universal program");
// Hinzufügen des Panels zum Frame
f.add("Center",
new ComponentPanel("I'm an application"));
// Setzen der Größe und Anzeigen des Frames
f.setSize(300, 200);
f.show();
}
// Aufruf beim Start als Applet
public void init() {
// Festlegen der Größe
setSize(300, 200);
// Zufügen des Panels zum Applet
setLayout(new BorderLayout());
add("Center", new ComponentPanel("I'm an applet"));
}
}
class ComponentPanel extends Panel {
public ComponentPanel(String text) {
// Hinzufügen von zwei Komponenten zum Panel
setLayout(new BorderLayout());
add("Center", new TextArea());
add("South", new Label(text, Label.CENTER));
}
}
Das Besondere an diesem Programm ist,
dass die Komponenten, die die
Oberfläche bilden, nicht direkt dem Applet hinzugefügt werden, sondern
einer zweiten, von Panel abgeleiteten Komponente.
Wenn das Programm als Applet gestartet wird, ruft der
Interpreter zuerst init() auf. Dort wird ein
Exemplar des Panel mit
den eingebetteten Komponenten erzeugt und dem Applet hinzugefügt:
add("Center", new ComponentPanel("I'm an applet"));
Wird das Programm als Applikation gestartet, wird beim
Start main() aufgerufen. Da beim Start als Applikation noch
kein Container vorhanden ist, der Komponenten aufnehmen kann, muss dieser
zuerst angelegt werden.
In diesem Fall wird dazu ein Frame
verwendet. Danach kann man das Panel, das die Komponenten
enthält, dem Frame hinzufügen und anschließend mit
show() anzeigen.
Die oben definierte Klasse ComponentPanel wird gemeinsam von
Applet und Applikation benutzt. Sowohl beim Start als Applet als auch
beim Start als Applikation wird dieselbe grafische
Oberfläche angezeigt.
In diesem Beispiel ist das Panel
mit den gemeinsamen Komponenten relativ einfach gestaltet. Es enthält
lediglich eine leere TextArea und ein Label, das
signalisiert, ob das Programm als Applet oder als Applikation
gestartet wurde. Auf diese Weise kann man aber auch
komplexere Oberflächen variabel halten.
Abbildung 7.6: Eine grafische Oberfläche als Applet und Applikation kombiniert
 |  |
Material zum Beispiel
Wie
Abbildung 7.6 zeigt, muss man jedoch
die unterschiedlichen Größen bei Applets und Applikationen berücksichtigen.
Die Breite des Applets wurde mit 300 und die Höhe mit 200 Pixeln initialisiert.
Dasselbe gilt für den Frame, der die Komponenten beim Start als Applikation
aufnimmt.
Dennoch steht bei der Variante als
Applikation
weniger Platz auf der Oberfläche zur Verfügung. Das liegt daran,
dass der Rahmen des Frames in der initialisierten Größe enthalten
ist. Dadurch wird der Platz, der den Komponenten effektiv zur
Verfügung steht, verringert.
Neben dem Anzeigen der grafischen Oberfläche gibt es noch
weitere Unterschiede, zwischen einem Applet und einer
Applikation zu beachten, so z. B. beim Laden von Bildern oder
beim Zugriff auf Dateien.
Innerhalb eines Applets wird ein Bild über den Aufruf der Methode
getImage() geladen.
Bei einer Applikation kann diese Methode
nicht verwendet werden, da getImage() von der
Klasse Applet implementiert wird. Sie ruft die entsprechende
Methode des Interface AppletContext auf, das wiederum
vom Browser implementiert wird. Beim Start als Applikation ist
diese Implementierung somit nicht vorhanden.
Deshalb müssen Applikationen auf die getImage()-Methode
der Klasse Toolkit zurückgreifen.
Das wird in Abschnitt 7.3.2 beschrieben.
Um diese Unterschiede zwischen Applets und Applikationen
in einer Anwendung zu verbergen und ein universelles
Programm zu entwickeln, bietet es sich an, eine
Klasse zu erzeugen, die eine Schnittstelle für jene
Methoden enthält, die bei Applets und Applikationen
unterschiedlich sind.
Die Definition kann entweder mit Hilfe einer abstrakten
Klasse oder eines Java-Interface erfolgen.
Folgende Klasse definiert eine Schnittstelle für das Laden
von Bildern:
public class ProgramFactory {
public abstract Image getImage(String location);
}
Für ein Applet könnte die Implementierung dieses Interface
folgendermaßen aussehen:
public class AppletFactory extends ProgramFactory {
protected Applet applet;
public AppletFactory(Applet applet) {
this.applet = applet;
}
public Image getImage(String image) {
return applet.getImage(applet.getCodebase(),image);
}
}
Dasselbe Interface könnte man ebenfalls für eine
Applikation implementieren:
public class ApplicationFactory extends ProgramFactory {
public Image getImage(String image) {
return Toolkit.getDefaultToolkit().getImage(image);
}
}
Wird nun die Anwendung entweder als Applet oder als
Applikation gestartet, so muss jeweils das richtige
ProgramFactory-Objekt gesetzt werden. Dadurch, dass
beide Factory-Objekte über dieselbe Schnittstelle
verfügen, muss innerhalb des eigentlichen Programms
keine Unterscheidung zwischen dem Start als Applet
oder als Applikation getroffen werden:
Das Setzen des ImageFactory-Objekts erfolgt
jeweils in init() bzw. in main():
import java.applet.Applet;
import java.awt.*;
public class AppletApplicationGUIDemo extends Applet {
// Aufruf beim Start als Applikation
public static void main(String args[]) {
Frame f = new Frame("An universal program");
// Hinzufügen des Panels zum Frame
f.add("Center",
new ComponentPanel(new ApplicationFactory()));
// Setzen der Größe und Anzeigen des Frames
f.setSize(300, 200);
f.show();
}
// Aufruf beim Start als Applet
public void init() {
// Festlegen der Größse
setSize(300, 200);
// Hinzufügen des Panels zum Applet
setLayout(new BorderLayout());
add("Center",
new ComponentPanel(new AppletFactory(this)));
}
}
class ImagePanel extends Panel {
ImageFactory factory;
Image img;
public ComponentPanel(ProgramFactory factory) {
// Speichern des Factory-Objektes
this.factory = factory;
img = factory.getImage("test.gif");
}
public void paint(Graphics g) {
g.drawImage(img,0,0,this);
}
}
Es ist allerdings zu beachten, dass diese Technik nur funktioniert,
wenn das Bild immer relativ zur Hauptklasse des Applets definiert wird.
Sobald Bilder mit absolutem Pfad angegeben werden, ist der Zugriff
bei Applets wiederum anders als bei Applikationen.
Copyright © 2002 dpunkt.Verlag, Heidelberg. Alle Rechte vorbehalten.