C H A P T E R  8

Design Actions

This section assumes that you have already read Develop Your First Component found in Chapter 2, Developing Components, and Developing Model Components.


Developing Extensible Components Which Have Component Design Actions

This section provides a description of the basic steps involved in adding design actions to your extensible component.

Component design actions encapsulate arbitrary design time behavior for a component. The design action might post an "About" or "Credits" dialog, perform validation, autoconfigure the component, synchronize support files, display messages or warnings, open complex editors and wizards, and even read and edit the finest details of the component object model.

To support component design actions, a new interface to Sun ONE Application Framework component architecture, called DesignableComponentInfo, is introduced. DesignableComponentInfo is an optional specialization of ExtensibleComponentInfo that allows the component author to define special design time behavior for extensible components. The practical use of DesignableComponentInfo is to expose design actions to the developer in the IDE. Any extensible command, mode,l and view ComponentInfo classes may optionally implement DesignableComponentInfo to expose ComponentDesignActionDescriptors.

The IDE module only exposes design actions for extensible components and therefore, the DesignableComponentInfo specializes ExtensibleComponentInfo to impose this rule.

When available, the IDE uses ComponentDesignActionDescriptors to present a submenu list of the defined design actions in the component node's contextual menu "Design Actions".

This figure shows the Design Actions Menu. 

Because DesignableComponentInfo is a recent addition to the Sun ONE Application Framework component architecture, only the Bean Adapter Model uses DesignableComponentInfo to expose the Update Properties design action.

What is a Component Design Action?

Although a component design action may be used to perform practically anything, here are some guidelines to consider.

The standard mechanism a developer expects to use when configuring an extensible component during design time is the property sheet of the primary component node and/or the contained property sheets of subnodes. The component author should first turn to automatic support for config properties and optionally any custom editors which may be applicable for complex config properties. If component authors are using design actions to take the place of config properties or custom editors, they might be going in the wrong direction.

Discrete component config property editors alone are often not enough for managing the design aspects of certain components. An editor for a config property will not have scope to other config properties or other parts of the component object model. Therefore, it is not possible to edit a subset of related config properties as a whole. In the case of models and container views, there is no way for a collection of model fields or child views to be edited together. Also, there is currently no support in the component architecture to specify wizards or initialization mechanisms to be used by the developer when creating a new component.

A solution to these issues is the component design action. You will see later in this section that, while performing a component design action, the component author is provided a context in which very powerful design changes (even continuous and re-entrant design changes) might be implemented.

A good example of a component design action can be found in Bean Adapter Model in the Sun ONE Application Framework component library. Although the Bean Adapter Model has a config property "Bean Type" which allows the developer to specify the type/class of the adapted Java Bean, there is no easy way for the developer to automatically generate model fields for the properties of the Bean. The Update Properties design action of the Bean Adapter Model validates the Bean Type config property and ensures that at least the full set of bean properties have representative model fields. This design action supports continuous design, because the action can be used as the adapted Bean changes.

An opportunity is provided with component design actions for component authors to publish "black box" components, which may be configured by a mechanism which does not use the component object model. For instance, an existing view or model component, or the foundation of a new component, which uses a custom runtime XML descriptor or properties file, might already exist. In this case, the component author needs a way to provide editors for this custom configuration. Advanced APIs of the ComponentDesignContext support such situations.

The rest of this section assumes that you has reviewed the JavaDocs for the com.iplanet.jato.component.design and com.iplanet.jato.component.design.objmodel packages.

A simple example of how to specify a ComponentDesignAction for an extensible component using the DesignableComponentInfo and ComponentDesignActionDescriptor APIs is presented.

Exposing Design Action in ComponentInfo

To expose component design actions for your extensible component, the first step is to implement DesignableComponentInfo.

In the example shown below, you build onto the XMLDocumentModel example. You will create a simple design action called "About" which presents an informational dialog to the developer dumping some component details including name, logical name, and config properties.

1. Have your component info implement DesignableComponentInfo.

2. Implement method getComponentDesignActionDescriptors() (see code example shown below).

3. Because the ComponentDesignActionDescriptor bean requires the ComponentDesignAction class to be assigned, you also need to create the action class.

The minimum that you need is a class implementing ComponentDesignAction, including the performAction(ComponentDesignContext) method.

A simple technique is to have an inner class of the component info define the action class as is shown in the code example below, where there is the static inner class AboutDialog.

The component design action mechanism will only call the default (no arg) constructor of the design action class. Therefore, avoid using alternate constructors, for they will have no use.

The performAction() method is not required to do anything other than return promptly; in our minimal example below we will post a modal dialog and call a helper method aboutDisplayMessage()

In this sample code, String values have been embedded directly for ease of demonstration. Utilize resource bundles if you anticipate the need to localize your display strings.

The following code represents what needs to be added to the XMLDocumentModelComponentInfo.java. Non-relevant code has been snipped as represented by the ellipsis " . . ."

. . .

import com.iplanet.jato.component.design.*;

import com.iplanet.jato.component.design.objmodel.*;

 

public class XMLDocumentModelComponentInfo extends ExtensibleModelComponentInfo

implements DesignableComponentInfo

{

. . .

 

public ComponentDesignActionDescriptor[] getComponentDesignActionDescriptors()

{

if(null != designActionDescriptors)

return designActionDescriptors;

 

List descriptors=new ArrayList();

 

ComponentDesignActionDescriptor descriptor = new ComponentDesignActionDescriptor(AboutDialog.class);

descriptor.setName("About");

 

descriptor.setDisplayName("About");

descriptor.setShortDescription(

"Displays a small list of component details");

descriptors.add(descriptor);

 

designActionDescriptors = (ComponentDesignActionDescriptor[])

descriptors.toArray(

new ComponentDesignActionDescriptor[descriptors.size()]);

return designActionDescriptors;

}

 

public static class AboutDialog implements ComponentDesignAction

{

public void performAction(ComponentDesignContext context)

throws DesignActionException

{

javax.swing.JOptionPane.showMessageDialog(

context.getMainWindow(),

aboutDisplayMessage(context),

"XMLDocumentModel About Design Action",

javax.swing.JOptionPane.INFORMATION_MESSAGE);

}

 

private String aboutDisplayMessage(ComponentDesignContext context)

{

StringBuffer msg = new StringBuffer(

"Component Name: " +

context.getComponentInfo().getComponentDescriptor().getName() +

"\nComponent Logical Name: " +

context.getComponentLogicalName() + "\n");

ConfigPropertyNode[] props = ((ConfigPropertyNodeContainer)

context.getPrimaryObjectModel()).getConfigPropertyNode();

for(int i=0;i<props.length;i++)

{

props[i].dump(msg, "\t");

msg.append("\n");

}

return msg.toString();

}

}

 

. . .

 

private ComponentDesignActionDescriptor[] designActionDescriptors;

}


In the AboutDialog design action, a Swing informational modal dialog box is presented to the developer. The "MainWindow" property of the ComponentDesignContext is used to place the Swing visual component. The message presented comes from the helper method aboutDisplayMessage(). Again, the various properties of the ComponentDesignContext are used to acquire information about the component including its name, logical name, and you loop through the config properties and dump their values.

To access the config properties, advantage is taken of object model interfaces ConfigPropertyNodeContainer and ConfigPropertyNode. This AboutDialog example can be used on Command, ContainerView, ViewBean, and Model extensible components. This example is not Model specific.

After compiling, packaging, and using this component in an application, instances of XMLDocumentModel will provide the design action "About".

This figure shows the Design Action, About. 

The result of performing the design action is:

This figure shows the result of the Design Action.