Lade Inhalt...

Komponenten Konzept von Java, Java-Beans

Ausarbeitung 2001 23 Seiten

Informatik - Software

Leseprobe

Inhaltsverzeichnis

1 Einleitung

2 Java Beans

3 Was macht Java Beans aus?
3.1 Eventhandling
3.2 Properties
3.2.1 Zugriff auf Eigenschaften
3.2.2 Indexed properties
3.2.3 Bound properties
3.2.4 Constrained properties
3.3 Introspection
3.3.1 Reflecion
3.3.2 Beanlnfo Schnittstelle
3.4 Customization
3.4.1 Property Editor
3.4.2 Customizer
3.5 Persistence
3.5.1 Serialization
3.5.2 Versionsproblematik und Kompatibilítaet
3.5.3 Externalization
3.5.4 Instanzierung von Serialisierten Beans
3.6 Packaging
3.6.1 Das Manifest
3.6.2 Erzeugen eines JAR Archives

A Appendix
A.l Beans Development Kit
A.2 Programmbeispiele
A.2.1 Gebundene Eigenschaften:
A.2.2 Eingeschraenkte Eigenschaften: Thermometer.java,
Constrainer.java, Terra.java
A.2.3 Serialisierung
A.2.4 Eigenschaftseditoren

1 Einleitung

Dieses Papier ist Grundlage fuer eine Praesentation im Zuge eines Seminars bei Herrn Prof. Schmidt an der Fachhochschule Wedel[1]. Die Aufgabe besteht darin eine Einfuehrung in Java-Beans zu geben und es mit Hilfe von Beispielen zu erlaeutern. Bei Fragen oder Anregungen wenden sie sich gerne an mich. Wenn sie dieses Dokument in einem anderen Format benoetigen - mail genuegt.

2 Java Beans

Das JavaBeans Application Programming Interface (API) ermoeglicht es Kom­ponenten Software in Java zu implementieren. Komponenten sind selbstenthal­tene, wiederverwendbare Softwareeinheiten die visuell als Komponenten zusam­mengesetzt werden koennen. So koennen dann neue Komponenten, Applets, Programme oder auch Servlets in visuellen Programmierwerkzeugen enstehen. JavaBean Komponenten werden kurz als Beans bezeichnet.

Beans bzw. Kompoenenten im weiteren Sinne bieten ihre Funktionalitaet, z.B. Methoden und Ereignisse, Programmierwerkzeugen (Builder) fuer die vi­suelle manipulation an. Die Funktionalitaet eines Beans wird anhand von be­stimmten Entwurfsmustern (patterns) erkannt die auf Namenskonventionen be­ruhen. Jeder Programmiererwerkzeug ist damit in der Lage jene Muster zu erkennen und kann das Bean dann mit der kompletten oeffentlichen Funkio- nalitaet fuer die visuelle Bearbeitung dem Entwickler zur Verfuegung stellen. So ein Builder kann das Bean dann in seine Palette bzw. in die Toolbox auf­nehmen. Das heisst jedoch nicht, das jedes Bean eine visuelle Repraesentation haben muss. Anschliesend steht das Bean dann dem Programmierer als Kompo­nente zur Verfuegung. Der Vorteil liegt darin, dass ueber die Standardisierung der Schnittstellen, jedes beliebige JavaBeans-Werkzeug mit einem Bean umge­hen kann, und ein Entwickler wiederum dieses Bean in seine Softwareprodukte einsetzen kann, ohne im Idealfall eine Zeile Code zu schreiben. Das Bedeu­tet vor allem hohe Entwicklungsgeschwindigkeit, hohe Wiederverwendbarkeit, einfachere Wartbarkeit der erzeugten Software.

Beans sind einfach zu erstellen und somit klein - sogenannte: lightweight Komponenten, dass heisst es ist nicht noetig diverse vererbte Ladungen “herum­zuschleppen” (Engländer 1997, p6). Das bedeutet ein Bean muss nicht alle nur erdenklichen Funktionen erstmal implementieren um zu einem Bean zu werden. Ein Bean ist somit Grundsaetzlich einfach und laesst sich dann hinreichend komplex gestalten, anders als bei anderen Modellen in denen Grundsaetzlich eine gewissse Komplexitaet implementiert werden muss, um ueberhaupt eine Komponente darzustellen.

3 Was macht Java Beans aus?

In diesem Kapitel wird auf die einzelnen Konzepte von Java Beans eingegangen. Grundsaetzlich soll hier noch angemerkt sein ,dass Beans nur reines Java nut­zen und keine neuen Mechanismen gebraucht werden, um Beans zu registrieren oder aehnliches. Jenes f'uert dazu das Beans alle Vorteile und Nachteile von Java unterliegen, d.h. z.B. Portabilitaet, was fuer wiederverwendbare Software sicher eine Entscheidene Rolle spielen sollte, ist mit Java als Sprache implizit vorhanden, das gleiche gilt auch fuer alle anderen Konzepte von Java, wie z.B. Sicherheit und Robustheit.

