Creating properties

When you create properties for your component, component users can see and manipulate those properties at design time. They can edit properties in the Component Inspector and see those changes reflected immediately in the UI Designer. Using properties makes use of good object-oriented design principles, providing significant advantages beyond making a component's data members public.

These are the main subjects involved in creating properties:


Fast track to creating properties

A typical component property has three main elements:

If a property is read-only, it has a read accessor method but no write method. If the property is based upon a calculation or other operation, the property does not have a data member. JBuilder's Component Inspector does not display read-only properties; it supports properties that have both read and write access.

To create a typical property for a component,

  1. Declare and write the property's accessor methods, following JavaBeans naming conventions.
  2. Declare a variable or instantiate an object to hold the desired information about your component's state. Unless you have a very good reason not to, declare this data member private.
  3. Set the property's initial or default value.
  4. If a property editor for the type of your property doesn't exist, write a special property editor and assign it to the property.

For more fast-track information about creating properties, see Creating JavaBeans with BeansExpress.

See also:
Component properties
Controlling access to property fields
Writing property editors


Defining component properties

Any data type that a method can return is a legitimate data type for a component property. A property can be of any primitive Java data type or any object. You define a component property by


Defining simple properties

Simple property types are numeric, character, and string properties that appear in the Component Inspector as numbers, characters, and strings. The user edits the value of a simple property in the Component Inspector.

Writing accessor methods

You must name accessor methods, commonly called read and write methods, with the property name preceded by "get" or "set". Thus, the size property has the accessor methods getSize() and setSize().

The exceptions to this rule are boolean properties. Instead of "get", precede a boolean property's name with "is". Use "set" to write to a boolean property.

Accessor methods must be declared public for the Component Inspector to recognize them. Implement the accessor methods the same way you would any other method.


Declaring the read accessor method

Declare the read accessor method for Java primitives and objects as follows:
public <type> get<propertyName>();

The following describes the elements in the declaration:

public
The property must be public for it to appear in the Component Inspector.
<type>
The read or get method returns the type of the property, such as int. If the property is an object, this method returns the object.
get<propertyName>
Name the read method by adding a lowercase "get" to the property name and capitalizing its first letter. Replace <propertyName> with the name of the property. (If your property accessor methods are not declared according to the standard naming conventions, you can use the optional BeanInfo interface to explain them to the Component Inspector.)

Note: boolean properties have a special read accessor method. The property name is preceded by the word "is":

is<propertyName>


Declaring the write accessor method

Declare the write accessor method for Java primitives and objects as follows:
public void set<propertyName>(<type> <value>);

The following describes the elements in the declaration:

public
The property must be public for it to appear in the Component Inspector.
void
The write or set method always returns void.
set<property>
Name the write method by adding a lowercase "set" to the property name and capitalizing its first letter. Replace <propertyName> with the name of the property. (If your property accessor methods are not declared according to the standard naming conventions, you can use the optional BeanInfo interface to explain them to the Component Inspector.)
<type> <value>
The write method takes an argument of the same type as the property. For example, setCount(int count). If the property is an object, this method takes an object argument.

Declaring property fields

Declare a property data member, or field, exactly as you would any other variable or member object. If it is a simple variable, you can declare it and assign its default value in the same statement. If the property is an object, instantiate it in your component as you would any other. The following declares and initializes a boolean variable to hold the state of the property enabled:
private boolean enabled = true;

The following code instantiates a Color object to hold the state of the property myColor:

private Color myColor = new Color(0,0,0); //myColor is currently black.

Note
The JavaBeans specification provides both a display name and a programmatic name for properties and events. The display name is localized while the programmatic name is locale independent. For example, a locale-independent, programmatic name for a property might be shapeColour. The access methods would be getShapeColour and setShapeColour. In the United States, the localized display name might be shapeColor. You can specify both programmatic and display names for your bean using the FeatureDescriptor class, but only the programmatic name appears in JBuilder's Component Inspector; the display name is not supported.

Setting the access level for property fields

Properties are often data members of a component; therefore, you can set the visibility of the data member to whatever level is appropriate for your component. This setting controls direct access to the data member by other objects.

Generally, you should declare your property data members private to protect them from direct access. If the field is private, the only way the component user can change the property value is by calling one of its accessor methods; therefore the user is unlikely to change its value unintentionally.

The accessor methods might need to notify other objects that the property has been set. You can also use accessor methods to perform other critical work you want done any time the property value has changed.

For example, suppose a dialog box has a button that is dimmed because its functionality is unavailable. When the state of the application changes, the button's function becomes available. The application object whose state changed calls the button's setEnabled() method and changes that property to true. But the setEnabled() method also includes a call to repaint() so that the button appears normal and the application user knows that the command is now available. If the application object changed enabled by directly assigning a new value, the call to repaint() would never occur.

