Team LiB
Previous Section Next Section

7.4. JavaBeans Conventions

JavaBeans is a framework for defining reusable modular software components. The JavaBeans specification includes the following definition of a bean: "a reusable software component that can be manipulated visually in a builder tool." As you can see, this is a rather loose definition; beans can take a variety of forms. The most common use of beans is for graphical user interface components, such as components of the java.awt and javax.swing packages, which are documented in Java Foundation Classes in a Nutshell and Java Swing, both from O'Reilly. Although all beans can be manipulated visually, this does not mean every bean has its own visual representation. For example, the javax.sql.RowSet class (documented in O'Reilly's Java Enterprise in a Nutshell) is a JavaBeans component that represents the data resulting from a database query. There are no limits on the simplicity or complexity of a JavaBeans component. The simplest beans are typically basic graphical interface components, such as a java.awt.Button object. But even complex systems, such as an embeddable spreadsheet application, can function as individual beans.

The JavaBeans component model consists of the java.beans, the java.beans.beancontext packages, and a number of important naming and API conventions to which conforming beans and bean-manipulation tools must adhere. These conventions are not part of the JavaBeans API itself but are in many ways more important to bean developers than the API itself. The conventions are sometimes referred to as design patterns; they specify such things as method names and signatures for property accessor methods defined by a bean. If the class you are writing is not intended to be a bean, suitable for visual manipulation in a builder tool, you don't need to follow these conventions. The JavaBeans conventions are widely used and well-understood, however, and you can improve the usability and reusabilty of your code by following the relevant ones. This is particularly true of the property accessor method naming conventions.

We cover the conventions themselves later in this section. First, however, an overview of the JavaBeans model is in order.

7.4.1. Bean Basics

Any object that conforms to certain basic rules can be a bean; there is no Bean class that all beans are required to subclass. Many beans are GUI components, but it is also quite possible, and often useful, to write "invisible" beans that do not have an onscreen appearance. (A bean having no onscreen appearance in a finished application does not mean it cannot be visually manipulated by a beanbox tool, however.)

A bean is characterized by the properties, events, and methods it exports. It is these properties, events, and methods that an application designer manipulates in a beanbox tool. A property is a piece of the bean's internal state that can be programmatically set and/or queried, usually through a standard pair of get and set accessor methods.