Im folgenden werden nun Grundlegende Prinzipien von Beans weiter be­leuchtet. Das sind im einzelnen: Properties, Introspection, Customization und Persistence, abschliessend geht es dann um das Packaging welches das Bean in eine Form bring welches sich zur Weitergabe eignet. Ein Java Konzept sei an dieser Stelle noch eingefuegt: die Ereignisbehandlung. Damit Instanzen mitein­ander kommunizieren koennen, wird das Event-Modell von Java eingesetzt. An dieser Stelle wird nur kurz und grob auf das Event modeli eingegangen. Grund­saetzlich ist zu sagen, dass Beans starken Gebrauch von dem Konzept machen, was primaer daran liegt, das es sich im visuelle Komponenten handelt, die im Allgemeinen mit Events gekoppelt werden.

3.1 Eventhandling

Ein Ereignis (Event) zeichnet sich dadurch aus, dass es auftret en kann aber nicht muss. Events werden von der Klasse java.util.EventObject abgeleitet. Dieses Ereignis Instanzen enthalten dann alle fuer das Event wichtige Informationen, wie z.B. im Falle eines Mausevents, die alktuelle Maus Koordinaten. Moechte ein Bean oder jeden andere Objekt von einen Event kenntnis erlangen muss es sich bei der Eventquelle mit einen sogenannten Listener registrieren. Die Quelle pflegt also einen Zuhoererstamm. Tritt nun ein bestimmtes Event ein wird das Objekt alle entsprechenden Zuhoerer davon mit auf'ruf einer Methode in Kenntnissetzen. Das genau diese Methoden jedoch von den Zuhoerern innerhalb des Listener zur Verfuegung steht, ist es dem Zuhoerer moeglich individuell auf das Event zu reagieren und es ggf. auch ignorieren.

3.2 Properties

Eigenschaften (properties) sind im weiteren Sinne benannte Attribute oder Cha­rakteristika von modellierten Realobjekten. Sie definieren den Zustand oder das Verhalten eines Objektes oder hier Beans. Eigenschaften werden über ihren Na­men referenziert und können von einem beliebigen Datentyp sein (z.B. int, class, interface). Im normalfall gehören die Eigenschaften zu dem Persi­stenten Teil eines Objektes (siehe 3.5). Eigenschaften können im Bean Konzept mit Hilfe von visuellen Editoren manipuliert werden.

3.2.1 Zugriff auf Eigenschaften

Eigenschaften werden mit Hilfe von Zugriffniethoden gelesen und geschrieben. Prinzipiell sind nur Lesen, nur Schreiben und Lesen/Schreiben Eigenschaften denkbar. Die Methoden, die das Lesen bzw. Schreiben realisieren sollten ei­nem Standart design für Eigenschaften folgen. Sie können demnach auch zu prüfende Ausnahmen (checked exceptions) auslösen. Standart Signaturen für Zugriffsniethoden sehen wie folgt aus.

public void set<PropertyName>(<PropertyType> value); public <PropertyType> get<PropertyName>();

Für nur Lesen oder nur Schreiben würde man demnach einfach die entspre­chende Methode weglassen bzw. sie nicht veröffentlichen. Im Sonderf'all von Boolschen Eigenschaften ist die folgende Verkürzung denkbar.

public boolean is<PropertyName>();

3.2.2 Indexed properties

Bisher wurde mit einer Eigenschaft immer genau ein Wert abgehandelt. Nun ist es jedoch oft wünschenswert mehrere Werte zusammen behandeln zu kön­nen ohne diverse Namen vergeben zu müssen. Die indizierten Eigenschaften (indexed properties) ermöglichen genau dies. Über einen Namen angesprochene Eigenschaften werden so, ähnlich wie bei Arrays, indiziert angesprochen. Um nun sowohl auf einzelne Werte als auch auf die gesamte geordnete Sammlung zugreifen zu können werden die folgenden Methoden benötigt:

public void set<PropertyName>(<PropertyType>[] value);

public <PropertyType> [] get<PropertyName>();

public void set<PropertyName>(int index, <PropertyType> value);

public <PropertyType> get<PropertyName>(int index);

An dieser Stelle macht es häufig Sinn eine throws Klau­sel für den indizierten Zugriff zu definieren um ggf. eine java.lang.ArraylndexOutOfBoundsException Ausnahme zu erzeugen.

3.2.3 Bound properties

Gebundene Eigenschaften (bound properties) sind Eigenschaften die eine Art Benachrichtigungsdienst für etwaige Änderungen der Eigenschaft implementie­ren. Es ist somit möglich andere Komponenten bzw. Objekte bei Änderung eines Wertes zu benachrichtigen. Die “interessierten” Komponenten müssen sich zu diesem Zweck registrieren. Dazu bedient man sich dem Listener Konzept von Java (siehe 3.1). Das Bean, welches gebundene Eigenschaften zur Verfü­gung stellt, muß somit Methoden für die Registrierung zur Verfügung stellen.

