Properties

It is often useful to have fields of D2K modules that we can expose and manipulate from the D2K environment. For example, imagine we have a module that reads a system description from some known location within the file system, and passes the text in that file downstream. Now, suppose the location of that file changes because of a system upgrade. Our module is now broken. On the other hand, if the location of this file was a stored in a property, we could modify it without writing a line of code. So a property is a field of a module that is made available to the D2K infrastructure via a getter and a setter method.

The mechanism that defines properties is not unique to the D2K environment -- it has existed in JavaBeans and other systems for some time. We have adopted this same convention to define the properties of D2K Modules. A very simple getter/setter design pattern is required to define a property. The getter and setter methods can do anything they want, but it is expected that the getter method return a representation of the property value that was last set.

The module we described in first paragraph would be easily modified to include a property that defines the location of the file it requires. The field we expose will be a String, here is the definition of the property within the module:

  String filename = "/etc/systeminfo";
  public void setSystemInfoPath (String path) {
    filename = path;
  }
  public String getSystemInfoPath () {
    return filename;
  }

The property name here is systemInfoPath. The getter and the setter methods must both share the same property name. The field name can be anything you want, and in fact, it doesn't even require a single field, there may be several fields that are manipulated by the getter and setter method. So we see that properties may be quite complex. The only requirement is that the property must be interfaced by the getter and setter methods.

The setter methods can also throw a PropertyVetoException. This exception is found in the java.beans package. This exception can then be caught by the system and displayed to the user in a dialog. This is very useful in those cases where the property is constrained in some way that the user may not be aware of.

For example, if a property of the module is a percentage, the developer of the module should throw an exception if the integer value the user enters is out of range:

  public void setTestPercent(int i) throws PropertyVetoException {
    if (i > 100 || i < 0)
      throw new PropertyVetoException ("Percentages should not be less than 0 and greater than 100", null);
    testPercent = i;
  }

If any of the setter methods throws an exception, the property editor window will remain exposed, and the user will be allowed to correct the mistake. It is also important to make the messages in the exception descriptive enough that the user is provided with enough information to correct the problem.

Property Descriptions

In addition to providing the getter and setter methods to expose the properties, there must also be a method provided for those modules that have properties. This method will return a data structure that describes the property fully.

The PropertyDescription Class

There exists a property description class which contains fields that describe a property. This class includes fields that contain the property name of the property, its common name, and a description of the text. The content for these fields must be passed to the constructor. For more information, see the java docs.

The getPropertyDescriptions() Method

There is a method of Module which can be overridden to return an array of PropertyDescription objects. In the D2K ToolKit, the properties will be presented in the property editor in the same order they are encountered in the returned array. Additionally, the common name will be used in place of the default property name. Tool tips will be displayed when the mouse is over the label for the property.

An Example

Following is an example of a correct implementation of the getPropertyDescriptionsMethod:

  public PropertyDescription [] getPropertiesDescriptions () {
    PropertyDescription [] pds = new PropertyDescription [4];
    pds[0] = new PropertyDescription ("yaMx", "Ya Max", "This is the Yaw Max.");
    pds[1] = new PropertyDescription ("xaMx", "Xa Max", "Maximum pitch.");
    pds[2] = new PropertyDescription ("LMax", "Limit Max", "This is the limit max test property.")
    pds[3] = new PropertyDescription ("xaMax", "Xa Mport Max", "This is something else.");
    return pds;
  }

In this method, we return a description of 4 properties named "yaMx", "xaMx","LMax", and "xaMax". The results will not be as expected if the property name(the first argument), is not correct.

Custom Property Editors

The D2K ToolKit will create default property editors that are adequate for many modules. Fields containing strings, integers, floats and booleans are easily manipulated using a standard text field for example. However, there are cases where the default property editor is not sufficient. As an example, some fields can only be correctly set to some some finite set of values, for example, a text field that should be set to one of some list of values, like "low", "medium" or "high". Ideally, this field would be set from a menu containing only those appropriate values for the field. However, the D2K ToolKit is not aware of the range of settings appropriate, so it is limited to using only a text field.

There is a method which returns a user interface component which is responsible for providing editing capability for all the fields of the module. This method is defined as follows:

  public CustomModuleEditor getPropertyEditor();

The base class implementation of this method returns null. If a more sophisticated property editor is required, override this method, returning a component that provides editing capability for the modules properties.

Notice the method does not return a Java AWT Component. Instead it returns a CustomModuleEditor. CustomModuleEditor is an interface which requires one method. That method is defined as follows:

 
  public boolean updateModule() throws Exception;

This method is called when the user tries to dismisses the dialog containing the custom editor. This functionality is all provided by the ToolKit, the developer needs only to provide the code in this method that will set the fields of the associated module. If any of the fields can not be set(for example, if a value is out of range) the method must throw an exception with a message describing the problem and should not set any of the fields of the module. In this instance, the property editor dialog will not be dismissed, it will remain until the problem is corrected. If any properties actually change, return true from this method, otherwise return false.