Java Beans Tutorial
Java Beans Tutorial
September 1997
A Tutorial
Alden DeSoto
iii
WaterSource . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-2
Valve . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-3
Pipe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-5
Testing WaterSource, Valve, and Pipe . . . . . . . . . . . . . . . . . . . . . 3-6
Example Beans and Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-8
4. Customization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-1
Customizer Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-1
PropertyEditor Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-2
BeanInfo Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-2
Example Beans and Customization . . . . . . . . . . . . . . . . . . . . . . . 4-3
5. Persistence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-1
What to Save . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-1
Changes and Versioning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-1
6. Packaging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-1
MANIFEST file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-1
Example. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-1
Additional Jar and Manifest File Information . . . . . . . . . . . . . . 6-2
Beans are Java classes that can be manipulated in a visual builder tool and
composed together into applications. Any Java class that adheres to certain
property and event interface conventions can be a Bean. This short tutorial
provides simple examples of how to program to these conventions.
1-1
1
The BeanBox
The BeanBox is a sample container for testing Beans. The BeanBox handles
visible Beans, those Beans that have a visual element, and invisible Beans,
those Beans that are purely computational objects.
When you start the BeanBox, a ToolBox of sample Beans is displayed. Source
code for these Beans is provided in the demo\sunw\demo\ subdirectory of the
distribution.
C:>cd beanbox
C:>nmake run
editable
sample properties for
Beans the selected
Bean in BeanBox
Icon
represen-
tations are
specified in
the .gmk
files of some
Beans
Beans instantiated
from ToolBox
4. Connect the line to the Juggler and click the mouse button.
The BeanBox responds with an Event Target Dialog as shown below. Juggler
methods which either take no argument or which take an argument of type
actionPerformed are listed in this dialog.
6. Connect the “stop” button to the Juggler stop method in the same
fashion.
Test by pressing the “stop” button.
JARFILE= ..\jars\SimplestBean.jar
clean:
-del sunw\demo\simplest\SimplestBean.class
-del $(JARFILE)
SimplestBean instance of
added to ToolBox SimplestBean
in the BeanBox
The File|MakeApplet... menu item creates a JAR file containing serialized data
and class files, a test HTML file that uses the JAR file (and any other JAR file
needed), a subdirectory with Java sources and makefile, and a readme file with
complete information about the generated applet and all files involved. This
generated readme file contains much useful information.
The generated applet can be used in any JDK 1.1-compliant browser. A good
test platform is the JDK 1.1 appletviewer (see http://java.sun.com/jdk/1.1/).
Another fully compliant browser is the HotJava browser (see http://
java.sun.com/products/hotjava). The preview2 Internet Explorer 4.0 release
does not yet support JAR files, and you will have to expand the JAR and
HTML files that are generated. A deserialization bug causes components to not
listen to mouse events also. See the generated readme file for more
information. The generated applet will not work in Netscape Communicator
versions 4.0 and 4.01; versions with full JDK 1.1 support are expected later this
year.
To see how Make Applet works, instantiate the Juggler Bean and two buttons,
and connect them like you did at the beginning of this chapter.
1. The generated applet will have the same size as the BeanBox frame, so you
may want to start by adjusting the BeanBox size to the size of the applet you
want.
2. Choose File|Make Applet to bring up the above dialog. Use the default JAR
file and applet name for this example.
3. Press the OK button. You can inspect your handiwork by moving to the
beanbox/tmp/myApplet directory of your BDK installation.
Simple Properties
A simple property represents a single value and can be defined with a pair of
get/set methods. A property’s name is derived from the method names. For
example the method names setX and getX indicate a property named “X”. A
method name isX by convention indicates that “X” is a boolean property.
2-1
2
public class alden2 extends Canvas {
property will String ourString="Hello";
be called
ourString public alden2(){
setBackground(Color.red);
setForeground(Color.blue);
}
Indexed Properties
An indexed property represents an array of values. Property element get/set
methods take an integer index parameter. The property may also support
getting and setting the entire array at once.
Bound Properties
A bound property notifies other objects when its value changes. Each time its
value is changed, the property fires a PropertyChange event which contains
the property name, old, and new values. Notification granularity is per bean,
not per property.
Properties 2-3
2
public class alden5 extends Canvas {
String ourString="Hello";
declare and instantiate private PropertyChangeSupport changes =
a property change
object new PropertyChangeSupport(this);
public alden5()
{
setBackground(Color.red);
setForeground(Color.blue);
}
1. Instantiate a Bean with bound properties and any other Bean in the
Beanbox. Select the Bean with bound properties.
3. Connect the Bean with bound properties to the second Bean and select a
target method.
The BeanBox will add the second bean to the bound property Bean’s list of
listeners.
4. When the BeanBox has finished generating code, change the bound
property value in the PropertySheet.
The selected method on the listener bean will be invoked.
Properties 2-5
2
Constrained Properties
An object with constrained properties allows other objects to veto a
constrained property value change. Constrained property listeners can veto a
change by throwing a PropertyVetoException.
......
public
void removeVetoableChangeListener(VetoableChangeListener l) {
vetos.removeVetoableChangeListener(l);
}
......
}
Properties 2-7
2
This chapter uses three example Beans to explain Events: WaterSource, Valve,
and Pipe. A WaterSource drips one WaterEventObject per second to its list of
WaterListeners. The list of WaterListeners may include any number and/or
combination of Valves and Pipes. An open Valve passes on WaterEventObjects
that it receives to its own list of WaterListeners. A closed Valve does not pass
on any WaterEventObjects. A Pipe behaves in the same way as an open Valve.
(implements)
WaterSource Valve (implements)
vector WaterListeners Pipe
vector WaterListeners
vector WaterListeners
(1 event per second)
WaterEventObject WaterEventObject
3-1
3
WaterEventObject
public class WaterEventObject extends EventObject {
WaterListeners
check timeOfEvent long timeOfEvent;
to determine
whether it is more public WaterEventObject(Object o) {
than 2 seconds old. super(o);
timeOfEvent = System.currentTimeMillis();
}
WaterSource
public class WaterSource extends Canvas implements Runnable {
Valve
public class Valve extends Canvas implements WaterListener,
Runnable {
public Valve() {
setBackground(Color.white);
thread = new Thread(this);
thread.start();
}
Events 3-3
3
if (lastWaterEvent != null) {
make the valve white if long dt = System.currentTimeMillis() -
a WaterEventObject has lastWaterEvent.getTimeOfEvent();
not been recieved in the if ((dt > 2000) || (!isOpen())) {
last 2 seconds or if the setBackground(Color.white);
valve is closed repaint();
}
}
}
}
BeanBox will call these public synchronized void addWaterListener(WaterListener l) {
methods to add and waterListeners.addElement(l);
remove registered }
listeners
public synchronized void removeWaterListener(WaterListener l) {
waterListeners.removeElement(l);
}
void splash() {
send a water event to Vector l;
registered listeners
WaterEventObject weo = new WaterEventObject(this);
... method continued on
next page synchronized(this) {
l = (Vector)waterListeners.clone();
}
Pipe
public class Pipe extends Canvas implements WaterListener,
Runnable {
public Pipe() {
setBackground(Color.white);
thread = new Thread(this);
thread.start();
}
if (lastWaterEvent != null) {
make the pipe white if long dt = System.currentTimeMillis() -
a water event has not lastWaterEvent.getTimeOfEvent();
been received in the if (dt > 2000) {
last 2 seconds setBackground(Color.white);
repaint();
}
Events 3-5
3
}
}
}
public synchronized void addWaterListener(WaterListener l) {
BeanBox will call these waterListeners.addElement(l);
methods to add and }
remove registered
listeners
public synchronized void removeWaterListener(WaterListener l) {
waterListeners.removeElement(l);
}
void splash() {
WaterEventObject weo = new WaterEventObject(this);
Events 3-7
3
You can customize how a Bean appears and behaves within a builder
environment by using the Customizer, PropertyEditor, and BeanInfo interfaces
as described in this chapter.
Customizer Interface
Implement the java.beans.Customizer interface to provide your own GUI
implementation of the property sheet. For example, the OurButton bean in
demo\sunw\demo\buttons\ is packaged with a custom property sheet:
4-1
4
public void
removePropertyChangeListener(PropertyChangeListener l){
support.removePropertyChangeListener(l)
}
PropertyEditor Interface
Implement the PropertyEditor interface to create a custom editor for a specific
property. The MoleculeNameEditor class in demo\sun\demo\molecule\ of
the distribution provides a good example of this.
If you provide a custom property editor class, you must refer to this class with
a call to PropertyDescriptor.setPropertyEditorClass in a BeanInfo
class (see next section).
BeanInfo Interface
Each Bean class may have a BeanInfo class which customizes how the Bean is
to appear in a builder. The BeanInfo can define properties, methods, events,
with display names and short help.
Customization 4-3
4
What to Save
Generally, a Bean should store the state of any exposed properties. Selected
internal state variables may also be saved. Beans should not, however, store
pointers to external Beans.
5-1
5
If you need to make changes to a class which alter its persistence, you might
define a version id field which can be checked at runtime. For example,
JavaBeans are distributed through JAR files. A JAR file is a ZIP format archive
file that may optionally have a MANIFEST file. The MANIFEST describes the
contents of the JAR file. A JAR file may contain .class files, serialized Beans
(.ser), help files in HTML format, and resources (images , audio, text).
MANIFEST file
If a JAR file does not have a MANIFEST, then all classes and serialized objects
in the package are treated as beans. Providing a MANIFEST file allows you to
specify which classes are Beans via "Java-Bean: True" entries (see Example
below).
Example
This example .mk file illustrates the compiling and packaging of three Beans
and two auxiliary classes. This .mk file was used to package the example
discussed in chapter 3, “Events”.
6-1
6
CLASSFILES= \
sunw\demo\valves\WaterListener.class \
sunw\demo\valves\WaterSource.class \
sunw\demo\valves\Valve.class \
sunw\demo\valves\Pipe.class \
sunw\demo\valves\WaterEventObject.class
JARFILE= ..\jars\valves.jar
all: $(JARFILE)
Name: sunw/demo/valves/WaterListener.class
do not display
Java-Bean: False
in ToolBox
Name: sunw/demo/valves/WaterSource.class
Java-Bean: True
Name: sunw/demo/valves/Valve.class
Java-Bean: True
Name: sunw/demo/valves/Pipe.class
Java-Bean: True
clean:
-del sunw\demo\valves\*.class
-del $(JARFILE)