Zu diesem Zweck sind einige Schnittstellen und Implementierungen zusaetzlich im Bean Konzept aufgenommen worden und sind im Einzelnen:

public void addPropertyChangeListener(PropertyChangeListener p);

public void removePropertyChangeListener(PropertyChangeListener p);

Die Methode propertyChangeO muss dann vom java, beans. PropertyChangeListener implementiert werden, welche dann mit Hilfe eines java.beans.PropertyChangeEvent das Event bearbeiten kann. Genau diese Funktionalitaet ist in der Klasse java.beans.PropertyChangeSupport abgebildet und vereinfacht die Um­setzung endweder durch Beerbung der Klasse oder durch eine Vlemb er vari able die relevanten Signaturen sind die folgenden:

public synchronized void addPropertyChangeListener (

PropertyChangeListener listener); public synchronized void removePropertyChangeListener(

PropertyChangeListener listener); public void firePropertyChange(PropertyChangeEvent evt);

Siehe A.2.1 fuer ein Beispiel zu den gebundene Eigenschaften.

3.2.4 Constrained properties

Eigenschaften, die es einem externen Programniteil ermoeglichen, eine Aende- rung abzulehnen, heissen eingeschraenkte Eigenschaften (constrained proper­ties). D.h. nicht nur das Bean, welches die Eigenschaft zur Verfuegung stellt, kann den neuen Wert auf Gueltigkeit testen (siehe A.2.2), sondern es ist auch moeglich registrierte “Zuhoerer” vor der Aenderung nach “Einwaenden” zu be­fragen. Dies wird mir Hilfe eines sogenannten Vetos abgebildet. Die Signatur von nicht eingeschraenkten Eigenschaften wird wie folgt, um die Moeglichkeit einer Veto-Ausnahme erweitert:

public <PropertyType> get<PropertyName>(); public void set<PropertyName>(<PropertyType> value) throws java.beans.PropertyVetoException;

Objekte die an dieser Gueltigkeitspruefung mitwirken wollen, muessen die java.beans.VetoableChangeListener Schnittstelle implementieren. Die­se Schnittstelle enthaelt eine Methode vetoableChangeO die ebenfalls ein java.beans.PropertyChangeEvent (wie bei gebundenen Eigenschaften) ueber- geben bekommt und ggf. eine java.beans.PropertyVetoExeption ausloest. Beans die eingeschraenkte Eigenschaften anbieten muessen demnach auch die Registrierungsniet ho den zur Verfuegung stellen:

public void addVetoableChangeListener(VetoableChangeListener p); public void removeVetoableChangeListener(VetoableChangeListener p);

Die Ereignisquelle muss die Ausnahme bearbeiten. Auch fuer diese Fun- tionalitaet wird eine Klasse im java.beans Packet zur Verfuegung gestellt VetoableChangeSupport. Siehe A.2.2 fuer ein Beispiel zu eingeschraenkten Ei­genschaften.

3.3 Introspection

Komponenten die in visuellen Entwicklungsumgebungen verwandt werden sol­len, muessen Informationen ueber ihre Funktionalitaet zur Verfuegung stellen. Beans muessen also ihre Eigenschaften, Methoden und Events veroeffentlichen.

Auf diese Weise wird es dann dem User bzw. der Entwicklungsumgebung (IDE) moeglidi das Verhalten, sowie die Erscheinung der Komponente zu beeinflussen. Eine IDE kann z.B. die BeanBox (siehe A.l) sein jedoch auch ein konmierzie- les Produkt wie z.B. JBuilder von Borland. Fuer diese Veroeflentlichung stehen nun zwei generelle Prinzipien zur Verfuegung: Reflection, Beanlnf'o-Klassen oder eine Kombination der beiden.

3.3.1 Reflecion

Haelt der Entwickler sich an die vorgesehenen Entwurfsmuster in der Na­mensgebung ist es mit Hilfe der Reflectionsmechanismusses von Java (package java.lang.reflect) moeglich Informationen ueber die Komponente zu ermit­teln. Nun mag der Fall jedoch eintreten, dass ein Entwickler gewollt von der Implementierung nach Namenskonvention absehen moechte oder die Kompo­nente ist zu Komplex um sie mit Hilfe von Reflektion zu “erkunden”. In diesem Fall muss die Beanlnf'o Schnittstelle zum Einsatz kommen.

3.3.2 Beanlnfo Schnittstelle

