Nachdem im vorherigen Unterkapitel die Introspektion erklärt wurde, wird in diesem Teil des Kapitels erläutert, wie das Verhalten und das Aussehen eines Beans zur Designzeit, d. h. innerhalb einer Entwicklungsumgebung, angepasst werden kann. Die JavaBeans-Technologie beinhaltet zwei Möglichkeiten, um die Anpassung der Komponenten innerhalb einer Entwicklungsumgebung mit minimalem Aufwand betreiben zu können: Verwendung eines Property-Editors Jede Eigenschaft eines Beans verfügt über einen eigenen Property-Editor, mit dem Eigenschaften angepasst werden können. Eine Entwicklungsumgebung stellt eine Eigenschaft eines Beans in einem sog. Property Sheet dar. Jeder Property-Editor ist mit einer bestimmten Eigenschaft assoziiert. Verwendung eines Customizers Mit einem Customizer kann das gesamte Bean in einem Schritt editiert werden. Im Gegensatz zum Property-Editor ist ein Customizer nicht mit einer bestimmten Eigenschaft, sondern mit dem gesamten Bean assoziiert. Property-Editor Property-Editoren sind Werkzeuge zur visuellen Manipulation von Eigenschaften. Sie unterstützen den Anwender bei der Konfiguration der Eigenschaften einer JavaBeans-Komponente. JavaBeans bieten Property-Editoren lediglich für die Eingabe der vorab definierten Datentypen (bspw. int, boolean oder Color) an. Abb. 9.13: Property-Editor für den Datentyp Color Wird ein Datentyp verwendet, für den kein Property-Editor existiert, wie bspw. für den Datentyp Date, so muss der Programmierer dafür sorgen, dass die visuelle Manipulierbarkeit dieses Datentyps unterstützt wird, dass also ein eigener Property-Editor angeboten wird. Ein Property-Editor kann entweder allgemein definiert werden, so dass Java für jede Eigenschaft dieser Art automatisch diesen Editor-Typ wählt, oder speziell für eine einzige Eigenschaft. Im zweiten Fall muss der Property-Editor mit Hilfe der Klasse BeanInfo mit der Eigenschaft assoziiert werden. Zur allgemeinen Definition muss der Property-Editor den folgenden Namen verwenden: <Datentyp>Editor, Im oben angesprochenen Beispiel ist der Name folglich DateEditor. Die Manipulation einer Eigenschaft findet immer im Kontext eines Beans statt. Somit beinhaltet das Editieren eines Beans den Umgang mit einer Gruppe von Property-Editoren, da ein Bean in der Regel mehrere Eigenschaften enthält. Das Editieren eines vollständigen Beans erfolgt, indem das Property Sheet verwendet wird. Ein Property Sheet enthält eine Auswahl verschiedener Property-Editoren für die spezifischen Eigenschaften eines Beans. Die Bindung eines Property-Editors an eine bestimmte Eigenschaft kann auf verschiedene Art und Weise erfolgen: Explizite Assoziation Die explizite Assoziation wird durch die explizite Angabe des Namens eines Property-Editors in der BeanInfo-Klasse realisiert: myPropertyDescriptor.setPropertyEditorClass (KlassenNameEditor.class); Explizite Registrierung Die explizite Registrierung wird durch die Methode java.Beans.PropertyEditorManager.registerEditor realisiert, die die folgenden zwei Argumente erwartet: Die Klasse des Datentyps, der editiert werden soll, und die Editor-Klasse, die mit diesem Typ verbunden ist. Implizite Suche nach dem Property-Editor Wird für einen Datentyp keine explizite Angabe des assoziierten Property-Editors vorgenommen, so sucht die Komponente PropertyEditorManager nach einem geeigneten Property-Editor für diesen Datentyp. Dies erfolgt, indem das Wort Editor zum gesamten Klassennamen hinzugefügt wird. So würde bspw. für die Klasse java.beans.Date der Property-Editor-Manager nach der Klasse java.beans.DateEditor suchen. Customizer Bei Komponenten größeren Umfangs kann es sinnvoll sein, die Eigenschaften in einer bestimmten Form zu gliedern, um zusammengehörige Eigenschaften auch im Dialogfenster zusammenhängend darzustellen. In diesem Fall definiert der Entwickler eine eigene Customizer-Klasse. Soll das JavaBean durch einen eigenen Customizer konfiguriert werden, so muss eine geeignete Beschreibung in der BeanInfo-Klasse erfolgen. Hierzu wird dem BeanDescriptor-Objekt zur Initialisierungszeit ein Customizer-Objekt übergeben. Die Entwicklungsumgebung fragt anschließend spätestens bei der Instantiierung eines JavaBeans das BeanDescriptor-Objekt nach dem jeweiligen Customizer-Objekt. Ist dieses vorhanden, so wird der Customizer anstelle des Standarddialogs angezeigt. Customizer werden vor allem dann benötigt, wenn die Property-Editoren nicht ausreichen, um ein Bean geeignet anzupassen. Jeder Customizer muss die folgenden Eigenschaften aufweisen: Direkte oder indirekte Ableitung von der Klasse java.awt.Component, damit er innerhalb eines java.awt.Dialog-Objekts oder innerhalb eines java.awt.panel-Objekts instantiiert werden kann. Implementierung des Interfaces java.beans.Customizer. Hierdurch erfolgt die Implementierung von Methoden zur Registrierung von PropertyChangeListener-Objekten und zur Generierung von PropertyChange-Events, wenn eine Änderung einer Eigenschaft stattfindet. Verwendung eines Null-Konstruktors. Customizer werden von Beans-Entwicklern entworfen und implementiert. JavaBeans stellt zwar ein Interface zur Verfügung, das jedes Customizer-Objekt implementieren muss, aber keine weitere Implementierungsunterstützung. Hierdurch kann die Entwicklung eines Customizers sehr aufwendig sein. API-Unterstützung Im Folgenden werden die Klassen und Interfaces beschrieben, die die Anpassung eines Beans unterstützen. Interface PropertyEditor Durch dieses Interface werden Editoren für einzelne Eigenschaften eines gegebenen Datentyps definiert. Da die JavaBeans-Technologie Property-Editoren für vorab definierte Datentypen bereits zur Verfügung stellt, werden Property-Editoren nur für selbst definierte Datentypen, wie bspw. für komplexe Zahlen, entwickelt. Klasse PropertyEditorSupport Die Klasse ProperyEditorSupport ist eine Hilfsklasse, die das Interface PropertyEditor implementiert. Diese Klasse erleichtert vor allem die Programmierung eines selbst definierten Property-Editors. Diese Klasse enthält die folgenden Methoden: addPropertyChangeListener(PropertyChangeListener) und removePropertyChangeListener(PropertyChangeListener) Diese Methoden werden zum Hinzufügen bzw. Löschen eines PropertyChangeListener-Objektes zu bzw. aus der Liste der EventListener-Objekte verwendet. Ein PropertyChange-Event wird dann ausgelöst, wenn der Wert einer Eigenschaft verändert wird. firePropertyChange() Meldet registrierten Listenern eine Änderung. getAsText() und setAsText(String) Liefert bzw. setzt den Wert einer Eigenschaft auf den Datentyp String, damit der Wert gelesen werden kann. getCustomEditor() Erzeugt ein java.awt.Component-Objekt, um den Wert einer Eigenschaft editieren zu können. supportsCustomEditor() Liefert dann den Wert true, wenn ein Property-Editor zur Verfügung steht. getJavaInitializationString() Gibt den Java-Code zurück, der den Anfangswert der Eigenschaft darstellt. Ein Beispiel für eine Eigenschaft des Datentyps Color wären die folgenden Anweisungen: new Color(255,0,0) oder Color.red. getValue() und setValue(Object) Erfragt bzw. setzt den Wert einer geänderten Eigenschaft. isPaintable() Liefert dann den Wert True, falls die Methode paintValue() anwendbar ist. paintValue(Graphics, Rectangle) Generiert eine grafische Repräsentation des Werts einer Eigenschaft innerhalb eines Rechtecks. Klasse PropertyEditorManager Diese Klasse wird verwendet, um den Property-Editor für eine Eigenschaft eines bestimmten Datentyps zu lokalisieren. Durch diese Klasse können Eigenschaftstypen registriert werden, um entsprechende Editoren finden zu können. Ist der Eigenschaftstyp nicht registriert, so sucht ein PropertyEditorManager-Objekt nach einem Property-Editor, dessen Namen sich aus dem Namen der Eigenschaft, gefolgt von dem Wort Editor, zusammensetzt. Die Klasse beinhaltet die folgenden Methoden: findEditor(Datenype) Sucht nach einem Property-Editor für einen bestimmten Datentyp und gibt ihn zurück. registerEditor(DatenTyp, Editor) Registriert eine Editor-Klasse für den angegebenen Datentyp. getEditorSearchPath() Gibt eine Liste von Package-Namen zurück, die untersucht werden müssen, um Property-Editoren zu finden. Der Anfangswert lautet bspw. sun.beans.editors. setEditorSearchPath(String[]) Setzt die Liste der Package-Namen, die untersucht werden müssen, um Property- Editoren zu finden. Interface Customizer Dieses Interface stellt ein GUI zur Verfügung, mit dessen Hilfe eine JavaBeans-Komponente angepasst werden kann. Die folgenden Methoden werden durch dieses Interface bereitgestellt: setObject (meinBean) Setzt das Bean-Objekt, das angepasst werden muss. addPropertyChangeListener(PropertyChangeListener) und removePropertyChangeListener(PropertyChangeListener) Diese Methoden werden zum Hinzufügen bzw. Löschen eines PropertyChangeListener-Objekts zu bzw. aus der Liste der EventListener-Objekte verwendet. Der Customizer erzeugt einen PropertyChange-Event, wenn eine Änderung einer Eigenschaft innerhalb eines Beans stattfindet. Zusammenfassung In diesem Unterkapitel wurde die Anpassung von JavaBeans-Komponenten erläutert, d. h. deren Unterstützung für Entwicklungsumgebungen erläutert. Grundsätzlich existieren zwei Möglichkeiten, um Entwicklungsumgebungen zu unterstützen. Der einfache Weg besteht in der Implementierung eines Property-Editors. Die Entwicklung eines Customizers stellt zwar bezüglich der Adaptivität eines Beans innerhalb einer Entwicklungsumgebung eine umfangreichere Lösung dar, erfordert aber eine aufwendige Programmierung. Es sei hier nochmals darauf hingewiesen, dass für vorab definierte Datentypen, wie bspw. int, float oder Color, kein Property-Editor implementiert werden muss, da in Java für diese Datentypen standardmäßig Property- Editoren zur Verfügung stehen.