This module took you inside a Bean to learn about the structure and organization of data and methods,
the two primary parts of a Bean.
You learned a great deal about properties, the Bean data made available externally via accessor methods.
The different types of properties were explored,
which include
- simple properties,
- indexed properties,
- bound properties, and
- constrained properties.
You finished the module by creating a property and its associated accessor methods.
An indexed property is an array instead of a single value. In this case, the bean class provides a method for getting and setting the entire array. Here is an example for an int[] property called testGrades:
public int[] getTestGrades() {
return mTestGrades;
}
public void setTestGrades(int[] tg) {
mTestGrades = tg;
}
For indexed properties, the bean class also provides methods for getting and setting a specific element of the array.
public int getTestGrades(int index) {
return mTestGrades[index];
}
public void setTestGrades(int index, int grade) {
mTestGrades[index] = grade;
}
Bound Properties
A bound property notifies listeners when its value changes. This has two implications:
- The bean class includes addPropertyChangeListener() and removePropertyChangeListener() methods for managing the bean's listeners.
- When a bound property is changed, the bean sends a PropertyChangeEvent to its registered listeners.
PropertyChangeEvent and PropertyChangeListener live in the java.beans package.
The java.beans package also includes a class, PropertyChangeSupport, that takes care of most of the work of bound properties.
This handy class keeps track of property listeners and includes a convenience method that fires property change events to all registered listeners. The following example shows how you could make the mouthWidth property a bound property using PropertyChangeSupport. The necessary additions for the bound property are shown in bold.
import java.beans.*;
public class FaceBean {
private int mMouthWidth = 90;
private PropertyChangeSupport mPcs = new PropertyChangeSupport(this);
public int getMouthWidth() {
return mMouthWidth;
}
public void setMouthWidth(int mw) {
int oldMouthWidth = mMouthWidth;
mMouthWidth = mw;
mPcs.firePropertyChange("mouthWidth", oldMouthWidth, mw);
}
public void
addPropertyChangeListener(PropertyChangeListener listener) {
mPcs.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
mPcs.removePropertyChangeListener(listener);
}
}
Bound properties can be tied directly to other bean properties using a builder tool like NetBeans.
You could, for example, take the value property of a slider component and bind it to the mouthWidth property shown in the example. NetBeans allows you to do this without writing any code.
Constrained Properties
A constrained property is a special kind of bound property. For a constrained property, the bean keeps track of a set of veto listeners.
When a constrained property is about to change, the listeners are consulted about the change. Any one of the listeners has a chance to veto the change, in which case the property remains unchanged.
The veto listeners are separate from the property change listeners. Fortunately, the java.beans package includes a VetoableChangeSupport class that greatly simplifies constrained properties.
Changes to the mouthWidth example are shown in bold:
import java.beans.*;
public class FaceBean {
private int mMouthWidth = 90;
private PropertyChangeSupport mPcs =
new PropertyChangeSupport(this);
private VetoableChangeSupport mVcs =
new VetoableChangeSupport(this);
public int getMouthWidth() {
return mMouthWidth;
}
public void setMouthWidth(int mw) throws PropertyVetoException {
int oldMouthWidth = mMouthWidth;
mVcs.fireVetoableChange("mouthWidth",
oldMouthWidth, mw);
mMouthWidth = mw;
mPcs.firePropertyChange("mouthWidth", oldMouthWidth, mw);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
mPcs.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
mPcs.removePropertyChangeListener(listener);
}
public void addVetoableChangeListener(VetoableChangeListener listener) {
mVcs.addVetoableChangeListener(listener);
}
public void removeVetoableChangeListener(VetoableChangeListener listener) {
mVcs.removeVetoableChangeListener(listener);
}
}
Bean Internals - Quiz
Before you move on to the next module, make sure to click the Quiz link below to take a multiple-choice quiz that has questions addressing all of the
lessons worked on through in this module.
Bean Internals - Quiz
In the next module, Bean internals will be analyzed by learning about design patterns and introspection.
You will also build your first complete Bean in the next module, which is a pretty important leap from theory to application.