You are on page 1of 7

Java BeansContents

• Introduction
• The BeanBox
• Creating a Java Bean
• Support for Properties and Events
Related Links
Java Beans trail in the Java Tutorial - a good introduction to Java Beans.
Java Beans Development Kit (BDK) - provides a basic development support tool (called
the BeanBox) as well as several examples of Java Bean components. This link also
provides links to various commercial development environments for Java Beans.
Java Beans API - various interfaces, classes and exception types that you will encounter
when developing Java Beans.
1. Introduction
A Java Bean is a reusable software component that can be manipulated visually in an
application builder tool. The idea is that one can start with a collection of such
components, and quickly wire them together to form complex programs without actually
writing any new code.

Software components must, in general, adopt standard techniques for interacting with the
rest of the world. For example, all GUI components inherit the java.awt.Component
class, which means that one can rely on them to have certain standard methods like
paint(), setSize(), etc. Java Beans are not actually required to inherit a particular base
class or implement a particular interface. However, they do provide support for some or
all of the following key features

• Support for introspection. Introspection is the process by which an application


builder discovers the properties, methods and events that are associated with a
Java Bean.

• Support for properties. These are basically member variables that control the
appearance or behavior of the Java Bean.

• Support for customization of the appearance and behavior of a Java Bean.

• Support for events. This is a mechanism by which Java Beans can communicate
with one another.

• Support for persistent storage. Persistence refers to the abilility to save the
current state of an object, so that it can be restored at a later time.
2. The BeanBox
This is a basic tool that Sun provides for testing Java Beans. To run the BeanBox, your
computer needs to have access to a BDK installation. To run the BeanBox, go to the
beans/beanbox subdirectory and then type run. This will bring up three windows:

• The ToolBox window gives you a palette of sample Java Beans to choose from.
• The BeanBox window is a container within which you can visually wire beans
together.
• The Properties window allows you to edit the properties of the currently selected
Java Bean.

Try a simple example: choose Juggler bean from the ToolBox and drop an instance in the
BeanBox window. Also create two instances of OurButton. Edit the labels of the buttons
to read start and stop using the Properties window. Now wire the start button to the
juggler as follows. Select the start button, then go to Edit | Events | action |
actionPerformed. Connect the rubber band to the juggler. You will now see an
EventTargetDialog box with a list of Juggler methods that could be invoked when the
start button is pressed (these are the methods that either take an ActionEvent as an
argument or have no arguments at all.) Choose startJuggling as the target method and
press OK. The BeanBox now generates an adaptor class to wire the start button to the
juggler. Wire the stop button to the juggler's stopJuggling method in a similar manner.

Now that the program has been designed, you can run it within the BeanBox. Simply
press the start button to start juggling and press the stop button to stop juggling. If you
wish, you can turn your program into an applet by choosing File | MakeApplet in the
BeanBox. This will automatically generate a complete set of files for the applet, which
can be run in the appletviewer. (Do not expect current versions of Netscape and Internet
Explorer to work with this applet.)

Let's take a closer look at how the BeanBox works. On start up, it scans the directory
beans/jars for files with the .jar extension that contain Java Beans. These beans are
displayed in the ToolBox window, from where they can be selected and dropped into the
BeanBox window. Next, we edited the labels of the two instances of OurButton. The
BeanBox determined that OurButton has a member named label by looking for setter and
getter methods that follow standard naming conventions called design patterns. If you
look at the source code in beans\demo\sunw\demo\buttons\OurButton.java, you will see
that OurButton has two methods named

public void setLabel(String newLabel) {


...
}

public String getLabel() {


...
}
Design patterns are an implicit technique by which builder tools can introspect a Java
Bean. There is also an explicit technique for exposing properties, methods and events.
This involves writing a bean information class, which implements the BeanInfo interface.

When we wired the start button to the juggler, the BeanBox set up the juggler to respond
to action events generated by the start button. The BeanBox again used design patterns to
determine the type of events that can be generated by an OurButton object. The
following design patterns indicate that OurButton is capable of firing ActionEvents.

public synchronized void addActionListener(ActionListener l) {


...
}

public synchronized void removeActionListener(ActionListener l) {


...
}

By choosing Edit | Events | action | actionPerformed to connect the start button to the
juggler, we were really registering an ActionListener with the start button. The Juggler
bean itself is does not implement the ActionListener interface. Instead the BeanBox
generated an event hookup adaptor, which implements ActionListener and simply calls
the juggler's startJuggling method in its actionPerformed method:

// Automatically generated event hookup file.

package tmp.sunw.beanbox;
import sunw.demo.juggler.Juggler;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class ___Hookup_1474c0159e implements


