Titel | Inhalt | Suchen | Index | DOC | Handbuch der Java-Programmierung, 3. Auflage |
<< | < | > | >> | API | Kapitel 44 - Beans |
Zur Unterstützung beim Entwurf und Testen von Beans und als Referenzplattform für die Demonstration des Bean-Konzepts wurde von SUN das Bean Development Kit (kurz BDK) entwickelt. Es wird frei zur Verfügung gestellt und kann beispielsweise über die Java Beans Homepage von http://java.sun.com/beans/index.html heruntergeladen werden. Während der Erstellung dieses Kapitels wurde die Version 1.1 verwendet. Wichtigster Bestandteil des BDK ist die Beanbox, die eine einfache Umgebung zum Testen von selbstentwickelten Beans zur Verfügung stellt. Bevor wir uns ihrer Bedienung zuwenden, soll die Installation des BDK beschrieben werden.
Die Beanbox sollte nicht als vollwertige Test- und Entwicklungsumgebung für Java-Beans betrachtet werden. Dazu ist sie zu schwach. Sie wurde lediglich entwickelt, um die Bean-Konzepte zu illustrieren und eine erste Möglichkeit für ihre Anwendung zur Verfügung zu stellen. Bei weitergehendem Einsatz stößt man schnell an die Grenzen der Beanbox, und ihr praktischer Nutzen ist recht begrenzt. |
|
Die Installation des BDK ist einfach; Voraussetzung ist ein funktionierendes JDK. Unter Windows gibt es ein menügesteuertes Installationsprogramm "bdk1_1-win.exe", das die meisten Schritte übernimmt. Nachdem es gestartet wurde, müssen zunächst die Lizenzbedingungen akzeptiert werden, dann ist die Eingabe des Installationsverzeichnisses erforderlich. Sind mehrere Java-Interpreter vorhanden, muß anschließend ausgewählt werden, welcher von ihnen zum Betrieb des BDK verwendet werden soll. Nach Drücken des "Install"-Buttons wird dann mit der Installation begonnen. Die Installationsroutine legt auch einen Uninstall-Eintrag an, mit dem das BDK bei Bedarf deinstalliert werden kann.
Nach der Installation befindet sich eine Datei run.bat
im Unterverzeichnis beanbox
des BDK-Verzeichnisses (analog dazu gibt es das Shell-Script run.sh
zum Starten der Beanbox auf UNIX-Systemen). Diese Batchdatei setzt
den CLASSPATH auf die benötigten
Klassen- und .jar-Dateien und startet
die Beanbox. Sie ist leider etwas archaisch. Einerseits wird der aktuelle
CLASSPATH überschrieben.
Zudem war sie im Test mitunter instabil, wenn der HotSpot-Compiler
aktiviert war. Eine modifizierte Version von run.bat
könnte etwa so aussehen (analoge Anpassungen können für
die UNIX-Version vorgenommen werden):
@echo off
set OLDCP=%CLASSPATH%
echo saving old CLASSPATH in OLDCP: %OLDCP%
set CLASSPATH=classes;..\lib\methodtracer.jar;..\infobus.jar
java -classic sun.beanbox.BeanBoxFrame
set CLASSPATH=%OLDCP%
set OLDCP=
echo CLASSPATH restored to %CLASSPATH%
Nach dem Aufruf des Startscripts run wird die Beanbox gestartet und präsentiert ihre aus vier Top-Level-Frames bestehende Arbeitsoberfläche:
Abbildung 44.2: Die Beanbox
Um eine Bean zu bearbeiten, muß sie zunächst im GUI-Designer plaziert werden. Dazu ist sie in der Toolbox anzuklicken und mit einem erneuten Klick im GUI-Designer zu plazieren. Der schraffierte Rand zeigt an, daß sie ausgewählt wurde und ihre Eigenschaften im Property-Editor modifiziert werden können. Durch Ziehen an einem der vier Ränder kann die Bean beliebig verschoben werden. Ist ihre Größe variabel, kann sie durch Ziehen an einer der vier Ecken verändert werden. Soll eine Bean aus dem GUI-Designer entfernt werden, ist sie zu markieren und mit dem Menüpunkt "Edit.Cut" zu löschen.
Beachten Sie bitte, daß das Verschieben der Bean und das Ändern ihrer Größe ausschließlich durch Mausklicks auf ihrem Rand ausgeführt wird. Mausoperationen im Inneren der Bean werden als reguläre Ereignisse gewertet und direkt an das zu diesem Zeitpunkt bereits instanzierte Bean-Objekt weitergeleitet. |
|
Als Beispiel wollen wir die vordefinierte Bean "OrangeButton" im GUI-Designer plazieren. Sie stellt sich zunächst als oranges Rechteck dar, das nach einem Mausklick kurz die Farbe wechselt. Im Property-Editor können die öffentlichen Eigenschaften der Bean verändert werden:
Die Beanbox bietet die Möglichkeit, eine Bean über die von ihr generierten Events mit einer anderen Bean zu verbinden. Um das beispielhaft zu demonstrieren, soll zusätzlich eine Instanz der Bean vom Typ "EventMonitor" im GUI-Designer plaziert werden. Dann klicken wir den Button an und rufen den Menüpunkt "edit.Events.buttonPushed.actionPerformed" auf. Wenn die Maus nun den Button verläßt, bleibt sie über eine rote Linie mit dem Button verbunden. Wir ziehen diese Linie auf den "EventMonitor" und führen einen weiteren Mausklick aus. In der nun angezeigten Liste aufrufbarer Methoden wählen wir den (einzigen) Eintrag initiateEventSourceMonitoring aus.
Die Beanbox generiert nun Java-Code für eine Adapterklasse, kompiliert ihn und legt die resultierenden Dateien im Unterverzeichnis tmp\sunw\beanbox ab. Gleichzeitig registriert sie die Adapterklasse für das Action-Ereignis des Buttons und sorgt durch den Aufruf der ausgewählten Methode innerhalb von actionPerformed dafür, daß der Event-Listener bei jedem Buttonklick benachrichtigt wird. Seine Aufgabe besteht darin, die ausgelösten Ereignisse zu speichern und in einer Listbox auf dem Bildschirm anzuzeigen.
Auf diese Weise lassen sich prinzipiell beliebige Beans miteinander verbinden. Die Einschränkung der Beanbox besteht lediglich darin, daß sie nur Adapterklassen für den Aufruf von parameterlosen Methoden erzeugen kann. Fortgeschrittenere GUI-Designer würden es erlauben, auch parametrisierte Methoden aufzurufen. Sie würden zusätzlich einen Editor zur Verfügung stellen, mit dem der erzeugte Code per Hand angepaßt werden kann. |
|
Neben den vordefinierten können auch eigene Beans in die Beanbox integriert werden. Sie können dann wie vordefinierte verwendet, manipuliert und serialisiert werden. Im folgenden wollen wir beschreiben, welche Schritte nötig sind, um eine Bean in der Beanbox verwendbar zu machen. Für die Einbindung in eigene GUI-Designer kann eventuell eine etwas andere Vorgehensweise erforderlich sein. Dazu sollte die Bean-Dokumentation des jeweiligen Entwicklungssystems konsultiert werden.
Die ersten beiden Schritte, das Entwickeln und Übersetzen der Bean, haben wird schon erledigt. Sie unterscheiden sich in keiner Weise von der einer herkömmlichen Java-Klasse. Als Ergebnis ensteht eine Klasse LightBulb.class mit dem Bytecode der Glühlampen-Bean.
Um bei GUI-Designern mit einer großen Anzahl unterschiedlicher Beans ein schwer zu durchschauendes Sammelsurium kleiner Klassendateien zu vermeiden, werden Beans in jar-Archive verpackt und so an den GUI-Designer übergeben. Eine jar-Datei darf beliebig viele Beans enthalten. Um dem GUI-Designer die Möglichkeit zu geben, Klassen für Beans von solchen mit reinen Hilfsfunktionen zu unterscheiden, wird dem jar-Archiv eine Manifest-Datei hinzugefügt, die ihren Inhalt beschreibt. Es handelt sich um eine normale Textdatei, die für jede enthaltene Bean einen Eintrag der folgenden Form enthält:
Name: BeanClassFile.class Java-Bean: True |
Der erste Eintrag gibt den Klassennamen an. Der zweite besagt, daß
es sich um eine Bean handelt (Manifest-Dateien können auch noch
andere Informationen über die im Archiv gespeicherten Dateien
enthalten). Die Informationen werden zweckmäßigerweise
in eine Textdatei manifest.txt geschrieben
und beim Erzeugen der jar-Datei mit der Option "m" eingebunden. Zum
Einbinden der Glühlampe muß diese Datei also folgenden
Inhalt haben:
Name: LightBulb.class
Java-Bean: True
Nun kann das Kommando zum Erzeugen der jar-Datei abgesetzt werden
(wir wollen sie hjp3beans.jar nennen):
jar cfm hjp3beans.jar manifest.txt LightBulb.class bulb*.gif
Die Option "c" steht für "create" und besagt, daß eine neue jar-Datei angelegt werden soll. Das "f" steht für "file" und gibt an, daß als erstes Argument hinter den Kommandobuchstaben der Name der jar-Datei steht. Das "m" steht für "manifest" und besagt, daß als nächstes Argument der Name der Manifest-Datei folgt. Ganz zum Schluß stehen die Namen der einzubindenden Dateien. In diesem Fall sind das die Klassendatei und die zur Darstellung benötigten gif-Dateien bulb1.gif und bulb2.gif.
Die jar-Datei muß nun in das Unterverzeichnis jars des BDK-Installationsverzeichnisses kopiert werden. Beim nächsten Start der Beanbox wird sie automatisch gefunden, analysiert, und die darin enthaltenen Beans werden im GUI-Designer zur Verfügung gestellt.
Unsere Glühlampe wird nun in der Toolbox angezeigt und kann wie jede andere Bean in den GUI-Designer übernommen werden. Im Eigenschaftenfenster werden ihre Eigenschaften angezeigt und können interaktiv verändert werden. Wird beispielsweise die Eigenschaft lightOn von false auf true gesetzt, ändert die Bean ihren Zustand und die Glühlampe leuchtet auf (siehe Abbildung 44.3). Auch auf das Verändern der ererbten Eigenschaften (z.B. der Hintergrundfarbe) reagiert unsere neue Komponente erwartungsgemäß mit einer entsprechenden Änderung der graphischen Darstellung.
Abbildung 44.3: Die Glühlampe in der BeanBox
Die Definition der Klasse LightBulb in Listing 44.3 enthält eine Methode toggleLight, mit der der Zustand der Lampe umgeschaltet werden kann. Da ihr Name nicht den Design-Konventionen für getter- und setter-Methoden entspricht, ist sie im GUI-Designer der Beanbox nicht sichtbar. In Abschnitt 44.6 werden wir erläutern, wie man sie mit Hilfe einer BeanInfo-Klasse dennoch sichtbar machen kann. |
|
Im vorigen Abschnitt wurde erwähnt, daß Beans serialisierbar sein müssen. Dadurch ist ein GUI-Designer in der Lage, eine zum Designzeitpunkt konfigurierte Bean dauerhaft zu speichern und sie anderen Programmen vorkonfiguriert zur Verfügung zu stellen.
Auch die Beanbox bietet eine einfache Möglichkeit, Beans zu serialisieren und auf der Festplatte zu speichern. Dazu ist die gewünschte Bean im GUI-Designer zu markieren und der Menüpunkt "File.SerializeComponent" aufzurufen. Nun ist ein Dateiname anzugeben, unter dem die konfigurierte Bean gespeichert werden soll.
Im folgenden wollen wir annehmen, daß die Glühlampen-Bean in der Beanbox so konfiguriert wurde, daß das Licht angeschaltet ist und sie unter dem Namen "lb1.ser" persistent gespeichert wurde.
Soll eine serialisierte und damit vorkonfigurierte Bean in einem Programm verwendet werden, muß sie vor dem Einbinden deserialisiert werden. Dazu wird ein ObjectInputStream verwendet, der die Bean mit Hilfe eines FileInputStream aus ihrer Datei liest. Anschließend kann das deserialisierte Objekt durch Aufruf von add in gewohnter Weise in den Dialog eingebunden werden:
001 /* Listing4405.java */ 002 003 import java.awt.*; 004 import java.awt.event.*; 005 import java.io.*; 006 007 public class Listing4405 008 extends Frame 009 { 010 public Listing4405() 011 { 012 super("LighBulbTest"); 013 setLayout(new FlowLayout()); 014 setBackground(Color.gray); 015 addWindowListener( 016 new WindowAdapter() { 017 public void windowClosing(WindowEvent event) 018 { 019 System.exit(0); 020 } 021 } 022 ); 023 loadLightBulb(); 024 } 025 026 private void loadLightBulb() 027 { 028 try { 029 ObjectInputStream is = new ObjectInputStream( 030 new FileInputStream("lb1.ser")); 031 LightBulb bulb = (LightBulb)is.readObject(); 032 is.close(); 033 add(bulb); 034 } catch (ClassNotFoundException e) { 035 System.err.println(e.toString()); 036 } catch (IOException e) { 037 System.err.println(e.toString()); 038 } 039 } 040 041 public static void main(String[] args) 042 { 043 Listing4405 frm = new Listing4405(); 044 frm.setLocation(100, 100); 045 frm.pack(); 046 frm.setVisible(true); 047 } 048 } |
Listing4405.java |
Wird das Programm gestartet, lädt es die Bean und zeigt sie mit angeschaltetem Licht:
Abbildung 44.4: Die deserialisierte Glühlampen-Bean
Titel | Inhalt | Suchen | Index | DOC | Handbuch der Java-Programmierung, 3. Auflage, Addison Wesley, Version 3.0.1 |
<< | < | > | >> | API | © 1998-2003 Guido Krüger, http://www.javabuch.de |