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
Provides an overview of creating a component property.
Read this if you are experienced with developing code for
reuse and already understand components.
- Defining component properties
Outlines the steps to creating a property.
- Defining simple
properties
Describes in depth the requirements for all properties. Includes
declaring property accessor methods, declaring a data
member to hold the property value, and standards for
determining access to the property.
- Defining special
property types
Explains how to work with properties of special types: boolean,
array properties, indexed, bound, and constrained.
- Writing property editors
Describes writing special editors for component
properties and declaring editors for properties.
- Creating component customizers
Outlines the steps required to develop a customizer for
your component.
Fast track to creating properties
A typical component property has three main elements:
- A data member (variable or object to hold the property's
value)
- A read accessor method (also known as a get method,
or a getter)
- A write accessor method (also known as a set method,
or a setter)
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,
- Declare and write the property's accessor methods,
following JavaBeans naming conventions.
- 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.
- Set the property's initial or default value.
- 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.