Tips for writing BeanInfo classes for the visual editor

This section describes some rules you can employ if you are writing a BeanInfo class for a Java bean intended for use in the visual editor for Java.

The visual editor for Java uses the property descriptors described in the BeanInfo class to establish the list of entries in the Properties view, as well as how they should be edited.

If a java.beans.PropertyDescriptor is hidden, then it will not be available within the Properties viewer. However, set methods of hidden properties will still be parsed by the code generator and will be applied to the live beans.

When a property is hidden it is still used by code parsing, but it will not be included in any other visual editor view or feature. VisualAge for Java allowed a property to be excluded from the Properties view, but was still available for other functions. For example, making connections by making it design time false. Although the visual editor for Java does not have connection capability, the concept of design time properties is carried forward. To make a property design time false, an attribute value should be set with the key of ivjDesignTimeProperty, and the value of Boolean.FALSE.

For example, if a BeanInfo class is being written for the class MyJavaBean that has a name property (from a public void setName(String) and public String getName() method pair), then the getPropertyDescriptors() method could be written as follows:

public PropertyDescriptor[] getPropertyDescriptors() { 
    PropertyDescriptor[] result = new PropertyDescriptor[1]; 
    try{ 
        PropertyDescriptor directionDescriptor = new
PropertyDescriptor("direction",MyJavaBean.class); 
        directionDescriptor.setValue("enumerationValues",new
Object[]{ 
            "North",new
Integer(myclasses.CompassPoint.NORTH),"myclasses.CompassPoint.NORTH",

            "East",new
Integer(myclasses.CompassPoint.EAST),"myclasses.CompassPoint.EAST",

            "South",new
Integer(myclasses.CompassPoint.SOUTH),"myclasses.CompassPoint.SOUTH",

            "West",new
Integer(myclasses.CompassPoint.WEST),"myclasses.CompassPoint.WEST" 
        }); 
        result[0] = directionDescriptor; 
    } catch ( IntrospectionError exc ) { 
    } 
    return result;
}

When a property is selected in the Properties view, an editor is created in the Value column where you can specify a new value. To calculate the editor for a property, the java.beans.PropertyDescriptor is queried for a property editor. If an associated property editor is found, then it is used. Otherwise, one is located that is defined to work with the property type. You cannot affect the list of pre-defined property editors for a type. If a java.beans.PropertyEditor is found in the property descriptor or found for the property type, then the Properties view will attempt to determine the type of editor to create. The rules used are:

  1. If the method public boolean supportsCustomEdit() returns true, then a dialog editor is created. The dialog button launches the editor returned from the method public Component getCustomEditor(). The editor returned should be a subclass of java.awt.Component, and it will be hosted with an OK and Cancel button in a Frame or JFrame as required.

  2. If the method public String[] getTags() returns an array of strings, they are shown in a list. The label used for an existing value in the Properties view is the result of calling public void setValue(Object) with the property value, then calling public String getAsText() to determine the String to use. As you select a new value in the list, the editor's method public void setAsText(String) is called, and the new property value is retrieved using public Object getValue().

  3. If neither of the above two methods return a custom editor or tags, then a text field editor is created in the Properties sheet. The text value initially displayed is the result of calling public void setValue(Object) and public String getAsText(). When a new string is entered in the text editor on each keystroke, the method public void setAsText(String) is called. If the method throws a java.lang.IllegalArgumentException, then the exception message is shown in the status bar and the value will not be applied. If no exception is thrown, when the Enter key is clicked in the text editor (or if another property in the Properties view receives focus), then the result of calling public Object getValue() is sent as the argument to the set method described in the property descriptor.

For every java.beans.PropertyEditor the method public String getJavaInitializationString() must also be specialized. This returns the string that is used in the Java source code as the argument to the set method of the property descriptor. This string should return the value, and any types referenced in the string should be fully qualified and not rely on any import statements in the class being composed. If your BeanInfo specializes the template JRE class java.beans.SimpleBeanInfo, then the method is not abstract and will be inherited to return '???'. You must remember to specialize it correctly.

In addition to using the public String[] getTags() method on a property descriptor to get a list, there is a shorter way of specifying a list of values. An attribute value is created with the key of enumerationValues, a value that is an array of triplicate entries of the displayName in the list, the value itself, and the initializationString. As an example, consider a property called direction that is typed to int and can be assigned values of 0,1, 2 and 3. These are references to static fields NORTH, EAST, SOUTH, and WEST on the class myclasses.CompassPoint. The property descriptor could be written as follows:

public PropertyDescriptor[] getPropertyDescriptors() {
    PropertyDescriptor[] result = new PropertyDescriptor[1];
    try{
        PropertyDescriptor directionDescriptor
= new PropertyDescriptor("direction",MyJavaBean.class);
        directionDescriptor.setValue("enumerationValues",new
Object[]{
           
"North",new
Integer(myclasses.CompassPoint.NORTH),"myclasses.CompassPoint.NORTH",
           
"East",new
Integer(myclasses.CompassPoint.EAST),"myclasses.CompassPoint.EAST",
           
"South",new
Integer(myclasses.CompassPoint.SOUTH),"myclasses.CompassPoint.SOUTH",
           
"West",new
Integer(myclasses.CompassPoint.WEST),"myclasses.CompassPoint.WEST"
        });
        result[0] = directionDescriptor;
    } catch ( IntrospectionError exc ) {
    }
    return result;
}

The second value in each of the entries is not the int static field itself such as myclasses.CompoassPoint.NORTH but instead is an instance of java.lang.Integer. This is because primitive types cannot be put into an array that is typed to Object, so instead their java.lang equivalent must be used.

 

Bean Info events

The list of events that is shown on a Java bean is the preferred method descriptors on its event descriptors.

If an adapter class is available, then it should be added to the java.beans.EventDescriptor as a named attribute with a key of "eventAdapterClass", for example

EventSetDescriptor focusEventSetDescriptor = new EventSetDescriptor(  
  java.awt.Component.class,  
  "focus",  
  java.awt.event.FocusListener.class,  
  new String[] { "focusGained(java.awt.event.FocusEvent)", "focusLost(java.awt.event.FocusEvent)" },  
  "addFocusListener(java.awt.event.FocusListener)",
  "removeFocusListener(java.awt.event.FocusListener"
);
focusEventSetDescriptor.setValue("eventAdapterClass", "java.awt.event.FocusAdapter");

 

Parent topic

BeanInfo classes and introspection

 

Related tasks

Controlling BeanInfo information for plug-in developers
Specifying the location of BeanInfo classes