See also:
Writing accessor methods

Setting default property values

When you declare a property, you should assign it a default value. The default value for a component property is the value that is set for the property in the component constructor. When you drop a component from the Component Palette in a container, JBuilder creates the component by calling the component constructor, which determines the initial values of the component's properties.


Defining special property types

Defining simple properties describes the guidelines that apply to all properties. This section discusses the special rules and exceptions for properties of special types:

Defining boolean properties

boolean properties are a special case of enumerated properties. They have a special naming convention for their read accessor methods. The write accessor method for boolean properties is the same as for other simple properties.

Declaring the read accessor method for boolean properties

For boolean properties, place "is" in front of the property name to form the method name. This way of naming the read method is easier to understand in your code.

Declare the read accessor method for boolean properties as follows:

public boolean is<propertyName>();

The following are the elements of the declaration:

public
The property must be public for it to appear in the Component Inspector.
boolean
The read or get method returns a boolean value.
is<propertyName>
Name the read method by adding a lowercase "is" to the property name and capitalizing its first letter. Replace <propertyName> with the name of the property. (If your property accessor methods are not declared according to the standard naming conventions, you can use the optional BeanInfo interface to explain them to the Component Inspector.)

Defining array properties

Array properties have the same accessor methods and data members as other properties, but the data member is an array. Remember to protect it by giving it private access. Declare and populate it as you would any other array. Array properties can be arrays of any data type, but they must be indexed by an integer value.

Declaring the read accessor method for array properties

Declare the read accessor method for an array property as follows:
public <type>[] get<propertyName>();

The following is a description of the elements in the declaration:

public
The property must be public for it to appear in the Component Inspector.
<type>[]
The read (or get) accessor method for an array property returns an array of the correct data type. For example, specify an array of strings as String[].
get<propertyName>
Name the read method by adding a lowercase "get" to the property name and capitalizing its first letter. Replace <propertyName> with the name of the property. (If your property accessor methods are not declared according to the standard naming conventions, you can use the optional BeanInfo interface to explain them to the Component Inspector.)

Declaring the write accessor method for array properties

Declare the write accessor method for an array property as follows:
public void set<propertyName>(<type>[] <value>);

The following describes the elements in the declaration:

public
The property must be public for it to appear in the Component Inspector.
void
The write (or set) accessor method returns void.
set<propertyName>
Name the write method by adding a lowercase "set" to the property name and capitalizing its first letter. Replace <propertyName> with the name of the property. (If your property accessor methods are not declared according to the standard naming conventions, you can use the optional BeanInfo interface to explain them to the Component Inspector.)
<type>[] <value>
The write accessor method for an array property takes an array argument of the same data type as the property. For example, public void setList(String[] names).

Defining indexed properties

An indexed property is a single element of an array property. Declare a field and set its value as you would any other.

Declaring the read accessor method for indexed properties

Declare the read accessor method for an array property as follows:
public <type>[] get<propertyName>(int <index>);

The following is a description of the elements in the declaration:

public
The property must be public for it to appear in the Component Inspector.
<type>[]
The read (or get) accessor returns an array element of the correct data type.
get<propertyName>
Name the read method by adding a lowercase "get" to the property name and capitalizing its first letter. Replace <propertyName> with the name of the property. (If your property accessor methods are not declared according to the standard naming conventions, you can use the optional BeanInfo interface to explain them to the Component Inspector.)
int <index>
The index argument identifies the array element. The array must be indexed by an integer.

Declaring the write accessor method for indexed properties

Declare the write accessor method for an indexed property as follows:
public void set<propertyName>(int <index>);

The following describes the elements in the declaration:

public
The property must be public for it to appear in the Component Inspector.
void
The write (or set) accessor method returns void.
set<propertyName>
Name the write method by adding a lowercase "set" to the property name and capitalizing its first letter. Replace <propertyName> with the name of the property. (If your property accessor methods are not declared according to the standard naming conventions, you can use the optional BeanInfo interface to explain them to the Component Inspector.)
int <index>
The index argument that identifies the array element. The array must be indexed by an integer.
 

Defining bound properties

A bound property is a property that notifies any listeners of changes in the property's value. A listener of a property change implements the PropertyChangeListener interface. When the bound property value changes, the component calls the propertyChange event of the listening object, sending a PropertyChangeEvent to it. The PropertyChangeEvent contains the locale-independent name of the property, the old property value, and the new property value. The listening component then has the opportunity to respond to the change in the property's value.