Durch implement er ung der Beanlnfo Schnittstelle (java.beans.Beanlnfo) wird explizit Information zum Bean zur Verfuegung gestellt. Jedes Leistungsmerk­mal (feature) wird mit einem FeatureDecriptor beschrieben. Eine Klasse wel­che die Schnittstelle implementiert muss sich an die Namenskonvention: <zu beschreibenes Bean>BeanInfo z.B. fuer das Bean: meinBean wuerde die Beanlnf'o-Klasse dann: meinBeanBeanlnfo heissen. Ein Nachteil, der sich un­mittelbat aus dieser Trennung in zwei Klassen (Bean und Beanlnfo) ergibt, ist die Problematische Wartung von zwei Klassen, die logisch jedoch zusammenge- hoeren. Darueberhinaus besteht an dieser Stelle keine andere Bindung der bei­den Klassen, als die Namenskonvention. In der Beanlnfo Schnittstelle sind acht Methoden definiert, die in einer Helferklasse (java.beans.SimpleBeanlnfo) be­reits implementiert sind, um dem Entwickler die Arbeit ein wenig zu vereinfa­chen. In dier Implementierung geben alle Methoden null Referenzen zurueck, was in einer Anwendung die Reflektion zum Einsatz bringen wuerde.

3.3.2.1 java.beans.FeatureDescriptor ist eine Klasse die Ob­

jekte beschreibt die von den Methoden getBeanDescriptorQ, getPropertyDescriptorQ, getMethodDescriptor() und

getEventSetDescriptor zurueckgeliefert werden und in der Basisinf'or- mationen wie Name der Klasse, Displayname und Expertenmodi beschrieben sind. Im folgenden werden die einzelnen Deskriptoren beschrieben.

3.3.2.2 java.beans.BeanDescriptor wird von getBeanDescriptor () ge­liefert und beschreibt das Bean generell wie z.B. Displaynamen und stellt ggf die Verbindung mit einem Customizer (siehe 3.4.2) her.

3.3.2.3 java.beans.PropertyDescriptor wird von

getPropertyDescriptorQ geliefert und beschreibt oeffentliehe Eigenschaften des Beans, wie den Namen der Eigenschaften, deren get- und set-Methoden und die zugrundeliegenden Klassen sowie den etwaigen Eigenschaften Editor.

3.3.2.4 java.beans.MethodDescriptor wird von

getMethodDescriptorO geliefert und beschreibt oeffentliche Methoden des Beans. Um die Parameter uebergeben zu koennen nimmt man ein java.beans.ParameterDescriptor zur Hilfe bzw ein Array von Parametern.

3.3.2.5 java.beans.EventDescriptor wird von getEventDescriptor()

geliefert und beschreibt Ereignisse die von dem Bean ausgeloest werden koen­nen. Auch hier nicht man sich ein Array zur Hilfe um mehrere Ereigniss abbilden zukoennen. In der Klasse werden dann Quellklasse, Event name, Listenertype und Listenermethodenname festgelegt.

Mit Hilfe der Methode java, awt. Image getIcon(int iconKind) kann das dem Bean zugewiesene Icon abgefragt werden, welches dann von einer IDE ver­wendet werden kann.

3.3.2.6 getAdditionaIBeanInfo() liefert relevante Beanlnfo Objekte die zur Beschreibung eines Beans benoetigt werden, dies ist dann der Fall, wenn eine Klassenhierachie von Beans entstanden ist und die dazugehoerigen Beanlnfo Klassen jeweils nur einen Teil des Beans beschreiben.

3.3.2.7 Die java.beans.Introspector Klasse kann Beanlnfo Objekte zu bestimmten Klassen zur Verfuegung stellen (getBeanlnfoCclass beanclass)), was benoetigt wird, da grundsaetlich keine Beanlnfo Klasse etwas von der Exi­stenz der anderen weiss.

3.3.2.8 Design- und Laufzeit kann fuer ein Bean unterschieden werden, d.h. das Bean verhaelt sich unterschiedlich in dem jeweiligen Mode. Die IDE kann die setDesignTimeO Methoden auf einer java.beans.Beans Klasse auf- ruf'en um den Mode umzuschalten. Z.Z. kann ein Bean jedoch nicht auf den Wechsel reagieren, da bisher keine EventListener registrier werden koennen.

3.4 Customization

Eine der wichtigsten Punkte in der visuellen Programmierung mit Komponenten ist die Moeglichkeit Aenderungen von Eigenschaften einfach zu gestalten. Dazu werden im Allgemeinen sogenannte Eigenschaf'tsblaetter (property sheets) ver­wandt. Diese Benutzerschnittstelle werden mit Hilfe von Eigenschaftseditoren (property editor) implementiert. Oftmals werden im ersten Anlauf Standartedi­toren eingesetzt, es kann jedoch fuer komplexere Beans Sinnvoll sein eigene zu schreiben.

3.4.1 Property Editor

Ein Eigenschafts Editor ist eine Klasse, die zum manipulieren von einer spe­ziellen Eigenschaft zur Verfuegung gestellt wird. Alle Eigenschafts Editoren muessen die java.beans.PropertyEditor Schnittstelle implementieren. Die­se Schnittstelle definiert grundlegende Funktionen wie z.B. den Zugriff auf die Eigenschaft unter Einsatz einer Textrepraesentation. Die Verbindung zwischen Editor und Eigenschaft wird per Beanlnf'o hergestellt (siehe 3.3.2.3). Man kann dann mit der Methode PropertyDescriptor .setPropertyEditorClass (Class propertyEditorClass) die Klasse festlegen. Siehe A.2.4 fuer ein Beispiel eines einfachen Editor fuer eine Boolsche Eigenschaft.

