15.6 Defining a Simple Property Editor
A bean can also provide auxiliary
PropertyEditor classes for use by a beanbox tool.
PropertyEditor is a flexible interface that allows
a bean to tell a beanbox how to display and edit the values of
certain types of properties.A beanbox tool always provides simple
property editors for common property types, such as strings, numbers,
fonts, and colors. If your bean has a property of a nonstandard type,
however, you should register a property editor for that type. The
easiest way to "register" a
property editor is through a simple naming convention. If your type
is defined by the class X, the editor for
it should be defined in the class X
Editor. Alternatively, you can register a property
editor by calling the PropertyEditorManager.registerEditor(
) method, probably from the constructor of your
BeanInfo class. If you call this method from the
bean itself, the bean then depends on the property editor class, so
the editor has to be bundled with the bean in applications, which is
not desirable. Another way to register a property editor is by using
a PropertyDescriptor object in a
BeanInfo class to specify the
PropertyEditor for a specific property. The
YesNoPanelBeanInfo class does this for the
messageText property, for example.The PropertyEditor
interface can seem confusing at first. Its methods allow you to
define three techniques for displaying the value of a property and
two techniques for allowing the user to edit the value of a property.
The value of a property can be displayed:
- As a string
If you define the
getAsText( ) method, a beanbox can convert a
property to a string and display that string to the user.- As an enumerated value
If a property can take only on values from a fixed set of values, you
can define the getTags( ) method to allow a
beanbox to display a drop-down menu of allowed values for the
property.- In a graphical display
If you define
paintValue( ), a beanbox can ask the property
editor to display the value using some natural graphical format, such
as a color swatch for colors. You also need to define
isPaintable( ) to specify that a graphical format
is supported.
The two editing techniques are:
- String editing
If you define the setAsText( ) method, a beanbox
knows it can simply have the user type a value into a text field and
pass that value to setAsText( ). If your property
editor defines getTags( ), it should also define
setAsText( ), so that a beanbox can set the
property value using the individual tag values.- Custom editing
If your property editor defines
getCustomEditor( ), a beanbox can call it to
obtain some kind of GUI component that can be displayed in a dialog
box and serve as a custom editor for the property. You also need to
define supportsCustomEditor( ) to specify that
custom editing is supported.
The
setValue( ) method of a
PropertyEditor is called to specify the current
value of the property. It is this value that should be converted to a
string or graphical representation by getAsText( )
or paintValue( ).A
property editor must maintain a list of event listeners that are
interested in changes to the value of the property. The
addPropertyChangeListener( ) and
removePropertyChangeListener( ) methods are
standard event-listener registration and removal methods. When a
property editor changes the value of a property, either through
setAsText( ) or through a custom editor, it must
send a PropertyChangeEvent to all registered
listeners.PropertyEditor
defines the getJavaInitializationString( ) for use
by beanbox tools that generate Java code. This method should return a
fragment of Java code that can initialize a variable to the current
property value.Finally, a class that implements the
PropertyEditor interface must have a no-argument
constructor, so it can be dynamically loaded and instantiated by a
beanbox. Most property editors can be much simpler
than this detailed description suggests. In many cases, you can
subclass PropertyEditorSupport instead of
implementing the PropertyEditor interface
directly. This useful class provides no-op implementations of most
PropertyEditor methods. It also implements the
methods for adding and removing event listeners.A
property that has an enumerated value requires a simple property
editor. The alignment property of the
YesNoPanel bean is an example of this common type
of property. The property has only the three legal values defined by
the Alignment class. The
AlignmentEditor class shown in Example 15-7 is a property editor that tells a beanbox how
to display and edit the value of this property. Because
AlignmentEditor follows a JavaBeans naming
convention, a beanbox automatically uses it for any property of type
Alignment.
Example 15-7. AlignmentEditor.java
package je3.beans;
import java.beans.*;
import java.awt.*;
/**
* This PropertyEditor defines the enumerated values of
the alignment property
* so that a bean box or IDE can present those values to
the user for selection
**/
public class AlignmentEditor extends PropertyEditorSupport {
/** Return the list of value names for the enumerated type. */
public String[ ] getTags( ) {
return new String[ ] { "left", "center", "right" };
}
/** Convert each of those value names into the actual value. */
public void setAsText(String s) {
if (s.equals("left")) setValue(Alignment.LEFT);
else if (s.equals("center")) setValue(Alignment.CENTER);
else if (s.equals("right")) setValue(Alignment.RIGHT);
else throw new IllegalArgumentException(s);
}
/** This is an important method for code generation. */
public String getJavaInitializationString( ) {
Object o = getValue( );
if (o == Alignment.LEFT)
return "je3.beans.Alignment.LEFT";
if (o == Alignment.CENTER)
return "je3.beans.Alignment.CENTER";
if (o == Alignment.RIGHT)
return "je3.beans.Alignment.RIGHT";
return null;
}
}