Note that the event source component should send the PropertyChangeEvent to the listening objects after it updates its internal state.

The component with bound properties should include the event listener registration methods for PropertyChangeListeners:

public void addPropertyChangeListener(PropertyChangeListener pcl);
public void removePropertyChangeListener(PropertyChangeListener pcl);
Using these registration methods, the listening objects can respond when any of the bound properties in the component change in value. Alternately, the listeners can respond to changes in a specific property value if the following event registration methods are used instead:
void addPropertyChangeListener(String propertyName, PropertyChangeListener pcl);

void removePropertyChangeListener(String propertyName, PropertyChangeListener pcl);

For more information about event listeners, see Working with events.

Declaring the read accessor method for bound properties

Declare the read accessor method for bound properties as you would for a simple property:
public <type> get<propertyName>();

The following describes the elements in the declaration:

public
The property must be public for it to appear in the Component Inspector.
<type>
The read or get method returns the type of the property, such as int. If the property is an object, this method returns the object.
get<propertyName>
Name the read method by adding a lowercase "get" to the property name and capitalizing its first letter. Replace <propertyName> with the name of the property. (If your property accessor methods are not declared according to the standard naming conventions, you can use the optional BeanInfo interface to explain them to the Component Inspector.)

Declaring the write accessor method for bound properties

Declare the write accessor method as you would for a simple property:
public void set<propertyName>(<type> <value>);

The following describes the elements in the declaration:

public
The property must be public for it to appear in the Component Inspector.
void
The write or set method always returns void.
set<property>
Name the write method by adding a lowercase "set" to the property name and capitalizing its first letter. Replace <propertyName> with the name of the property. (If your property accessor methods are not declared according to the standard naming conventions, you can use the optional BeanInfo interface to explain them to the Component Inspector.)
<type> <value>
The write method takes an argument of the same type as the property. For example, setCount(int count). If the property is an object, this method takes an object argument.

Defining constrained properties

A constrained property is a property in which a change to the property value can be vetoed by another component that is listening for changes in the property's value. The listening component implements the VetoableChangeListener interface. When a constrained property value changes, the component calls the vetoableChange() method of the listening object, sending a PropertyChangeEvent to it. The PropertyChangeEvent contains the locale-independent name of the property, the old property value, and the new property value.

The listening component then has the opportunity to reject the change in the property's value by throwing a PropertyVetoException. The source component must catch this exception and change the property value back to the old value. Then it should call the listener's vetoableChange() method to notify the listener that the old value is back in place.

Note that the event source component should send the PropertyChangeEvent to the listening objects before it updates its internal state.

The component with constrained properties should include the event listener registration methods for VetoableChangeChangeListeners:

public void addVetoableChangeListener(VetoableChangeListener vcl);
public void removeVetoableChangeListener(VetoableChangeListener vcl);
Using these registration methods, the listening objects can veto changes when any of the constrained properties in the component change in value. Alternately, the listeners can veto a change in a specific property value if the following event registration methods are used instead:
void addVetoableChangleListener(String propertyName, VetoableChangeListener vcl);
void removeVetoableChangeListener(String propertyName, VetoableChangeListener vcl);

For more information about event listeners, see Working with events.

Declaring the read accessor method for constrained properties

Declare the read accessor method for constrained properties as you would for a simple property:
public <type> get<propertyName>();

The following describes the elements in the declaration:

public
The property must be public for it to appear in the Component Inspector.
<type>
The read or get method returns the type of the property, such as int. If the property is an object, this method returns the object.
get<propertyName>
Name the read method by adding a lowercase "get" to the property name and capitalizing its first letter. Replace <propertyName> with the name of the property. (If your property accessor methods are not declared according to the standard naming conventions, you can use the optional BeanInfo interface to explain them to the Component Inspector.)

Declaring the write accessor method for constrained properties

Declare the write accessor method as you would for a simple property, except include the PropertyVetoException:
public void set<propertyName>(<type> <value>) throws PropertyVetoException;

The following describes the elements in the declaration:

public
The property must be public for it to appear in the Component Inspector.
void
The write or set method always returns void.
set<property>
Name the write method by adding a lowercase "set" to the property name and capitalizing its first letter. Replace <propertyName> with the name of the property. (If your property accessor methods are not declared according to the standard naming conventions, you can use the optional BeanInfo interface to explain them to the Component Inspector.)
<type> <value>
The write method takes an argument of the same type as the property. For example, setCount(int count). If the property is an object, this method takes an object argument.
throws PropertyVetoException
The PropertyVetoException is thrown if a listening component objects to the change of property value. The source component must catch the exception and change the property value back to the old value.