3.4.2 Customizer

Ein customizer (Anpassungselement) ist eine Schnittstelle um ein ganzes Bean und nicht nur eine Eigenschaft fuer den Benutzer anpassbar zu machen. Custo­mizer sind nicht auf die oeffentlichen Eigenschaften des Beans beschraenkt, son­dern auch andere Parameter eines Beans koennen auf dieser Weise konfigurieren. Customizre sollte zum Einsatz kommen, wenn Beans sehr komplex und schwer ueberschaubar werden. Ein Customizer hat grundsaetlich alle moeglichkeit en einer GUI (Graphical User Interface) und kann auch als Dialog implementiert werden und somit wizard fungieren. Wer Customizer einsetzen will muss in jeden Fall auch eine Beanslnf'o Klasse implementieren, da die Verbindung zwi­schen Customizer und Bean aehnlich wie bei den Eigenschaftseditoren, in der Beanlnfo Klasse hergestellt werden (siehe 3.3.2.2). Alle Customizer muessen die java.beans .Customizer Schnittstelle implementieren, die primaer Metho­den fuer die Registrierung von Zuhoerern definiert und eine Methode namens setObject(Object bean) ohne Rueckgabewert zur Verfuegung stellt. Letzte­re spezifiziert das zugehoerige Bean, welches mit dem Customizer angepasst werden soll. Darueberhinaus muss der Customizer java.awt.Component im­plementieren und einen Konstruktor ohne Parameter haben. Nun kann man sich leicht vorstellen, dass dieser Customizer alle nur erdenklichen Aktionen auf dem Bean durchfuehren kann und auch solche Parameter aendern, die nicht bestandteil des Vero effent liehen Teils des Beans sind, da der Customizer ueber eine Referenz auf das Bean verfliegt.

3.5 Persistence

Die meisten Komponenten pflegen ueber die Programmlogik hinaus Informatio­nen, die Erscheinung und Verhalten der Komponente beschreiben. Einige dieser Informationen befinden sich in den Objekt Eigenschaften (siehe 3.2) wie z.B. Schriftart, oder Farbe der Komponente. Ueber die veroeffentlichen Eigenschaf­ten hinweg koennen dies auch interne Eigenschaften sein. Wenn Eigenschaften das Erscheinungsbild bzw. das Verhalten beeinflussen und auch wahrend des Programmlaufes auch veraendert werden koennen, muss es eine Moeglichkeit geben, diese Informationen ueber die Laufzeit hinweg zu erhalten - sprich es persistent zu machen.

3.5.1 Serialization

Die Java Beans Architektur bedient sich dazu des Java Objekt Serialisierungs- mechanismusses. Um in Java Klassen mit diesem Mechanismusses zu behan­deln, muss die Schnittstelle j ava. io. Serialization implementiert werden. Die Schnittstelle ist lediglich ein Marker und enthaelt keiner Methoden. Standart- maessig werden alle “non-static” und “non-transient” Elemente der Komponente serialisiert. Moechte man auch diese Elemente sichern muss der Programmierer es in jeden Fall selbst umsetzen. Im Abschnitt A.2.3 befindet sich ein kleines Beispiel.

3.5.2 Versionsproblematik und Kompatibilitaet

Wenn Serialisierung zur Anwendung kommt, entsteht unmittelbar die Proble­matik der Version einer Klasse, welche Grundlage fuer ein serialisiertes Objekt war, welches nun deserialisiert werden soll. Solange keine neuen Informationen zu Grunde gelegt werden und nur Methoden veraendert oder hinzugefuegt wer­den wird dies nicht zu einem Problem fuehren. Die Versionkontrolle wird jedoch in jedem Falle bei Veraenderter Klassendefinition Inkompatibilít act annehmen und bei dem Versuch des deserialisirens eine java.io.InvalidClassException ausloesen. Wenn man bereit ist die Inkompatiblitaeten selber zu behandeln oder es bewusst machen moechte, laesst sich dies von Hand innerhalb der Methode readObjectO umsetzen. Kompatible Änderungen, wie z.B. Hinzu- f'uegen einer Methoden wuerde wie oben beschrieben eine Exception ausloe­sen. Um die Java Virtual Machine (JVM) nun zu ueberreden, dass die Aende- rung gewollt ist, muss man ein Stream Unique Identifier (SUID) zum Einsatz kommen, der die erste kompatible Klasse kennzeichnet. Mit Hilfe des Pro­grammes seri alver (Teil des JDKs) lassen sich solche SUID erzeugen, welche dann mit Hilfe einer Konstante (z.b. static final long serialVersionUID = 8984554447612061263L;)in den kompatiblen Quellcode eingesetzt werden. Somit wird die JVM keine Exception mehr ausloesen.

3.5.3 Externalization

