JavaBeans Übersicht Marc Monecke [email protected] Praktische Informatik Fachbereich Elektrotechnik und Informatik Universität Siegen, D-57068 Siegen 3. Juni 2003 Inhaltsverzeichnis 1 JavaBeans-Grundlagen 1.1 Grundlegende Merkmale . 1.1.1 Entwurf . . . . . . 1.1.2 Laufzeit . . . . . . 1.1.3 Sehr einfache Bean . . . . 3 3 3 3 3 2 Einfache Bean-Eigenschaften (Properties) 2.1 Simple Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2 Indexed Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3 Eigenschaften-Editoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 4 5 5 3 Ereignisse 3.1 Beispiel: Schaltfläche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.1.1 Explizite Beschreibung der Ereignisse . . . . . . . . . . . . . . . . . . . . 3.1.2 Ereignis-Adapter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 6 6 6 4 Eigenschaften mit Benachrichtigung 4.1 Bound Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2 Constrained Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2.1 Bestandteile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 7 7 9 5 BeanInfo – Informationen über Beans 9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Persistente Beans 9 6.1 Vorgegebene Serialisierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 6.2 Serialisierung in speziellem Format . . . . . . . . . . . . . . . . . . . . . . . . . 10 1 7 Bean-Entwicklungswerkzeuge 10 7.1 Verpacken und Ausliefern von Beans . . . . . . . . . . . . . . . . . . . . . . . . 10 8 Zusammenfassung 11 2 1 JavaBeans-Grundlagen – Software-Komponenten in Java – meist als GUI-Elemente genutzt – mit GUI-Editor graphische Benutzungsschnittstellen realisieren – seit JDK 1.1 in Java enthalten – Java-Komponenten können auch ohne Beans entwickelt werden – Beans standardisieren aber die Konzepte dazu – Vorschriften zur Gestaltung von Beans oft auch als Entwurfsmuster (design patterns) – sind aber nur Gestaltungsrichtlinien für Java-Klassen, die als Beans verwendet werden sollen – plattformunabhängig, unabhängig von Entwicklungsumgebung – aber sprachspezifisch 1.1 Grundlegende Merkmale 1.1.1 Entwurf – Beans über Eigenschaften konfigurierbar – Beans können serialisiert werden → Code und Eigenschaften rekonstruierbar – Werkzeuge (builder tools) können vorhandene Eigenschaften und relevante Ereignisse ermitteln → Eigenschaften-Editor – dazu wird Reflexivität von Java genutzt – oft Nachrichtenaustausch zwischen Beans im Werkzeug graphisch editierbar 1.1.2 Laufzeit – Eine Bean entspricht zur Laufzeit einem Java-Objekt – Interaktion zwischen Beans über Ereignisse (events) – Änderung der Eigenschaften von anderen Beans überwachbar 1.1.3 Sehr einfache Bean import java.awt.*; import java.io.Serializable; public class FirstBean extends Canvas implements Serializable { private Color color = Color.green; //Constructor sets inherited properties public FirstBean() { 3 setSize(60,40); setBackground(Color.red); } public Color getColor() { return color; } public void setColor(Color newColor) { color = newColor; repaint(); } } zu beachten: – Konstruktor ohne Parameter – Eigenschaft color, private-Attribut – zugehörige set-/get- Operationen – Superklasse Canvas → Bean darstellbar – mit Superklasse Panel auch komplexere GUI-Elemente möglich – implementiert Serializable → serialisierbar 2 Einfache Bean-Eigenschaften (Properties) – Eigenschaften (Properties) entsprechen Attributen der Bean-Klasse – von außen nicht zugreifbar → private – für jede Eigenschaften get- und set-Operation implementieren – Benennung: set <Eigenschaftsname>, get <Eigenschaftsname>: Eigenschaft color → setColor(), getColor() – Anhand Parametertyp/Rückgabetyp kann passender Editor im builder tool automatisch bestimmt werden → Farb-Dialog – Arten von Eigenschaften: – Simple Properties: einfache (atomare) Eigenschaften – Indexed Properties: Arrays von Eigenschaften – Bound Properties: Eigenschaften, deren Änderung überwacht werden kann – Constrained Properties: Eigenschaften, deren Änderung eingeschränkt werden kann 2.1 Simple Properties – atomare Java-Datentypen – Java-Klassen (z.B. Color) 4 – Eigenschaften-Editoren sind Teil des jeweiligen Werkzeugs – werden abhängig vom Typ ausgewählt – für atomare Typen, Schriftarten und Farbe verfügbar – spezielle Eigenschaften-Editoren können implementiert und den Beans zugeordnet werden 2.2 Indexed Properties → Mehrwertige Eigenschaften – mehrwertige Eigenschaften – Zugriff auf einzelne Elemente über Index – Zugriffsoperationen zum – lesen/schreiben des gesamten Arrays – lesen/schreiben einzelner Einträge – spezielle Editoren zum Bearbeiten der Eigenschaften nötig Gestaltung der Schnittstelle // Zugriff auf gesamte Eigenschaft public <PropertyType>[] get<PropertyName> (); public void set<PropertyName> ( <PropertyType>[] value ); // Zugriff auf einzelne Werte public <PropertyType> get<PropertyName> ( int index ); public void set<PropertyName> ( int index, <PropertyType> value ); 2.3 Eigenschaften-Editoren – vorgegebene Editoren für atomare Attribute, Farbe, Schriftart – erscheinen im Propertysheet der Bean – spezielle Editoren können implementiert werden – Zuordnung von Editor zu Eigenschaft – explizit zuordnen in BeanInfo – Registrierung beim PropertyEditorManager – nach Namen suchen (<Bean-Klassenname>Editor) – statt Propertysheet auch Customizer möglich 5 3 Ereignisse → Kommunikation zwischen Beans – nutzt bekannten Java-Event-Mechanismus – anhand von Bean-Schnittstelle kann der Typ der auslösbaren Ereignisse ermittelt werden Schnittstelle public void add<EventListenerType>(<EventListenerType> a) public void remove<EventListenerType>(<EventListenerType> a) 3.1 Beispiel: Schaltfläche Schaltfläche (button) sendet ActionEvents, wenn er betätigt wird public void public void addActionListener ( ActionListener l ) removeActionListener ( ActionListener l ) ActionListener implementiert Operation public void 3.1.1 actionPerformed ( ActionEvent e ) Explizite Beschreibung der Ereignisse Operation public EventSetDescriptor[] getEventSetDescriptors () in BeanInfo-Klasse liefert Beschreibungen zurück 3.1.2 Ereignis-Adapter – ”übersetzen” Ereignisse zwischen Beans – Adapter vermittelt zwischen Sender und Empfänger (Abbildung 1) 4 Eigenschaften mit Benachrichtigung → Änderung der Eigenschaften kann durch andere Beans überwacht und beeinflußt werden 6 Button listeners <<interface>> addActionListener(ActionListener) ActionListener * removeActionListener(ActionListener) actionPerformed(ActionEvent) fireActionEvent() Adapter for all l in listeners actionPerformed(ActionEvent) l.actionPerformed(event); 1 target.startJuggling(); target Juggler startJuggling() Abbildung 1: Ereignis-Adapter 4.1 Bound Properties → überwachbare Eigenschaften – Änderung von Bean-Eigenschaften überwachen (Abbildung 2) → Bean verwaltet listener, die über Änderungen informiert werden (PropertyChangeListener) – Verwalten der Listener → PropertyChangeSupport – Operationen zum Hinzufügen, Entfernen von Listenern – bei Änderung Listener benachrichtigen: firePropertyChange – PropertyChangeEvent enthält alten und neuen Wert 4.2 Constrained Properties → eingeschränkte Eigenschaften – Änderung von Bean-Eigenschaften einschränken → nur erlaubte Werte setzen – Überwachung der Änderungen außerhalb der Bean (Abbildung 3): – weitere Bean überwacht beabsichtigte Änderung (analog zu bound properties) – kann ’Veto’ einlegen oder die Änderung akzeptieren: vetoableChange(PropertyChangeEvent) throws PropertyVetoException – set-Operation wirft exception, wenn Änderung abgelehnt 7 String old_text; old_text = text; text = new_text; changes.firePropertyChange( "text", old_text, new_text); MyBean text : String setText(new_text : String) getText() : String addPropertyChangeListener( listener : PropertyChangeListener) removePropertyChangeListener( PropertyChangeListener) changes. removePropertyChangeListener( listener); 1 <<interface>> PropertyChangeListener listeners * propertyChange(PropertyChangeEvent) changes MyChangeListener PropertyChangeSupport propertyChange(PropertyChangeEvent) addPropertyChangeListener( PropertyChangeListener) removePropertyChangeListener( PropertyChangeListener) firePropertyChange String, Object, Object) Abbildung 2: Bound Properties MyBean text : String setText(String) getText() : String addVetoableChangeListener ( VetoableChangeListener) removeVetoableChangeListener ( VetoableChangeListener) 1 listeners * changes <<interface>> VetoableChangeListener vetoableChange(PropertyChangeEvent) MyChangeListener VetoablePropertyChangeSupport vetoableChange(PropertyChangeEvent) addVetoableChangeListener( VetoableChangeListener) removeVetoableChangeListener( VetoableChangeListener) fireVetoableChange ( String, Object, Object) PropertyVetoException PropertyVetoException Abbildung 3: Constrained Properties 8 4.2.1 Bestandteile Bean mit überwachter Eigenschaft – Listener verwalten (VetoableChangeSupport) – in set-Operation Listener benachrichtigen Bean, die Änderungen überwacht (Listener) – implementiert Schnittstelle VetoableChangeListener – Operation vetoableChange wird aufgerufen – bei Widerspruch, PropertyVetoException werfen 5 BeanInfo – Informationen über Beans – Merkmale von Beans können aus Schnittstelle abgeleitet werden (sofern Richtlinien beachtet) – dafür zuständig: java.beans.Introspector – liefert für eine Bean ein Beschreibungsobjekt zurück – dieses implementiert die Schnittstelle BeanInfo – statt dessen kann auch eigene BeanInfo-Klasse implementiert werden: Benennung: <Bean-Klassenname>Info – ableitbar von SimpleBeanInfo – Werkzeug lädt diese, wenn vorhanden; daher keine introspection mehr → nur Eigenschaften aus BeanInfo-Klasse verfügbar! Ausschnitt aus der BeanInfo-Schnittstelle public Image getIcon(int iconKind) PropertyDescriptor[] getPropertyDescriptors(); MethodDescriptor[] getMethodDescriptors(); EventSetDescriptor[] getEventSetDescriptors(); 6 Persistente Beans → Zustand einer Bean persistent machen und Bean aus Datei/Strom rekonstruieren 6.1 Vorgegebene Serialisierung – Implementierung der Schnittstelle Serializable (sofern nicht von Oberklasse implementiert) – Konstruktor ohne Argumente zum Laden nötig – funktioniert mit einfachen Eigenschaften 9 – Ausblenden von Attributen mit transient und static möglich – alternativ: Operationen zum Schreiben und Lesen der Bean implementieren: private void writeObject(java.io.ObjectOutputStream out) throws IOException; private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException; 6.2 Serialisierung in speziellem Format → volle Kontrolle über den Serialisierungsvorgang – Schnittstelle Externalizable implementieren – Verwendung von eigenem Dateiformat möglich 7 Bean-Entwicklungswerkzeuge – gleichzeitig Entwurfswerkzeug und Laufzeitumgebung – Laden von Beans – customizing – Erzeugen von Ereignis-Beziehungen graphisch durch Verbinden der Beans mit Linien – Generieren von Ereignis-Adaptern – Beispiel: BeanBox von Sun 7.1 Verpacken und Ausliefern von Beans – Java Archives (jar-Dateien) enthalten Beans im Binärformat und alle relevanten Ressourcen – Klassendateien (.class) – serialisierte Beans (.ser) – Hilfedateien (.html) – weitere Ressourcen (Bilder, Audio, Text) – optional: MANIFEST-Datei, enthält Informationen über Inhalt des Archivs → Kennzeichnung von Beans – BeanBox benötigt diese Beispiel Datei: META-INF/MANIFEST.MF Manifest-Version: 1.0 Name: com/sun/commerce/AddressGate/AddressGateImpl.class Java-Bean: True 10 Name: pi/swt2/demo/demo.ser Java-Bean: True Name: pi/swt2/demo/EventObj.class Java-Bean: False Name: hello.gif Java-Bean: False 8 Zusammenfassung – JavaBeans ist einfaches Komponentenmodell – Regeln für die Gestaltung der Komponenten-Schnittstelle – plattformunabhängig, aber sprachspezifisch – Bean == Java-Klasse 11