# Creating Dialogs and Wizards for Inserting Controls

You can create a custom user interface that will be used when user adds your control to an application. You may want to provide insert UI if your control simply isn't useful until certain property attribute values are set.

The Java control API provides two classes that define the methods required by the IDE for a custom insert user interface. Your UI extends one of these to provide a means for the IDE to interact with your user interface, to get any values set by the user, and to get the text to be used as code in a JCX file if one is being generated.

- You extend the ControlWizardSimple class to provide a user interface that will be integrated with the default insert dialogs provided with WebLogic Workshop. Your UI will be added as a supplemental panel to the dialog. This is the simplest approach, and probably suits most needs.
- You extend the ControlWizard class to create a completely custom dialog.

## Extending ControlWizardSimple

What your ControlWizardSimple implementation does will vary depending on your specific goals. In fact, there are reasons to extend this class that aren't about creating a user interface at all (as described later).

Note: The panel created with your user interface components is actually not always the third in a dialog. If the user adds a new extension of your control from the File menu, it will be the second panel. These are sized slightly differently by the IDE. As with all UI design, you will need to experiment a bit to ensure that you get the results you want.

For the purpose of presenting the added panel in a control insert dialog, your basic goals are captured in the following methods you can override:

- getConfigurationInfo — Called by the IDE to discover whether your control supports using or generating a Java control extension (JCX) file and whether it supports being designated a control factory. Your return value should be some combination of the following four constants (or'ed together), although none of them is required.
  - Return CONFIG_CREATE_EXTENSION_FILE to indicate that your control can generate a JCX file. If you return this value, you must also override this class's getExtensionFileContent method to pass to the IDE the contents of the JCX file it generates. When you return this value, the insert dialog gives the user the option to generate a JCX and to give that file a name.

    > For more information about generating and using JCX files, see Creating Extensible Controls.

  - Return CONFIG_INSERT_INSTANCE to indicate that there are properties that are scoped to the control's instance declaration — that is, to the control as a whole. If you return this value, you must also override the getInstanceAnnotations method as described below.
  - Return CONFIG_NO_FACTORY to indicate that your control cannot be used as a control factory. If you return this value, the insert dialog will disable the check box that allows users to specify control factory use. (See the WebLogic Workshop control documentation for more information about control factories.)
  - Return CONFIG_USE_EXISTING to indicate that an existing JCX file may be used for this control instance. If you return this value, the insert dialog will allow the user to enter the name of an existing JCX file rather than a new one.
- getComponent — Called by the IDE to retrieve the user interface components that should make up the supplemental panel. Your user interface should provide a place for the user to enter values for attributes without which the control would be less than useful. The user should end up with a control instance that immediately compiles and runs.
- onFinish — Called by the IDE when the user clicks the Create button on the insert dialog. Your code here should perform any validation needed for the values the user has entered in the dialog. The method should return true if all values are valid and it's all right for the IDE to insert a new control based on them. You should return false if something's not right. (You can create a class specifically for validating property attribute values. For more information, see Creating Attribute Editors and Validators.)

  If you return false, the IDE will call the getIssues method.

- getIssues — Called by the IDE to retrieve an array of classes that implement the Issue interface. You implement Issue so that you can return messages back to the user via the IDE. The Issue interface provides a place for you to describe what went wrong, what to do about it, and whether the problem is an error. The IDE will present a dialog containing your messages, after which the user will be able to edit the value they've entered and try again.

The preceding methods are those that guide the contents of the insert dialog. The ControlWizardSimple class's remaining methods don't set user interface characteristics, but are key parts of an insert dialog implementation.

- setConfiguration — Called by the IDE to indicate whether the user has chosen to generate a JCX file. Your code will receive CONFIG_CREATE_EXTENSION_FILE if they have (if you specified that it is possible for them to do so, as described above).
- setName — Called by the IDE to give you the name chosen by the user for the control extension interface (and, of course, the name of the JCX file). You use this value when constructing the content of the JCX file.
- setPackage — Called by the IDE to give you the package name for the control extension interface if a JCX is to be generated. As with the value received via the getName method, you use this value in the JCX file's package declaration.
- getInstanceAnnotations — Called by the IDE to get property annotations for the instance declaration. You should override this method if you returned CONFIG_INSERT_INSTANCE from your implementation of the getConfigurationInfo method. This method should return an array of TagAttributeList objects that the IDE can use to annotate the control's instance declaration.
- getExtensionFileContent — Called by the IDE to retrieve the content of the JCX file to generate, if your control supports it. You should override this method if you returned CONFIG_CREATE_EXTENSION_FILE from the getConfigurationInfo method. The return value for this method is a String containing the contents of the JCX file. You should build this value based on values the user has entered in the insert dialog, including those you receive via the setName and setPackage methods. You should also include a serialization version ID as illustrated in Creating Extensible Controls.

Finally, the ControlWizardSimple class provides two methods you may find useful for interacting with the IDE's current context. The IDE calls setContext to pass in an instance of the EditorContext object. This object provides methods through which you can start WebLogic Server, print control-related messages to a log, get a File object representing the project to which your control is being added, and more.

Use the getContext method to retrieve this object.

## Extending ControlWizard

The key differences between extending ControlWizard and extending ControlWizardSimple have to do with the fact that when you extend ControlWizard, your user interface isn't a piece of another dialog owned by the IDE. For two pieces of information, the role between your component and the IDE are swapped: you provide the control extension name (if any) and instance name to the IDE, rather than the other way around.

The ControlWizard methods you can override include the following:

- getDialog — Called by the IDE to retrieve a Dialog instance representing your user interface. As with an extension of ControlWizardSimple, your UI should prompt the user for any property attribute values needed to make the new control instance compilable within its container. In addition, your UI must also prompt for an instance name (the value that goes into the control's declaration in its container code) and extension name, if a JCX is to be generated.
- getExtensionName — Called by the IDE to retrieve the JCX name set by the user in your dialog.
- getInstanceName — Called by the IDE to retrieve the instance variable name set by the user in your dialog.

Note that two methods overridden in ControlWizard are never called by the IDE: getComponent and getIssues. The getComponent method is rendered unused because it is replaced by getDialog, which must return a Dialog instance rather than a Component instance. The getIssues method is unused because in the context of your dialog, you are responsible for displaying messages that warn the user of invalid values.

### Prompting the IDE to Validate Names

Because the IDE is "out-of-the-loop" with regard to what goes on in your custom dialog, you must do a little extra to ensure that the control instance and JCX names that the user has entered in your dialog are valid from the IDE's perspective. Your code should do this before returning from your dialog's show method.

To do this, you use the ControlWizard.NameValidator class that the IDE passes to your dialog with the setNameValidator method. Your code should hang on to that instance, then call its validateInstanceName or validateExtensionName method with the name proposed by the user. The return value for an invalid name will be an array of Issue objects you can use to present relevant messages to the user.

## Connecting a Custom Insert User Interface to the IDE

To have the IDE use your control insert implementation, you simply set your JCS' insert-wizard-class attribute to the name of your implementation class. The insert-wizard-class attribute is one of the jc-jar property attributes.

For more information about the jc-jar property see Controlling Appearance and Handling Actions in Design View.

## Putting It All Together

The code for the following example is based on the ServerCheck sample control in the ControlDevKit sample application. For the complete working version, see the ControlFeatures project in that application, and look in the insertWizard folder.

### ControlWizardSimple Example

As discussed in this topic, an insert dialog's job is to prompt the user for information needed to create a compilable instance of the control. This example displays a supplemental pane in the default dialog to prompt the user for several values needed to connect to a WebLogic MBean. It does not generate a JCX file, instead returning the property attributes so they can be written as annotations to the control's instance declaration.

For an example that generates a JCX file, see the XQuery control in the jcxCreate folder of the ControlFeatures project.

    package insertWizard.ide;

    import com.bea.ide.control.ControlWizardSimple;
    import javax.swing.JComponent;
    import java.util.ArrayList;
    import com.bea.ide.control.EditorContext;

    /*
     * The insert-wizard-class attribute in the jc-jar file for this
     * control project specifies that this is the class WebLogic Workshop
     * should use to provide a custom insert wizard.
     *
     * This class extends ControlWizardSimple, which provides methods through
     * which WebLogic Workshop retrieves the user interface to use, the
     * annotation values to insert into the control's container, and so on.
     */
    public class ServerCheckWizard extends ControlWizardSimple
    {
        private ServerCheckWizardPanel m_panel;
        private boolean _createExtension = false;
        private EditorContext _context;

        /**
         * Initializes the user interface. UI components
         * are assembled in the ServerCheckWizardPanel class.
         * That class is not presented in this topic -- it's
         * typical of a Swing component. See the ControlDevKit
         * sample application for its code.
         */
        public ServerCheckWizard ()
        {
            m_panel = new ServerCheckWizardPanel();
        }

        /**
         * Tells WebLogic Workshop whether to display an option
         * to create a JCX file. The constant returned here
         * tells it that an instance is all that is needed.
         */
        public int getConfigurationInfo()
        {
            return CONFIG_INSERT_INSTANCE;
        }
        /**
         * Gives the wizard a way to interact with the IDE.
         */
        public void setContext(EditorContext ctx)
        {
            _context = ctx;
            m_panel.setContext(ctx);
        }

        /**
         * Provides a way for subclasses to get the context as needed.
         */
        public EditorContext getContext()
        {
            return _context;
        }

        /**
         * Returns the user interface component to use.
         */
        public JComponent getComponent()
        {
            return m_panel;
        }

        /**
         * Provides a place to execute code when the control's user
         * clicks the "Create" button on the insert dialog.
         */
        public boolean onFinish()
        {
            if (super.onFinish() == false)
            {
                return false;
            } else
            {
                return true;
            }
        }

        /**
         * Provides to WebLogic Workshop an ArrayList containing
         * the annotations it should write preceding the control
         * instance.
         */
        public ArrayList getInstanceAnnotations()
        {
            // An ArrayList for the annotation attributes. There are four.
            ArrayList attributeList = new ArrayList();
            // An ArrayList for this control's two annotations.
            ArrayList annotationsList = new ArrayList();

            /*
             * The attribute ArrayList is filled with TagAttributeValue
             * instances containing attribute name/value mappings. These
             * are used below for the jc:server-data annotation.
             *
             * Attribute values are retrieved from the insert dialog box UI.
             */
            attributeList.add(new TagAttributeValue("server-name", m_panel.getServerName()));
            attributeList.add(new TagAttributeValue("url", m_panel.getServerURL()));
            attributeList.add(new TagAttributeValue("user-name", m_panel.getUserName()));
            attributeList.add(new TagAttributeValue("password", m_panel.getPassword()));

            /*
             * The annotation ArrayList is filled with TagAttributeList instances
             * containing the annotation name/attribute-list mappings.
             * Note that the second annotation uses the attribute ArrayList.
             */
            annotationsList.add(new TagAttributeList("common:control", null));
            annotationsList.add(new TagAttributeList("jc:server-data", attributeList));
            return annotationsList;
        }
    }

Related Topics

None.