A bean communicates with the application in which it is embedded as well as with other beans by generating events. The JavaBeans API uses the same event model that AWT and Swing components use. The model is based on the java.util.EventObject class and the java.util.EventListener interface; it is described in detail in Java Foundation Classes in a Nutshell (O'Reilly). In brief, the event model works like this:

  • A bean defines an event if it provides add and remove methods for registering and deregistering listener objects for that event.

  • An application that wants to be notified when an event of that type occurs uses these methods to register an event listener object of the appropriate type.

  • When the event occurs, the bean notifies all registered listeners by passing an event object that describes the event to a method defined by the event listener interface.

A unicast event is a rare kind of event for which there can be only a single registered listener object. The add registration method for a unicast event throws a TooManyListenersException if an attempt is made to register more than a single listener.

The methods exported by a bean are simply any public methods defined by the bean, excluding those methods that get and set property values and register and remove event listeners.

In addition to the regular sort of properties described earlier, the JavaBeans API also supports several specialized property subtypes. An indexed property is a property that has an array value, as well as getter and setter methods that access both individual elements of the array and the entire array. A bound property is one that sends a PropertyChangeEvent to any interested PropertyChangeListener objects whenever the value of the property changes. A constrained property is one that can have any changes vetoed by any interested listener. When the value of a constrained property of a bean changes, the bean must send out a PropertyChangeEvent to the list of interested VetoableChangeListener objects. If any of these objects throws a PropertyVetoException, the property value is not changed, and the PropertyVetoException is propagated back to the property setter method.

7.4.2. Bean Classes

A bean class itself must adhere to the following conventions:


Class name

There are no restrictions on the class name of a bean.


Superclass

A bean can extend any other class. Beans are often AWT or Swing components, but there are no restrictions.


Instantiation

A bean should provide a no-parameter constructor so bean manipulation tools can easily instantiate the bean.

7.4.3. Properties

A bean defines a property p of type T if it has accessor methods that follow these patterns (if T is boolean, a special form of getter method is allowed):


Getter

public T getP( )


Boolean getter

public boolean isP( )


Setter

public void setP(T)


Exceptions

Property accessor methods can throw any type of checked or unchecked exceptions.

7.4.4. Indexed Properties

An indexed property is a property of array type that provides accessor methods that get and set the entire array as well as methods that get and set individual elements of the array. A bean defines an indexed property p of type T[ ] if it defines the following accessor methods:


Array getter

public T[ ] getP()


Element getter

public T getP(int)


Array setter

public void setP(T[])


Element setter

public void setP(int,T)


Exceptions

Indexed property accessor methods can throw any type of checked or unchecked exceptions. They should throw an ArrayIndexOutOfBoundsException if the supplied index is out of bounds.

7.4.5. Bound Properties

A bound property is one that generates a PropertyChangeEvent when its value changes. Here are the conventions for a bound property:


Accessor methods

The getter and setter methods for a bound property follow the same conventions as a regular property.


Listener registration

A bean that defines one or more bound properties must define a pair of methods for the registration of listeners that are notified when any bound property value changes. The methods must have these signatures:

public void addPropertyChangeListener(PropertyChangeListener)
public void removePropertyChangeListener(PropertyChangeListener)


Named property listener registration

A bean can optionally provide additional methods that allow event listeners to be registered for changes to a single bound property value. These methods are passed the name of a property and have the following signatures:

public void addPropertyChangeListener(String, PropertyChangeListener)
public void removePropertyChangeListener(String, PropertyChangeListener)


Per-property listener registration

A bean can optionally provide additional event listener registration methods that are specific to a single property. For a property p, these methods have the following signatures:

public void addPListener(PropertyChangeListener)
public void removePListener(PropertyChangeListener)

Methods of this type allow a beanbox to distinguish a bound property from an unbound property.


Notification

When the value of a bound property changes, the bean should update its internal state to reflect the change and then pass a PropertyChangeEvent to the propertyChange() method of every PropertyChangeListener object registered for the bean or the specific bound property.


Support

java.beans.PropertyChangeSupport is a helpful class for implementing bound properties.

7.4.6. Constrained Properties

A constrained property is one for which any changes can be vetoed by registered listeners. Most constrained properties are also bound properties. Here are the conventions for a constrained property:


Getter

The getter method for a constrained property is the same as the getter method for a regular property.


Setter

The setter method of a constrained property throws a PropertyVetoException if the property change is vetoed. For a property p of type T, the signature looks like this:

public void setP(T) throws PropertyVetoException


Listener registration

A bean that defines one or more constrained properties must define a pair of methods for the registration of listeners that are notified when any constrained property value changes. The methods must have these signatures:

public void addVetoableChangeListener(VetoableChangeListener)
public void removeVetoableChangeListener(VetoableChangeListener)


Named property listener registration

A bean can optionally provide additional methods that allow event listeners to be registered for changes to a single constrained property value. These methods are passed the name of a property and have the following signatures:

public void addVetoableChangeListener(String, VetoableChangeListener)
public void removeVetoableChangeListener(String, VetoableChangeListener)


Per-property listener registration

A bean can optionally provide additional listener registration methods that are specific to a single constrained property. For a property p, these methods have the following signatures:

public void addPListener(VetoableChangeListener)
public void removePListener(VetoableChangeListener)


Notification

When the setter method of a constrained property is invoked, the bean must generate a PropertyChangeEvent that describes the requested change and pass that event to the vetoableChange( ) method of every VetoableChangeListener object registered for the bean or the specific constrained property. If any listener vetoes the change by throwing a PropertyVetoException, the bean must send out another PropertyChangeEvent to revert the property to its original value. It should then throw a PropertyVetoException itself. If, on the other hand, the property change is not vetoed, the bean should update its internal state to reflect the change. If the constrained property is also a bound property, the bean should notify PropertyChangeListener objects at this point.


Support

java.beans.VetoableChangeSupport is a helpful class for implementing constrained properties.

7.4.7. Events

In addition to PropertyChangeEvent events generated when bound and constrained properties are changed, a bean can generate other types of events. An event named E should follow these conventions:


Event class

The event class should directly or indirectly extend java.util.EventObject and should be named EEvent.


Listener interface

The event must be associated with an event listener interface that extends java.util.EventListener and is named EListener.


Listener methods

The event listener interface can define any number of methods that take a single argument of type EEvent and return void.


Listener registration

The bean must define a pair of methods for registering event listeners that want to be notified when an E event occurs. The methods should have the following signatures:

public void addEListener(EListener)
public void removeEListener(EListener)


Unicast events

A unicast event allows only one listener object to be registered at a single time. If E is a unicast event, the listener registration method should have this signature:

public void addEListener(EListener) throws TooManyListenersException

    Team LiB
    Previous Section Next Section