java.awt.event.ActionListener, java.io.Serializable {

public void setTarget(sunw.demo.juggler.Juggler t) {


target = t;
}

public void actionPerformed(java.awt.event.ActionEvent arg0) {


target.startJuggling(arg0);
}

private sunw.demo.juggler.Juggler target;


}

A similar event hookup adaptor was generated when we wired the stop button to the
juggler's stopJuggling method.
Why not make Juggler implement the ActionListener interface directly? This is mainly a
matter of convenience. Suppose that Juggler implemented ActionListener and that it was
registered to receive ActionEvents from both the start button and the stop button. Then
the Juggler's actionPerformed method would need to examine incoming events to
determine the event source, before it could know whether to call startJuggling or
stopJuggling.

3. Creating a Java Bean


This example illustrates how to create a simple Java Bean. Java Bean classes must be
made serializable so that they support persistent storage. To make use of the default
serialization capabilities in Java, the class needs to implement the Serializable interface
or inherit a class that implements the Serializable interface. Note that the Serializable
interface does not have any methods. It just serves as a flag to say that the designer has
tested the class to make sure it works with default serialization. Here is the code:

SimpleBean.java

import java.awt.*;
import java.io.Serializable;

public class SimpleBean extends Canvas implements Serializable {


//Constructor sets inherited properties
public SimpleBean() {
setSize(60,40);
setBackground(Color.red);
}
}

Since this class extends a GUI component, java.awt.Canvas, it will be a visible Java
Bean. Java Beans may also be invisible.

Now the Java Bean must be compiled and packaged into a JAR file. First run the
compiler:

javac SimpleBean.java

Then create a manifest file

manifest.tmp

Name: SimpleBean.class
Java-Bean: True

Finally create the JAR file:


jar cfmv SimpleBean.jar manifest.tmp SimpleBean.class

The JAR file can now be placed in the beans/jars so that the BeanBox will find it on
startup, or it can be loaded subsequently by choosing File | LoadJar.

4. Support for Properties and Events


This example builds on the SimpleBean class. It illustrates how to add customizable
properties to a Java Bean and how to generate and receive property change events.

SimpleBean.java

import java.awt.*;
import java.io.Serializable;
import java.beans.*;

public class SimpleBean extends Canvas implements Serializable,


java.beans.PropertyChangeListener {

// Constructor sets inherited properties


public SimpleBean() {
setSize(60,40);
setBackground(Color.red);
}

// This section illustrates how to add customizable properties to the Java Bean. The
names
// of the property setter and getter methods must follow specific design patterns that
allow
// the BeanBox (or builder tool) to determine the name of the property variable upon

// introspection.

private Color beanColor = Color.green;

public void setBeanColor(Color newColor) {


Color oldColor = beanColor;
beanColor = newColor;
repaint();

// This relates to bound property support (see below).


changes.firePropertyChange("beanColor", oldColor, newColor);
}
public Color getBeanColor() {
return beanColor;
}

public void paint(Graphics g) {


g.setColor(beanColor);
g.fillRect(20,5,20,30);
}

// This section illustrates how to implement bound property support. Bound


property
// support allows other objects to respond when a property change occurs in this
Java
// Bean. Remember that each property setter method must fire a property change
event,
// so that registered listeners can be properly notified. The
addPropertyChangeListener
// and removePropertyChangeListener methods follow design patterns that indicate
the
// ability of this Java Bean to generate property change events. As it happens, these
// methods overide methods of the same names, which are inherited through
java.awt.Canvas.

private PropertyChangeSupport changes = new PropertyChangeSupport(this);

public void addPropertyChangeListener(PropertyChangeListener l) {


changes.addPropertyChangeListener(l);
}

public void removePropertyChangeListener(PropertyChangeListener l) {


changes.removePropertyChangeListener(l);
}

// This section illustrates how to implement a bound property listener, which will
allow this
// Java Bean to register itself to receive property change events fired by other
objects.
// Registration simply involves making a call to the other object's
addPropertyChangeListener
// method with this Java Bean as the argument. If you are using the BeanBox,
however, you
// will typically use the event hookup adaptor mechanism to receive the events. In
this case,
// you can set the target method to be the propertyChange method. (Another word
about the
// BeanBox: the Edit | bind property option is a useful way to make a property
change in one
// object automatically trigger a property change in another object. In this case, the
BeanBox
// will invoke the correct property setter using code in
sunw/beanbox/PropertyHookup.java.
// An adaptor class will not be generated in this case.)

public void propertyChange(PropertyChangeEvent evt) {


String propertyName = evt.getPropertyName();
System.out.println("Received property change event " + propertyName);
}
}

You might also like