Objekte, die die Schnittstelle java.io.Externalization implementieren koennen ebenfalls persistent gespeichert und wieder herhgestellt wer­den. Waehrend des Serialisationsprozess wird vorerst auf die Schnittstelle java. io.Serializable gepruef't und wenn nicht vorhanden auf die Schnittstel­le java, io .Externalizable. Klassen welche diese Schnittstelle implementieren muessen sich anders wie bei serializable komplett um die abarbeitung der Speicherung kuemmern und ggf. auch selber die Klassenhierachie abarbeiten. Beim Serialisieren wird die Methode writeExternalQ aufgerufen und analog beim lesen die Methode readExternalQ. Wichtig an dieser Stelle ist, dass es keine default Routinen fuer diese Vorgaenge gibt.

3.5.4 Instanzierung von Serialisierten Beans

Um nun serialisierte Beans zu instanzieren wird die statische Methode instantiate0 der Klasse java.beans.Beans benutzt. Diese Methode be­ kommt zwei Parameter: ein Klassenlader (wird im Regelfall auf null ge- setzt)und einen String welcher das Beans spezifiziert. Findet die Methode eine Datei die den gleichen Namen wie das Bean, mit der Endung .ser, hat wird es geladen - wird keine Datei gefunden wird ein neues Objekt erstellt mit Hilfe des Standart Konstruktors.

3.6 Packaging

Java Beans werden gepackt und verteilt in JAR Files. Diese Technik macht es Moeglich alle Dateien, die zu einer Bean gehören, wie z.B. die Klassen-Dateien, serialisierte Objekte, Bilder, Help-Files und andere Resource-Dateien in einer Datei auszuliefern. Ein JAR File ist ein Archiv im ZIP-Format, welches optional eine sogenannte Manifest-Datei beinhaltet, die Beschreibungen über den Inhalt des Archivs enthält. Alle JAR Files die Beans enthalten, müssen eine solche Manifest-Datei beinhalten. In einem JAR File können eine oder mehrere Beans enthalten sein. Welche Dateien Beans sind und welche nicht werden innerhalb des der Manifestdatei beschrieben.

3.6.1 Das Manifest

Die Manifest-Datei enthält Informationen über bestimmte Teile des Archivs. Die einzelnen Sektionen werden durch Leerzeilen getrennt. Jede Sektion enthält einen oder mehrere Header in dem Format <tag>: <value>. Sektionen die Informationen über Dateien des Archivs beinhalten, haben ein <tag> Name, mit dem relativen Dateinamen als <value> Dateien die Beans darstellen, haben zusätzlich noch einen Header mit Java-Bean als <tag> und True als <value>. Eine Manifest-Datei könnte al­so z.B. folgenden Inhalt haben:

Name : elektrowurst/de/seminar/Wurst.dass Java-Bean: True

Header mit dem <tag> Depends-On zeigen Abhängigkeiten der Datei an. Als <value> wird eine Liste von Dateien des Archivs angegeben, zu denen Ab­hängigkeiten bestehen. Das können zusätzliche Klassen oder Ressourcen sein. Fehlt das Depends-On <tag>, so sind Abhängigkeiten unbekannt. Ist es hinge­gen vorhanden, muß es alle Abhängigkeiten anzeigen. Das <tag> ohne <value> zeigt an, daß keine Abhängigkeiten bestehen. Das folgende Manifest definiert ein Bean a.b, deren Abhängigkeiten unbekannt sind ein Bean x.y mit Abhän­gigkeiten zu x/a.gif, x/b.gif und der Klasse elektrowurst.de.Wurst und ein Bean SuperWurst ohne Abhängigkeiten

Name: a/b.ser Java-Bean: True

Name: x/y.class

Java-Bean: True

Depends-On: x/a.gif x/b.gif

Depends-On: elektrowurst/de/Wurst.dass

Name : SuperWurst. dass Java-Bean: True Depends-On:

Die Manifest Sektion für einen JAR Eintrag kann optional das Design-Time-Only <tag> benutzen, um zu zeigen, daß dieser Eintrag lediglich zur Design-Zeit benötigt wird. Dies könnte von Buildern dazu benutzt wer­den, diese Dateien in neuen Beans oder Applikationen nicht mit in das Paket zu tun. Folgendes Beispiel definiert ein Bean elektrowurst. de. Mega Wurst und sagt, dafi die dazugehörige elektrowurst.de.MegaWurstBeanlnfo.class lediglich zur Design-Zeit benötigt wird.

Name : elektrowurst/de/MegaWurst. dass Java-Bean: True

Name : elektrwurst/de/MegaWurstBeanlnfо.dass Design-Time_Only: True

Natuerlich koennen auch Dokumentationen zu den Beans in HTML in das JAR File eingefügt werden.

3.6.2 Erzeugen eines JAR Archives

Um nun ein Beans ausliefern zu koennen ist hier ein Beispiel fuer ein Bean Ultra Wurst aufgezeigt.

