Creating a Custom Properties Value Editor

The Properties window in Visual J++ 6.0 provides editing capability for the values of the properties exposed in your control. In fact, the Properties window is really just a custom editor host. You can specify a custom editor, or you can rely on the default editing capabilities of the Properties window.

The mechanism is this: the Properties window first checks to see if you have specified a custom value editor. If not, it will look for an inner class called Editor inside the class of the type of the property. If no editor is found, it traverses the type’s hierarchy looking for any superclass that has an editor. Because there is an ObjectEditor class associated with java.lang.Object, an editor will always be found. The Properties window will provide a default editor for all simple types, such as a string editor, integer editor, and so forth.

You might specify a custom value editor for many reasons. Typical tasks for a custom property editor include:

For more information, see Defining a Custom Value Editor.

Defining a Custom Value Editor

To create a custom value editor, you must implement com.ms.wfc.core.IValueEditor. A convenient way to do so is to extend com.ms.wfc.core.ValueEditor to provide a default implementation of all methods.

To create the value to be displayed (as a string) in the Properties window, override the getTextFromValue method. In order for the changed value to be reflected in the control and displayed in the Properties window, override the getValueFromText method.

The following example illustrates a simple custom value editor that displays a percentage value with "%" in the Properties window, but then strips out the punctuation before the value is stored. This example makes use of the Value class in com.ms.wfc.util class for conversions:

import com.ms.wfc.core.*;
import com.ms.wfc.util.*;

public class PercentEditor extends ValueEditor { 
   // Creates string as "nn%" for display in the Properties window
   public String getTextFromValue(Object value) {
      return Value.toString(Value.toInt(value)) + "%";
   }
   
   // Converts string in format "nn%" to integer. This method
   // is required.
   public Object getValueFromText(String text) {
      String s = Utils.trimBlanks(text.replace('%', ' '));
      return Value.toObject(Value.toInt(s));
   }
}

The methods provided by com.ms.wfc.core for exchanging information with a property editor are listed in the following table.

Method Description
editValue Provides a user interface for editing the property value.
getConstantName Retrieves the fully-qualified name of a constant that represents the specified value.
getStyle Returns a bitfield of style flags.
getTextFromValue Converts a value into a string.
getValues Returns an array of values; typically, the Properties window displays these in a list by calling getTextFromValue in a loop.
getValueFromText Returns a value from a string. You must implement this method.
paintValue Paints a representation of the value in a specified rectangle.

Two additional methods — getSubProperties and getValueFromSubPropertyValues — allow you to work with properties of objects, such as a Font object, that normally are passed as part of the constructor.

The getStyle method is used to get and set flags used to specify behavior in the value editor. Valid styles are:

The following example shows how you can display a modal dialog box as the custom property editor. In this example, you can see how IValueAccess provides an abstract way to get and set a value on the component that an editor is currently editing. This is useful if more than one component might be selected. When you call the get and set value methods through IValueAccess, the Properties window can correctly set the value on multiple components. To display an ellipsis button that calls the dialog box, the example overrides the getStyle method and sets STYLE_EDITVALUE in the bitfield returned by getStyle:

import com.ms.wfc.core.*;
import com.ms.wfc.util.*;

public class PercentEditor extends ValueEditor {
    public void editValue(IValueAccess valueAccess) {
        PercentDialog dialog = new PercentDialog();
        int value = Value.toInt(valueAccess.getValue());
        dialog.setPercentValue(value);
        int result = dialog.showDialog();
        if (result == DialogResult.OK) {
            valueAccess.setValue(dialog.getText());
        }
    }

    public int getStyle() {
        // Using OR operator sets bitfield to display ellipsis button
        return super.getStyle() | STYLE_EDITVALUE;
    }
}

The following example illustrates how to display a drop-down dialog box. The control calls IEditorHost.dropDownDone when done editing the property. In addition, the control is responsible for calling the setValue method of IValueAccess. The Properties window will shut the drop-down list if the user cancels the drop-down dialog in any way:

import com.ms.wfc.core.*;
import com.ms.wfc.util.*;

public class PercentEditor extends ValueEditor {
    public void editValue(IValueAccess valueAccess) {
        PercentControl control = new PercentControl();
        int value = Value.toInt(valueAccess.getValue());
        dialog.setPercentValue(value);
        
        IEditorHost host = 
            (IEditorHost)valueAccess.getService(IEditorHost.class);
        control.setValueAccess(valueAccess);
        host.dropDownControl(control);
    }

    public int getStyle() {
        return super.getStyle() | STYLE_EDITVALUE | STYLE_DROPDOWNARROW;
    }
}