Java Beans

JavaSoft Online Training has some good links to tutorials to learn and understand JavaBeans (and other topics). If you haven't already, you need to register and set up a password to get into the Java Developer Connection (JDC) page.

For people at Chico State, I have a copy of these locally and will be referencing them heavily throughout this page. Their copyright.
Table of contents for one of the tutorials And for even more tutorial information (reallybigindex.html) (JavaBeans under continued)
And for those of you who asked Java Enterprise Beans tutorial
In addition to the tutorials, notes on this page reference page numbers in the 1.1 version of Core Java Volume II and the second edition of Java in a Nutshell. Although the page numbers may differ in later editions of Core Java, the material is the same.

Definition: What is a Bean?

If you have used Delphi, or Visual Basic, you are already familiar with the notion of a bean. The idea is the same; the programming language is different. A Java Bean is a reusable software component that works with Java. More specifically: a Java Bean is a reusable software component that can be manipulated in visual design tools. Beans may be visible objects, like AWT components, or invisible objects, like queues and stacks. A builder/integration tool manipulates Beans to create applets and applications.

Definition: A Java Bean is a reusable software component that can be visually manipulated in builder tools. To understand the precise meaning of this definition of a Bean, clarification is required for the following terms:

discussion

Basic Bean Concepts and Let's Make Some Beans!

The simplest kind of a bean is really nothing more than a java class that follows some fairly strict naming conventions for its event listeners and its methods.

There is no base bean class that you need to extend to build beans. "Visual beans obviously have too extend from Component or a subclass of Component, but non-visual beans can simply extend implicitly from Object. Remember that a bean is simply any class that can be manipulated in a visual design tool." (Core Java V2)

The best way to build a bean is to start with a simple example. Start with the most basic possible bean, then add a property to it. First the basic bean (Acme01Bean ...hmmm actually resize(int, int) was deprecated and we need setSize(int, int)) and a little more interesting basic bean

Another "simple example" can be found in Java in a Nutshell the MultiLineLabel. Note a couple of things in this example:

Beans Architecture

A bean consists of and "exports" three things:

Properties

Properties define the characteristics of the Bean; a property is a piece of the bean's internal state that can be programmatically set and queried, usually through a standard set of accessor: get and mutator: set methods. Obviously, since these methods change the state of the Bean, Beans need to be able to be persistent over time. Review: What does that mean?

Discussion:

In general, a method or methods in the following design pattern defines a property:

Where PropertyName is the name of the property, and PropertyType is its datatype. If only a get method is present, the property is read-only (set missing) (similarly, write-only if get missing).

There is one exception to the get/set naming pattern. Properties that have Boolean values should use a naming convention as follows:

Also be careful with the capitalization pattern you use for your method names. JavaSoft decided that the name of the property in the above example would be propertyName, with a lowercase p, even though the get and set methods contain uppercase P (getPropertyName, setPropertyName). The bean analyzer performs a process called decapitalization to derive the property name. (Core Java, V2).

The above (lowercase propetyName) is what shows up on the properties list in the BeanTool. In reality, the actual name of the instance variable modified or retrieved by the pair does not matter! This actually makes perfect sense, since the properties for the property list are determined by the introspection mechanism in the BeanBox finding the method get/set patterns that define the properties which are to be capable of visual manipulation. Adding Properties and Acme02Bean.java

Also, the MultiLineLabel.java from "Java in a Nutshell" defined variables:

and methods used

"Java in a Nutshell" 2nd Edition has a table for Naming Patterns and Conventions...we will see specifics of some of these in the following.

Note (if you looked at the naming conventions) the different types of properties:

Simple

A simple property is one that takes a single value such as a string or number. The fileName property of the ImageViewer is an example.

Notice the read-only property of this bean ( getPreferredSize()). You would not normally be able to see read-only properties at design time in a Property Sheet.

Note all of the NOTEs and TIPs in CoreJavaVol2. Make sure to initialize private data members explicitly...

Indexed

An indexed property is any property that has an array value and for which the bean provides methods to get and set individual elements in the array, as well as methods to get and set the entire array.

With indexed properties, you supply two pairs of get/set methods. The design pattern for these properties is:

In particular, in Core Java, the ChartBean is an example. Look at it in the Beanbox. (v2ch7, v2ch8) And also the Bean , the Bean being edited , the Bean changed See Core Java. Also note NOTE (seems to be corrected now but still says problem in Java2 book)).

Bound

A bound property is one that sends out a notification event when its value changes.