$ jar cfm UltraWurstBean.jar UltraWurst.mf UltraWurst.dass es sind ggf. noch mehrere Klassen hinzuzufuegen.

A Appendix

A.l Beans Development Kit

Der BeanDevelopmentKit (BDK) ist eine visuelle Entwicklungsumgebung, die das Erstellen eigener Software erleichtert. Durch die Wiederverwendung be­reits geschriebener Beans und die optische Darstellung wichtiger Informationen können Anwendungen erzeugt werden, ohne programmieren zu müssen. Statt dessen ist es möglich, allein durch Drag&Drop-Operationen zu arbeiten. Um übersichtlich zu bleiben, ist der BDK in drei separate Fenster unterteilt. Beim Starten erscheint auf der linken Seite die ToolBox, auf der rechten Seite das PropertySheet und in der Mitte die eigentliche Arbeitsfläche, die BeanBox.

In der ToolBox werden fertige Beans bereit gestellt, die wir mit der Maus in die BeanBox ziehen können. Dort können wir diese Beans verändern. Für die­sen Schritt tritt das PropertySheet in Aktion. Mit Hilfe der Reflexion filtert die Introspektion die Eigenschaften der Bean heraus und stellt sie im PropertySheet zur Verfügung. Dieses ist also ein Eigenschaftsblatt, das die Bean beschreibt. Umfangreiche Eigenschaftsblätter werden Customizer genannt. Erfahrene Pro­grammierer werden an dieser Stelle sicherlich die Nähe zu Wizards erkennen. Mögliche Eigenschaften sind “Hintergrundfarbe”, “Vordergrundfarbe”, “Schrift” und “Text”, die im PropertySheet jeweils durch einen eigenen PropertyEditor angezeigt und manipuliert werden. Um eigene spezielle PropertyEditoren zu erstellen muß auf die Klasse PropertyEditorManager und das Interface Proper­tyEditor zurückgegriffen werden. Arbeitet man mit mehreren Beans, so wird die Bean im PropertySheet beschrieben, die in der BeanBox schraffiert umrandet ist. Zu Anfang mag es irritierend sein, daß das PropertySheet Eigenschaften anzeigt, obwohl wir doch noch gar keine Bean aus der ToolBox importiert ha­ben. Die einfache Lösung ist, daß die BeanBox selber wieder eine Bean ist und somit ihre Eigenschaften angezeigt werden.

Die Stärke des BDK liegt aber in der Möglichkeit, mehrere Beans zu einer neuen Anwendung zusammenzufügen. Dazu importieren wir die Beans in die BeanBox und klicken eine Bean an. Über das Menü in der Kopfleiste wählen wir das Ereignis, das diese Bean aussenden soll, aus. Jetzt markieren wir die Ereignisabhörerbean und wählen im Fenster “EventTargetDialog” die Schnitt­stelle. Das Fenster wird automatisch durch Reflexion der öffentlichen Methoden generiert.

A.2 Programmbeispiele

A.2.1 Gebundene Eigenschaften: Temperatur.java

