JavaBeans Grundlagen Eigenschaften Ereignisse Konfiguration JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 1 Begriffsdefinition "A JavaBean is a reusable software component that can be manipulated visually in a builder tool." Softwarekomponente • Wiederverwendbare, in sich abgeschlossene Einheit Interaktive Manipulation in Entwicklungswerkzeug (GUI-Builder) • Visuelle Programmierung • Sichtbare und unsichtbare Beans • Zusammenstellung zu komplexeren Beans, Applets oder Anwendungen • Serialisierung oder Erzeugung von Programmcode Definiert durch Java-Klasse, die bestimmten Konventionen folgt • Klassendefinition und Methodensignaturen • Ereignismechanismus Hilfsklassen im Paket java.beans JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 2 Grundlegende Eigenschaften von Beans wird durch ein Objekt repräsentiert; existiert sowohl zur Design-Zeit als auch zur Laufzeit ist durch eine Klasse definiert besitzt konfigurierbare Eigenschaften, durch welche das Bean angepasst werden kann verwendet Ereigniskonzept zur Interaktion mit anderen Programmteilen die Programmierung muss bestimmten Konventionen („Design Patterns“) folgen: • Klasse hat parameterlosen Konstruktor • Zugriff auf Eigenschaften mittels Getter- und Setter-Methoden • Design-Pattern für die Kodierung von Ereignissen • Namenskonventionen für Eigenschaften und Ereignisse JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 3 Grundlegende Eigenschaften von Beans (Fortsetzung) ist serialisierbar und deserialisierbar erlaubt Introspection, d.h. die Ausforschung und Beschreibung der Eigenschaften, Methoden und Ereignisse • Introspection auf Basis der Design-Patterns und Namenskonventionen • Beschreibung durch eigene Informationsklasse (= BeanInfo-Klasse) erlaubt die interaktive Anpassung in interaktiven Entwicklungswerkzeugen • auf Basis der Beschreibung des Beans JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 4 Verwendung von Beans bei wiederverwendbaren, durch Eigenschaften anpassbaren Komponenten insbesondere für die interaktive, visuelle Programmierung sowohl für kleine Komponenten als auch für große Anwendungen, z.B.: • Button • Timer • ImageViewer • Spreadsheet JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 5 Beispiel CountdownBean CountdownBean ist eine wiederverwendbare Komponente für Countdowns CountdownBean leistet folgendes: • man kann eine Countdown-Zeit setzen (Zeit im Millisekunden) • man kann Countdown starten • man kann Countdown stoppen • Bean informiert in bestimmten Zeitintervallen über die Restzeit - zuerst in größeren Abständen - zum Ende hin in kürzeren Abständen • Bean informiert über Starten, Stoppen und Ende des Countdown • Bean ist anpassbar durch - Intervallzeiten - Zeitspanne, wenn kurze Intervallzeiten beginnen sollen Beispielanwendung des CountdownBeans: • bei Bombe • bei Selbstauslöser in Fotoapparaten JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 6 Beispiel CountdownBean: Klassendiagramm JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 7 Bean-Klasse wie jede andere Klasse braucht unbedingt parameterlosen Konstruktor Beispiel CountdownBean: public class CountdownBean extends java.lang.Object implements Runnable { /** Creates a new instance of CountdownBean */ public CountdownBean() { ... } JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 8 JavaBeans Grundlagen Eigenschaften Ereignisse Konfiguration JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 9 Eigenschaften (Properties) Bestimmen Erscheinung und Verhalten • Können von Entwicklungswerkzeug ausgelesen und verändert werden Erkennbar an Methodensignatur für Getter- und Setter-Methoden • Simple Properties public <PropType> get<PropertyName>() bzw. public boolean is<PropertyName>() public void set<PropName>(<PropType> value) void int void boolean • setMaxLength(int int maxLength); getMaxLength(); setEditable(boolean boolean editable); isEditable(); Indexed Properties public public public public <PropType>[] get<PropertyName>() void set<PropName>(<PropType>[] value) <PropType> get<PropertyName>(int i) void set<PropName>(int i, <PropType> value) void void float[] float float setDataSet(float float[] dataSet); float setDataSet(int int index, float data); getDataSet(); getDataSet(int int index); JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 10 Beispiel CountdownBean: Eigenschaften Eigenschaften für • Countdown-Zeit • langes Intervall public int getTime() { return time; } public void setTime(int int time) { this.time = time; this } public void setLongInterval(int int i) { longInterval = i; } public int getLongInterval() { return longInterval; } • kurzes Intervall public void setShortInterval(int int i) { shortInterval = i; } public int getShortInterval() { return shortInterval; } • Beginn des kurzen Intervalls public void setShortIntervalPeriod(int int i) { shortIntervalPeriod = i; } public int getShortIntervalPeriod() { return shortIntervalPeriod; } JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 11 JavaBeans Grundlagen Eigenschaften Ereignisse Konfiguration JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 12 Ereignisse Kommunikation mit anderen Beans • Zustandsänderung wird allen Interessierten mitgeteilt • Lose gekoppelte Kommunikation Quelle • Auslöser eines Ereignisses • Benachrichtigt Interessierte Interessierter (Listener) • Reagiert auf Ereignis • Wird bei Quelle registriert und deregistriert Ereignisobjekt (EventObject) • Informationen über Ereignis JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 13 Design Pattern für Ereignisse Listener • • Interface welche Ereignismethoden implementiert kann java.util.EventListener erweitern public interface TimerListener extends java.util.EventListener { public void timerAction(TimerEvent e); } Quelle • implementiert Methoden für das Anfügen und Entfernen von Listener public void add<ListenerType>(<ListenerType> listener) public void remove<ListenerType>(<ListenerType> listener); public class TimerBean { public void addTimerListener(TimerListener l) { … } public void removeTimerListener(TimerListener l) { … } private void fireTimerEvent(TimerEvent e) { … } } JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 14 Design Pattern für Ereignisse (Fortsetzung) Ereignisobjekt • • erweitert java.util.EventObject kommuniziert Informationen über Ereignis public class TimerEvent extends java.util.EventObject { private long time; public TimerEvent(Object source) { super(source); super time = System.currentTimeMillis(); } public long getTime() { return time; } } JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 15 Beispiel CountdownBean: Countdown-Ereignis CountdownListener public interface CountdownListener extends EventListener { void countdownStarted(CountdownEvent e); void countdownStopped(CountdownEvent e); void countdownTimeElapsed(CountdownEvent e); void countdownFinished(CountdownEvent e); } CountdownEvent public class CountdownEvent extends java.util.EventObject { public CountdownEvent(Object source, int restTime) { super(source); super this.restTime = restTime; this } public int getRestTime() { return restTime; } private int restTime; } JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 16 Beispiel CountdownBean: Countdown-Ereignis (Forts.) Quelle public class CountdownBean implements Runnable { public void addCountdownListener(CountdownListener l) { lList.add(CountdownListener.class class, class l); } public void removeCountdownListener(CountdownListener l) { lList.remove(CountdownListener.class class, class l); } protected void fireCountdownStartedEvent() { CountdownEvent event = new CountdownEvent(this this, this restTime); CountdownListener[] cdLs = ((CountdownListener[]) lList.getListeners(CountdownListener.class class)); class for (int int i = 0; i < cdLs.length; i++) { cdLs[i].countdownStarted(event); } } protected void fireCountdownTimeElapsedEvent() { CountdownEvent event = new CountdownEvent(this this, this restTime); CountdownListener[] cdLList = ((CountdownListener[]) lList.getListeners(CountdownListener.class class)); class for (int int i = 0; i < cdLs.length; i++) { cdLs[i].countdownTimeElapsed(event); } } ... JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 17 Bound Properties Ereigniskonzept für die Benachrichtigung von Wertänderungen bei Properties Listener PropertyChangeListener public interface PropertyChangeListener extends EventListener { void propertyChange(PropertyChangeEvent evt); } Ereignisobjekt PropertyChangeEvent enthält alten und neuen Wert public class PropertyChangeEvent extends java.util.EventObject { public PropertyChangeEvent(Object source, String propertyName, Object oldValue, Object newValue) { ... } public String getPropertyName() { return propertyName; } public Object getNewValue() { return newValue; } public Object getOldValue() { return oldValue; } ... Anmeldung und Abmeldung über addPropertyChangeListener und removePropertyChangeListener; Implementierung mittels PropertyChangeSupport transient protected PropertyChangeSupport pchglisteners; public void addPropertyChangeListener(PropertyChangeListener l) { pchglisteners.addPropertyChangeListener(l); } public void removePropertyChangeListener(PropertyChangeListener l) { pchglisteners.removePropertyChangeListener(l); } JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 18 Constrained Properties Erlaubt anderen Objekten, Wertänderung bei Property zu verhindern Listener VetoableChangeListener: Methode vetoableChange wirft PropertyVetoException public interface VetoableChangeListener extends EventListener { void vetoableChange(PropertyChangeEvent evt) throws PropertyVetoException; } Anmeldung und Abmelden von Listeners; Implementierung über VetoableChangeSupport transient protected VetoableChangeSupport vchglistener = new VetoableChangeSupport(this); public void addVetoableChangeListener(VetoableChangeListener l) { vchglisteners.addVetoableChangeListener(l); } public void removeVetoableChangeListener(VetoableChangeListener l) { vchglisteners.removeVetoableChangeListener(l); } Setter-Methode soll PropertyVetoException werfen public void setValue(int int value) throws PropertyVetoException { int oldValue = this.value; this vchglisteners.fireVetoableChange("value", oldValue, value); this.value = value; this pchglisteners.firePropertyChange("value", oldvalue, value); } JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 19 Beispiel CountdownBean: CountdownBean PropertyChange-Ereignis PropertyChange PropertyChange-Ereignis bei Änderung der Countdown-Zeit public void setTime(int int time) { int oldValue = this.time; this this.time = time; this pchglisteners.firePropertyChange("time", oldValue, this.time); this } public void addTimeChangeListener(PropertyChangeListener listener) { pchglisteners.addPropertyChangeListener(listener); } public void removeTimeChangeListener(PropertyChangeListener listener) { pchglisteners.removePropertyChangeListener(listener); } JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 20 Beispiel CountdownBean: CountdownBean VetoableChange-Ereignis VetoableChange VetoableChange-Ereignis bei Setzen von langem und kurzem Intervall und Periode erlaubt Einspruch, wenn Werte nicht akzeptabel, z.B. wenn sie nicht zusammenpassen transient protected VetoableChangeSupport vchglisteners = new VetoableChangeSupport(this this); this ... public int getLongInterval() { return longInterval; } public void addVetoableChangeListener(VetoableChangeListener l) { vchglisteners.addVetoableChangeListener(l); } public void removeVetoableChangeListener(VetoableChangeListener l) { vchglisteners.removeVetoableChangeListener(l); } public void setLongInterval(int int interval) throws PropertyVetoException { vchglisteners.fireVetoableChange("longInterval", this.longInterval, interval); this longInterval = interval; } public void setShortInterval(int int interval) throws PropertyVetoException { vchglisteners.fireVetoableChange("shortInterval", this.shortInterval, interval); this this.shortInterval = interval; this } ... JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 21 Beispiel CountdownBean: CountdownBean start und run-Methoden run public void start() { restTime = getTime() * 1000; countdownThread = new Thread(this this); this countdownThread.start(); } public void run() { fireCountdownStartedEvent(); fireCountdownStartedEvent(); try { while (restTime > 0) { int timeToNextEvent; if (restTime <= getShortIntervalPeriod()) { timeToNextEvent = getShortInterval(); } else { timeToNextEvent = getLongInterval(); } if (timeToNextEvent > restTime) { timeToNextEvent = restTime; } Thread.sleep(timeToNextEvent); Thread.sleep(timeToNextEvent); restTime = restTime - timeToNextEvent; fireCountdownTimeElapsedEvent(); fireCountdownTimeElapsedEvent(); } fireCountdownFinishedEvent(); fireCountdownFinishedEvent(); } catch (InterruptedException ign) { } } ... JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 22 JavaBeans Grundlagen Eigenschaften Ereignisse Konfiguration JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 23 Introspection Introspector: versorgt Entwicklungsumgebung mit Informationen über Bean Analysiert Bean und eruiert Eigenschaften, Ereignisse und Methoden verwendet Reflection orientiert sich an den Programmierkonventionen erstellt daraus BeanInfo-Klasse BeanInfo-Klasse kann auch programmiert werden BeanInfo-Klasse • Klassenname = Name der Bean + "BeanInfo" • Implementiert Interface BeanInfo • Hilfsklasse SimpleBeanInfo mit leeren Methoden public interface BeanInfo { BeanInfo[] getAdditionalBeanInfo(); BeanDescriptor getBeanDescriptor(); int getDefaultEventIndex(); int getDefaultPropertyIndex(); EventSetDescriptor[] getEventSetDescriptors(); Image getIcon(int int iconKind); MethodDescriptor[] getMethodDescriptors(); PropertyDescriptor[] getPropertyDescriptors(); } JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 24 Konfiguration von Beans Benutzerdefinierter Editor • Konfiguration einer Eigenschaft oder aller Eigenschaften einer Klasse • Muss Interface PropertyEditor implementieren • Hilfsklasse PropertyEditorSupport • Zuordnung über Namenskonvention, PropertyEditorManager, BeanInfo Background blue Benutzerdefinierte Konfigurationsoberfläche • Konfiguration einer gesamten Bean • Muss Customizer implementieren und sollte Container erweitern • Anzeige in Dialogfenster oder Panel • Zuordnung zu Bean über BeanInfo JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 25 Beispiel CountdownBean: Anpassung in netBeans IDE JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 26 Beispiel CountdownBean: Anpassung mit Visual Editor Visual Editor (http://www.eclipse.org/vep/) ist ein Eclipse Tool für die visuelle interaktive Erstellung von GUIs JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 27 Verpacken von Beans JavaBean besteht aus mehreren Dateien • Auslieferung als JAR-Datei • z.B. Java-Klassen, Dokumentation, Bilder, Videos, … JAR-Werkzeug wird mit JDK mitgeliefert META-INF\MANIFEST.MF • Beschreibt Inhalt der JAR-Datei ManifestManifest-Version: 1.0 Name: sunw/demo/juggler/Juggler.class JavaJava-Bean: True CreatedCreated-By: 1.2.2 (Sun Microsystems Inc.) JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 28 Zusammenfassung Komponentenmodell von Java • Wiederverwendung Merkmale einer JavaBean • Eigenschaften • Ereignisse Manipulation in Entwicklungswerkzeug • Rapid Application Development • Introspection • PropertyEditors und Customizers JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 29 Literatur Java Beans Homepage: http://java.sun.com/products/javabeans/ JavaBeans 1.01 API Specification, Sun Microsystems, 1997, http://java.sun.com/products/javabeans/docs/spec.html Introduction to the JavaBeans API, Tutorials & Code Camps, http://java.sun.com/developer/onlineTraining/Beans/JBeansAPI/index.html JavaBeans 101 Tutorial, Tutorials & Code Camps, http://java.sun.com/developer/onlineTraining/Beans/bean01/index.html, http://java.sun.com/developer/onlineTraining/Beans/beans02/index.html Horstmann, Cornell, Core Java 2, Band 2 - Expertenwissen, Markt und Technik, 2002: Kapitel 8 Krüger, Handbuch der Java-Programmierung, 3. Auflage, Addison-Wesley, 2003, http://www.javabuch.de, Kapitel 44 JOHANNES KEPLER UNIVERSITY LINZ Research and teaching network Pratikum SWE 2 © M. Löberbauer, T. Kotzmann, H. Prähofer 30