Suppose there is a property in an object that a number of different objects want to know about. The example in the tutorial (changing an Employee Bean's salary property) is an example of a bound property. Here, they suggest that both the boss and the spouse would want to know. Geez.

Things to note to make this idea simple

  1. The property to be changed is in one object (say the employee)
  2. This class would be the one to set and get the actual salary value
  3. This class would be the one to say who else should know (be a Listener)However, note that the actual management is ultimately done by a support class so,
  4. This class would be the one to instantiate a support class to keep track of Listeners and ultimately delegate the task of adding and removing property change listeners
  5. This class (the PropertyChangeSupport) would be the one to actually fire a PropertyChangeEvent (delegated through the support class) to notify listeners of the change when it gets set
  6. Listener classes would need to implement the listener , in this case (PropertyChangeListener) and they need to provide code for the method to handle the event.
If your bean extends any Swing class that ultimately extends the JComponent class, then you do not need to implement the addPropertyChangeListener and removePropertyChangeListener methods. These methods are already implemented in the JComponent superclass.

For examples, I will show both not using Swing and using Swing. I think it is good to see everything implemented to get a good feel for what is there.

The fileName in the FileNameBean is an example. When the file name changes, then the ImageViewerBean is automatically notified and it loads the new file.

An example of items 3 and 4 (above) from this bean is seen in the code from the FileNameBean class:
The java.beans package has a convenience class, called PropertyChangeSupport that manages the listeners.

and item 5:

And here is the Swing FileNameBean ( edition 7) and its ImageViewerbean ( edition 7)
Note

  public void setFileName(String newValue)
   {  String oldValue = nameField.getText();
      firePropertyChange("fileName", oldValue, newValue);
      nameField.setText(newValue);
   }
The class inherits the firePropertyChange method (and the add and remove Listeners) from its superclass JComponent JPanel. (See note in CoreJava)

Basically, for bound properties we see two new mechanisms:

Then the firePropertyChange() method of the PropertyChangeSupport object is used to deliver an event to all the registered listeners. Note:

pcs.firePropertyChange("fileName",oldValue, newValue); in the setFileName method. The values must be objects (so wrap if not).

Don't forget, other beans that want to be notified must implement the PropertyChangeListener interface - which means implement the propertyChange method.

Note in the Core Java book that their example of the FileNameBean having a bound property with the ImageViewerBean listening is rather strange. Why? the ImageViewerBean does not implement the PropertyChangeListener interface.

The book says the, "In this case the BeanBox registered itself as a property change listener to the FileNameBean, and it called the setFileName method of the ImageViewerBean." I don't know about you, but I don't like this... For a "homework",
Never mind - changes in 1.4 for the listeners and support

Demo: (the FileName bindproperty filename to the ImageViewer filename)
added Beans, FileNameBean, ImageViewerBean , fileNameChooser , BindProperty , BindPropSourceChoices , BindTargetProperty , A selected image

Finally, a given Bean may be a listener for more that one object. Make sure your listener's propertyChange method checks the property name via getPropertyName to see if you received the PropertyChangeEvent you were expecting.

Another finally: for a bean to generate or receive property change events, you must add the following import statements to the top of the file.

Constrained

A constrained property is a property that sends out a notification event when its value changes and allows the change to be vetoed by listeners. example

Constrained properties should also, obviously, be bounded since some other bean might be notified (via the event) to potentially perform this veto. Apparently, this is not a "requirement":

IntTextBean , IntTextBean Properties , RangeBean , vetoChange , RangeBean Properties

The RangeBean has two IntTextBeans that are constrained such that the "from" field must be smaller than the "to" field. It will not let you change otherwise (reverts back to original number) and the console where you opened the beanbox says:

WARNING: Vetoed; reason is: from > to

Make sure to check the VetoableChangeListener before the PropertyChangeListener so that you don't change the property value until all the registered vetoable listeners have agreed. Conversely, a vetoable change listener should never assume that a change that it agrees with is actually happening. The only reliable way to get notified when a change is actually happening is through a property change listener.

So, constrained have the same needs as bounded with a couple more requirements. Specifically, as before:

  1. The property to be changed is in one object (say the employee)
  2. This class would be the one to set and get the actual salary value Here the setPropertyName method throws PropertyVetoException;
  3. This class would be the one to say who else should know (be a Listener)However, note that the actual management is ultimately done by a support class so,
  4. This class would be the one to instantiate a support class to keep track of Listeners and ultimately delegate the task of adding and removing property and vetoable change listeners
  5. This class would be the one to actually fire an event (delegated through the support class) to notify listeners of the change when it tries to get set
  6. Listener classes would need to implement the listener , in this case (PropertyChangeListener) and (VetoableChangeListener) and they need to provide code for the method to handle the event.
In step 3, rather than providing one listener for all property change events, and another for all vetoable change events, you can elect to maintain separate lists of listeners for each property ( PropertyName). The design pattern for this is: So what are we talking about?

Vetoable properties can be thought of as a producer (someone is using the interface and wants to produce a new value for this Object/variable) and a consumer (only certain values are allowable so the consumer can veto). So here, a bean must notify its consumers of the new value and give the consumers a chance to veto the change. Thus, additional VetoableChangeListeners (receivers) are needed.

Often, the Object that implements the veto is a container (has IVs) of the Objects that are going to be changed.

For example, the the IntTextBean is the producer of the vetoable event (it is the Object that is changing) and the RangeBean is the consumer.

In IntTextBean (1) note one can edit from the property field (setValue) or (2) the text field; see the low-level event handling of the text field. Note also that the editComplete catches the exception thrown from the firePropertyChange/vetoableChange call whereas the setValue does not (the Beanbox again???- someone must catch it to make the value go back)

If change from text-field, doesn't really change unless valid, but doesn't veto either. getFocus() is inherited from Component and "Requests that this component get the input focus." Changes in property list occur immediately in text-field or immediately give veto (note where exception is handled). Changes in text-field are only shown in property list if valid. This is all OK (i.e., works) but I think something is not working correctly since they both ultimately throw PropertyVetoException in vetoableChange method

Also notice in the Listener (RangeBean) (which contains the IntTextBeans instances of to and from):

Notice, again, the lack of a PropertyChangeListener and propertyChange method. Beanbox??

The JComponent versions are here: the IntTextBean and the RangeBean . Tips from Core Java:
The JComponent class has some support for constrained properties, but it is not as extensive as that for bound properties. The JComponent class keeps a single listener list for vetoable change listeners, but not a separate list for each property. And the fireVetoableChange method is not overloaded for basic types. If your bean extends JComponent and has a single constrained property then the listener support of the JComponent superclass is entirely adequate, and you do not need a separate VetoableChangeSupport object.

This page is getting too long. See this page for the rest of the Beans story.