import java.beans.PropertyChangeSupport; public class Temperatur{

protected PropertyChangeSupport boundSupport;

// die aktuelle Temperatur protected double aktTemp = 25.0;

// Standartkonstruktor public Temperatur(){

boundSupport = new PropertyChangeSupport(this);

>

// Konstruktor

public Temperatur (double startTempH // aufrufen des Standartkonstruktors thisO ;

aktTemp=startTemp;

>

// Zugriffsmethode für Aktuelle Temperatur public double getAktuelleTemperatur(){ return aktTemp;

> protected void notifyTemperaturChange(){

//deligieren des Eventabschusses,

boundSupport.firePropertyChange("Aktuelle Temperatur",

null, new Double(aktTemp));

>

>

A.2.2 Eingeschraenkte Eigenschaften: Thermometer.java, Constrai- ner.java, Terra.java

Thermometer.java

import java.beans.*;

public dass Thermometer implements PropertyChangeListener{

// Einschraenkung der Werte protected double minTemp = 18.0; protected double maxTemp = 30.0; final static double MIN = 10; final static double MAX = 35;

// die aktuelle Temperatur protected Temperatur aktTemp;

protected VetoableChangeSupport constraintHandler;

public Thermometer(){ this(25.0);

>

public Thermometer(double temperatur){ aktTemp = new Temperatur(temperatur); constraintHandler = new VetoableChangeSupport(this);

>

// implementierung des PropertyChangeListener interfaces public void propertyChange(PropertyChangeEvent evt){

// hier muesste noch implementiert werden

>

// implementierung des VetoableChangeSupport

public void addVetoableChangeListener(VetoableChangeListener 1){

// weiterreichen an den Handler constraintHandler.addVetoableChangeListener(l);

>

public void removeVetoableChangeListener(VetoableChangeListener 1){

// weiterreichen an den Handler

constraintHandler.removeVetoableChangeListener(l);

// Zugriffsmethoden für die min und max Werte public double getMinimumTemperatur(){ return minTemp;

>

public double getMaximumTemperatur(){ return maxTemp;

>

public void setMinimumTemperatur(double value)

throws PropertyVetoException{

// intern einmal testen, ob der neue Wert // ok ist und ggf. veto ausloesen if (value>MAX || value<MIN ){

throw new PropertyVetoException("Wert liegt ausserhalb des zulaessigen Bereiches(10-35)",

new PropertyChangeEvent(this,"MinimumTemperature", new Double(minTemp), new Double(value)));

>

// ansonsten weiterreichen an Haendler (extern) constraintHandler.fireVetoableChangeC'MinimumTemperatur", new Double(minTemp), new Double(value));

// wenn keine Exception fliegt geht die Aenderung in Ordnung minTemp = value;

>

public void setMaximumTemperatur(double value) throws

PropertyVetoException{

// intern testen, ob der neue Wert ok ist und ggf. veto ausloesen if (value>MAX || value<MIN ){

throw new PropertyVetoException("Wert liegt ausserhalb des zulaessigen Bereiches(10-35)",

new PropertyChangeEvent(this,"MinimumTemperature", new Double(minTemp),

new Double(value)));

// ansonsten weiterreichen an Haendler constraintHandler.fireVetoableChangeC'MaximumTemperatur", new Double(maxTemp), new Double(value));

// wenn keine Exception fliegt geht die Aenderung in Ordnung maxTemp = value;

>

>

Constrainer.j ava import java.beans.*;

public class Constrainer implements VetoableChangeListener{

// implementieren des interface: VetoableChangeListener public void vetoableChange(PropertyChangeEvent evt)

throws PropertyVetoException{

// die Limitierung wird getestet, liegt der Wert // auch wirklich im Bereich (11 bis 33)

double value = ((Double)evt.getNewValue()).doubleValue0 ; if (value>33 I I value<ll){

throw new PropertyVetoExceptionO'VETO von Constrainer: Wert "

+value+" abgelehnt ",evt);

}else{

System.out.printin("Wert : "+value+" von Constrainer angenommen");

>

>

>

A.2.3 Serialisierung

Storage.java

import java.io.*; import java.awt.*; import java.awt.event.*;

public class Storage extends Button{ protected String dateiname; protected boolean mode; public static final boolean save = true; public static final boolean restore = false;

public Storage(){ mode = save;

dateiname = new String("Storage.tmp"); setLabel("Wurst");

addActionListener (new MyListenerQ) ;

>

class MyListener implements ActionListener{

//ueberschreiben

public void actionPerformed(ActionEvent e){ if (mode) saveO; else restore ();

>

>

// ne paar Zugriffmethoden

public String getDateinameO{return dateiname;} public void setDateiname(String sHdateiname = s;} public boolean getModeO{return mode;} public void setMode(boolean b){mode=b;}

private void save(){ try{

FileOutputStream fos = new FileOutputStream(dateiname); ObjectOutputStream s = new ObjectOutputStream(fos); s.writeObject(getLabelQ) ;

s.flush О ;

}catch (Exception eKSystem.out.println(e) ;>

private void restore О{ try{

FilelnputStream fis = new FilelnputStream(dateiname); Obj ectInputStream s = new ObjectInputStream(fis); setLabel((String)s.readObj ect());

}catch (Exception eKSystem.out.println(e) ;>

>

>

A.2.4 Eigenschaftseditoren RunningEditor.j ava

import java.beans.PropertyEditorSupport;

public class RunningEditor extends PropertyEditorSupport{ // der Aktuelle Zustand der Eigenschaft protected boolean bRunning;

// setzen des zu editierenden Objektes public void setValue(Object o){

// Ermitteln des aktuellen Wertes bRunning = ((Boolean)o).booleanValue();

>

// Zugriffsmethode fuer den aktuellen Wert public Object getValue(){

return new Boolean(bRunning);

>

// Liefert den Wert als Text public String getAsText(){ if (bRunning){ return "YES";

}else{

return "NO";

>

>

// setzen des Wertes als Text public void setAsText(String s){ if (s.equals("YES")){ bRunning = true;

}else{

bRunning = false;

>

// Aenderung kommunizieren firePropertyChangeü ;

>

Literatur

Beth, S. (2000), ‘Javabeans 101’, Java Developer Connection .

*http:/7developer .java.sun.com

Englander, R. (1997), Developing Java Beans, 1st edn, O’Reilly & Associates, Inc.

Flanagan, D. (1997), Java in a Nutshell, 2cd edn, O’Reilly & Associates, Inc.

Quinn, A. (2000), ‘The java tutorial/javabeans’.

*http://java.sun.com/docs/books/tutorial/javabeans/index.html

[...]


[1]www.fh-wedel. de

Details

Seiten
23
Jahr
2001
Dateigröße
498 KB
Sprache
Deutsch
Katalognummer
v98801
Note
Schlagworte
Java Beans

Autor

Teilen

Zurück

Titel: Komponenten Konzept von Java, Java-Beans