|
|
BeanHelpers
OverviewBeanHelpers is an extension of JavaBeansTM technology that is used to implement JavaBeans with an advanced functionality. These beans are still backward compatible with JavaBeans technology but when used with one of the Property Inspectors provided by BeanExplorerTM the extensions are recognized and used to enhance user interface. Goals
Architecture OverviewBeanHelpers consist of two java packages: Package | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
FeartureDescriptor methods to store additional meta information as key-value pairs in its internal hashtable | |
Enumeration | attributeNames()Gets an enumeration of the locale-independent names of this feature. |
Object | getValue(String attributeName)Retrieve a named attribute with this feature. |
void | setValue(String attributeName, Object value)Associate a named attribute with this feature. |
BeanInfoConstants interface declares all keys to get access for additional meta information provided by BeanHelpers technology. This constants are summarized in the table in the end of document.
BeanHelpers technology provides type safe methods to associate correct type of meta information value with the specified key. This methods are declared in following classes:
BeanInfoEx extends standard BeanInfo class to specify an explicit ordering of the properties and supply additional meta information about the bean. PropertyDescriptorEx extends standard PropertyDescriptor class to supply additional meta information about the property. IndexedPropertyDescriptorEx extends of standard IndexedPropertyDescriptor class to supply additional meta information about the indexed property. JavaBeans technology does not provide mechanism to order the properties of a bean. Trying to solve this problem builder tools allows to developer sort properties by its name or value class. BeanHelpers technology allows bean implementer to specifies explicitly the order for the properties.
From the BeanHelpers' view point the order is still some additional meta information. This information is stored in BeanDescriptor internal hashtable as array of PropertyDescriptors with BeanInfoConstants.ORDER key.
Property Inspector or builder tool should use a following algorithm to get PropertyDescriptors describing properties provided by the bean:
BeanInfo beanInfo = Introspetor.getBeanInfo(Foo.class);
// try to get ordered PropertyDescriptors array
// provided by BeanHelpers technology
BeanDescriptor beanDescriptor = beanInfo.getBeanDescriptor();
PropertyDescriptor[] properties = (PropertyDescriptor[])
beanDescriptor.getValue(BeanConstants.ORDER);
// if properties order is not defined,
// then standard approach is used
if(properties == null)
properties = beanInfo.getPropertyDescriptors();BeanInfoEx provides a special add method allowing a bean implementer to specify the order while creating a BeanEinfo. The properties will be arranged by Property Inspector in the same order in which they were added. For example if Foo bean class has properties named a, b, c, then bean implementer can specify the order in the following way:
public class FooBeanInfo extends BeanInfoEx
{
public FooBeanInfo()
{
super(Foo.class);
add(new PropertyDescriptor("a", beanClass));
add(new PropertyDescriptor("b", beanClass));
add(new PropertyDescriptor("c", beanClass));
}
}When add method is invoked, BeanInfoEx instance puts the specified PropertyDescriptor into its internal vector. Later when BeanInfoEx used as "informant" it returns BeanDescriptor with ordered array of PropertyDescriptors from the vector.
BeanInfoEx methods to provide properties order | |
void | add(PropertyDescriptor pd)Adds the specified property. |
void | add(PropertyDescriptor pd, Class propertyEditor)Adds the property with the specified PropertyEditor. |
void | add(PropertyDescriptor pd, Class propertyEditor, String displayName, String description)Adds the property with the specified PropertyEditor and short description. |
void | add(PropertyDescriptor pd, String displayName, String description)Adds the property with the given display name and description. |
void | addHidden(PropertyDescriptor pd)Adds the specified property as 'hidden'. |
void | addHidden(PropertyDescriptor pd, Class propertyEditor)Adds the specified property as 'hidden'. |
BeanInfoEx provides several utility add methods with extra arguments (see the table above). For example, add(PropertyDescriptor pd, Class propertyEditor) method allows the developer to set up property editor class for the given property descriptor. The code of the method you can see below.
public void add(PropertyDescriptor pd, Class propertyEditor)
{
pd.setPropertyEditor(propertyEditor);
add(pd);
}| PropertyDescriptorEx methods for semantic control of property values | |
void | setCanBeNull(boolean value) Indicates that the property can be null. |
void | setDefaultValue(DefaultValue value) Sets the initial value for the property when its getter method returns null. |
void | setDefaultValue(Method method) Sets a method to generate initial value for the property when its getter method returns null. |
| Other PropertyDescriptorEx methods for meta data | |
void | setHelpId(String helpId) Sets context for the property in some help system defined by an application. |
void | setNodeIcon(int type, Image icon) Sets an icon for the property. |
void | setReadOnly(boolean value) Indicates that property as 'read only'. |
void | setReadOnly(Method method) Sets a method which determines whether the property is 'read only'. |
void | setToolTip(Method method) Sets a method for generating tooltip for the property. |
BeanHelpers technology introduce PropertyEditorEx class that extends standard java.beans.PropertyEditor interface to provide editor with access to the bean which property is being edited. Property sets up the such editors using PropertyEditorEx.setBean method. Later property editor can get access to the bean using PropertyEditorEx.getBean method.
Property Inspector may also pass to a editor implementing this interface additional arguments isSelected and hasFocus to provide finer integration into JTable components, using methods getCustomRenderer and getCustomEditor methods.
There is a support class CustomEditorSupport to simplify creation of the property editors implementing PropertyEditorEx interface.
Another extension (part of PropertyDescriptoEx) allows the developer to specify preferred size of the property when it is being displayed in some visual UI like PropertyInspector or DialogPropertyInspector, as well as specify format string for the property value. The tables below provides summary of such methods.
| PropertyDescriptorEx concerning property editors | |
void | setEditorPreferredSize(Dimension editorPreferredSize) This method allows the developer to specify preferred size of the property when it is displayed in some visual UI like PropertyInspector or DialogPropertyInspector |
void | setFormatMask(Method method) Sets a method which generates format string for the property value. |
Composite Editor is a container editor allowing the developer to group several property editors into one panel. Composite Editor can be specified both as bean editor and property editor. Lesson 6 gives you a detailed example how composite editor can be used.
| BeanInfoEx method to specify composite editor | |
void | setCompositeEditor(String propertyList, LayoutManager layoutManager) Set and setup composite editor for some properties of bean. |
Possibility to control properties behavior by the bean or changing behavior of the properties at run time is one of the central in BeanHelpers technology.
According to JavaBeans technology BeanInfo is associated with class, not with particular instance of the class. Because class definition is immutable all class instances share the same BeanInfo instance and consequently have the same outlook in Property Inspector. Such approach is good enough for application builder tools. But in practice it is often necessary to have values of property attributes depending on some conditions. Here are some examples:
To solve this task BeanHelpers introduce the concept of dynamic property attribute. We say that property attribute is dynamic when its value is controlled by some method of the bean, specified in PropertyDescriptor. PropertyInspector invokes the specified method of the bean to get value of the property attribute. This allows a bean to control behavior of the property.
The table below summarizes methods of PropertyDescriptorEx that can be used to specify property attributes that values can be calculated dynamically by a bean. Lesson 4 gives an example how you can use dynamic property attribute in your application.
| PropertyDecriptorEx methods to specify property attributes that values will be calculated dynamically by a bean | |
void | setDisplayName(Method method) Sets a method for generating display name of the property. |
void | setToolTip(Method method) Sets a method for generating tooltip for the property. |
void | setReadOnly(Method method) Sets a method which determines whether the property is 'read only'. |
void | setHidden(Method method) Sets a method for determining visibility of the property. |
void | setDefaultValue(Method method) Sets a method to generate initial value for the property when its getter method returns null. |
void | setFormatMask(Method method) Sets a method which generates format string for the property value. |
void | setChildDisplayName(Method method) Sets a method for calculating display names for the elements of the indexed property. |
void | setHideChildren(Method method) Sets a method for determining whether the children of composite property should be visible or not. |
void | setResizable(Method m) Sets a method which determines whether elements of the indexed property can be changed at run time. |
void | setCanDelete(Method m) Sets a method which determines whether elements of the indexed property can be removed at run time. |
void | setCanInsert(Method m) Sets a method which determines whether elements of the indexed property can be added at run time. |
void | setCanMove(Method m) Sets a method which determines whether the order of the elements of the indexed property can be changed at run time. |
Bean properties can form a hierarchy, represented in Property Inspector as a tree. In the example below BarChart bean has array property columns. Array items presented by composite properties that consists of 4 simple properties: label, value, color and visible. Thus in this example we have three level hierarchy:
BarChart; columns property;
BeanHelpers technology provides two extensions to address complications arising for such hierarchies. First extension provides fine control on array item properties. Second extensions concerns merging metadata from BeanDescriptor and PropertyDescriptor when some bean (child) is used as property of other bean (parent).
By type of its value properties are divided into three groups:
java.lang.XXXXXX types or simple Java type: boolean, byte, char, short, int, long, float or double. In the picture above title, orientation and autoLayout are examples of simple properties. columns is array property, and composite property is associated with each array item. BeanHelpers technology provides following methods for dealing with hierarchies of the properties:
| PropertyDescriptorEx methods to concerning properties hierarchy | |
void | setSimple(boolean value) This flag forces interpretation of composite properties as simple. |
void | setNoRecursionCheck(boolean noRecursionCheck) Sets a flag for no recursion check. |
void | setHideChildren(boolean value) Specifies whether the children of a composite property should be visible or not. |
void | setHideChildren(Method method) Sets a method for determining whether the children of composite property should be visible or not. |
BeanHelpers extends JavaBeans technology to provide fine control on array items. The table below summarizes methods of PropertyDescriptorEx for dealing with array items.
By default display names of array elements are shown as [0], [1], [2] etc. Using setChildDisplayName method a bean can provide a method for calculating display names for the elements of the indexed property.
Other methods allow a bean to control insertion or deletion of array items*.
| PropertyDescriptorEx methods to control on array items | |
void | setChildDisplayName(Method method) Sets a method for calculating display names for the elements of the indexed property. |
void | setResizable(Boolean value) Specifies that number elements of the indexed property can be changed at run time. |
void | setResizable(Method m) Sets a method which determines whether elements of the indexed property can be changed at run time. |
void | setCanDelete(Method m) Sets a method which determines whether elements of the indexed property can be removed at run time. |
void | setCanInsert(Method m) Sets a method which determines whether elements of the indexed property can be added at run time. |
void | setCanMove(Method m) Sets a method which determines whether the order of the elements of the indexed property can be changed at run time. |
* This feature is not yet supported by standard Property Editors.
Any bean (child) can be used as a value of the property of another bean (parent). In such case we consider metadata from child BeanDescriptor as default, while parent PropertyDescriptor can redefine some child property attributes.
BeanExplorer merges information from PropertyDescriptor and BeanDescriptor when a property is created. Property attributes defined in BeanDescriptor are replaced by corresponding attributes from PropertyDescriptor if such attributes exist.
| Key | Value class | Description |
ORDER | PropertyDescriptor[] | Key to get SpecifiesThis attrubute allows passing the order in which properties were added in using BeanInfoEx interface. This attribute can be extracted by visualization UI and used to display properties in order. |
Meta information to display a property | ||
BEAN_DISPLAY_NAME | Method | Key for method to be invoked to calculate display name for the bean |
DISPLAY_NAME | Method | Specifies the method to be invoked to calculate display name for the property |
CHILD_DISPLAY_NAME | Method | Specifies the method to be invoked to calculate display for array items in array property |
TOOLTIP | This attribute is used as a placeholder for specifying methods to calculate tooltip for properties at run time | |
HELP_ID | This attribute is used a context help for the property. It can be some identifier of help resource as well as help message itself | |
NODE_ICON_COLOR_16x16 NODE_ICON_COLOR_32x32 NODE_ICON_MONO_16x16 NODE_ICON_MONO_32x32 | Flags are used to specify icons for the individual properties. Java Beans technology allows the developer to specify icons for the bean-level only, though modern UI approaches are based on tree models where icons are required for the leaves | |
Meta information to control property behavior | ||
READ_ONLY | This flag is used to force the properties to be read only even if they have setter methods | |
HIDDEN | This attribute is used as a placeholder for specifying method that will calculate visiblity of the property at run time | |
HIDE_CHILDREN | This attribute is used for composite properties when the developer doesn't want to show its children | |
SIMPLE | This attribute is used to disable recursive introspection of some properties. Normally introspection is applied to all non-promitive properties to find out whether they are itself Beans. | |
NO_RECURSION_CHECK | This flag is caused by classes like java.awt.Dimension which contain property of the type java.awt.Dimension thus causing endless loop while recursively introspecting beans. Normally we suppress recursion but in some situations this screens out required properties. In such situation the developer can use this flag to aviod recusrion suppresion, but he may be required to write BeanInfo for the class in this case. | |
SUBSTITUTE_BY_CHILD | This attribute is used for composite properties when they contain the only visible child property. If this attribute is specified parent peoprty wil be replaced by child | |
Meta information used by property editor | ||
FORMAT_MASK | String | Property format string |
EDITOR_PREFERRED_SIZE | Dimension | Specifies preferred size of the property control when it is displayed in some visual UI like PropertyInspector or DialogPropertyInspector |
COMPOSITE_EDITOR_PROPERTY_LIST | String | List of property names for composite editor. |
COMPOSITE_EDITOR_LAYOUT_MANAGER | LayoutManager | Layout manager to arrange property renderers/editors inside the composite editor. |
Meta information to control property value | ||
DEFAULT_VALUE | Object | Specifies an initial value for the property when its getter method returns null. |
CAN_BE_NULL | This attribute is used to specify the property can be null | |
Reserved for internal usage constants | ||
RESOURCES | Bean resources | |
PARENT_RESOURCES |
| Resources of beans parent |
|