Adding Dockable Frames

You've probably noticed that most of the WebLogic Workshop's windows share characteristics. They have tabs displaying their names, they are dockable (you can drag a window from one part of the IDE to another and make it stick there), they feature close boxes, and so on. As extensions, these windows are known as "frames". You can use frames to provide a wide range of features, such as views on data in your extension, documents with which the extension is interacting, and so on. In particular, a frame is useful for displaying data that the user may want to get at often in the course of their work. For example, a frame could offer quick access to custom tool functionality.

The following simple frame example is created by the FrameViewSimple sample extension.

For frame extension samples, see FrameViewSimple Sample.

Building Frame Extensions

To add support for a new frame:

Extension XML for Frames

The extension XML for a frame extension specifies a few simple aspects of the frame's UI as well as specifying which of your extension classes contains the frame content and logic. The user interface characteristics specified in the extension XML are limited to customizing characteristics managed and displayed by the IDE; from a visual point of view, this means items at and beyond the frame's borders. In other words, you write Java code for the interior. The UI pieces defined in the XML include:

For reference information on action extension XML, see Frame Extension XML Reference.

The following example shows the extension XML for a very simple single-frame extension.

<extension-definition>
    <extension-xml id="urn:com-bea-ide:frame">
        <frame-view-set>
            <frame-view class="ideExtensions.frameViewSimple.FrameView" label="hi.yo.peace." 
                askavailable="true" />
	    </frame-view-set>
    </extension-xml>
</extension-definition>

The <frame-view-set> stanza collects a set of frames; you can use an optional scope attribute to specify a circumstance under which the frames should be available for viewing. Each child <frame-view> element specifies the class that should be used for the frame's internal UI, and the label that should be used on the frame's tab. Including the askavailable attribute with a value of "true" tells WebLogic Workshop that you want it to query your implementation class's isAvailable method (as described below) to determine whether to make the frame available. Keep in mind that setting this attribute to "true" may also impact the performance of your extension (and the IDE in general) because of the frequency with which the IDE may actually do the asking.

The value of the class attribute must be the fully-qualified name of a class that implements IFrameView; for more information, see Implementing Frame Logic, below.

Arranging Multiple Frames

When there are multiple frames, the <application-layout> stanza specifies their startup arrangement in the IDE.

Note: Of course, the user can rearrange the frames as they choose. Keep in mind, too, that the position of frames is stored among the IDE preferences. To reset the IDE to a default state (such as when you're debugging frame arrangements), you'll need to rename or delete the preferences file. This file is located at USER_HOME/.workshop.zpref.

At the right of the following illustration, you can see three frames grouped together. Each of these frames uses the same implementation of IFrameView, but they're referred to separately in the extension.xml.

The following XML defines startup positions for the frames in the illustration. Note that the frames themselves are specified in the <frame-view-set> stanza. Their arrangement at startup, however, is defined in the <application-layout> stanza.

<extension-xml id="urn:com-bea-ide:frame">
  
    <frame-view-set scope="main">
        <frame-view id="frame1" class="ideExtensions.frameViewSimple.FrameView" 
            label="Frame 1" />
        <frame-view id="frame2" class="ideExtensions.frameViewSimple.FrameView" 
            label="Frame 2" />
        <frame-view id="frame3" class="ideExtensions.frameViewSimple.FrameView" 
            label="Frame 3" />
    </frame-view-set>

<application-layout id="main"> <frame-layout> <frame-container orientation="east" proportion="20%"> <frame-view-ref id="frame1" class="ideExtensions.frameViewSimple.FrameView" /> <frame-view-ref id="frame2" class="ideExtensions.frameViewSimple.FrameView" /> <frame-view-ref id="frame3" class="ideExtensions.frameViewSimple.FrameView" /> </frame-container> </frame-layout> </application-layout> </extension-xml>

The <application-layout> stanza's id attribute specifies the IDE "mode" in which the group will be visible. Here, "main" means "not debugging"; a value of "urn:com-bea-ide:debug" would mean this group is available when the IDE is in debug mode.

The <frame-container> stanza specifies through its orientation attribute where in the IDE the group should be placed at startup. You can have multiple <frame-container> stanzas nested inside one another to create nested frames. Keep in mind when nesting containers that the orientation attribute is only valid on the root <frame-container> stanza. In other words, only the root can be responsible for the group's position in the IDE as a whole.

The <frame-view> elements, of course, specify what should be displayed inside the group. As you can see here, you can use the same frame implementation in multiple places as long as you disambiguate them with differing id attribute values.

Implementing Frame User Interface and Logic

The core of a frame logic is your implementation of the IFrameView interface, which has two methods: getView and isAvailable.

Implementing the getView Method

The IDE calls your implementation of the getView method to retrieve the user inteface to display inside the frame's borders. Your return value must be a class that extends java.awt.Component, a superclass for dialogs, panels, and UI you might want the IDE to display in your frame. Typically, you'll want to write and return a class that extends a Swing class such as JPanel or JScrollPane. These classes extend Component (through JComponent and others), and work well as containers for other Swing UI components such as buttons, boxes, and so on.

For more information from Sun on Swing components that act as containers, see http://java.sun.com/docs/books/tutorial/uiswing/components/components.html. For links to information on Swing, see Getting Started with UI Programming.

Implementing the isAvailable Method

You can have the IDE call your isAvailable implementation find out if your frame should be available for display. The IDE will call this method only if the corresponding <frame-view> element in your extension XML specifies an askavailable attribute whose value is "true".

Returning true from isAvailable signals to the IDE that it's okay to display your frame. So when would you want to return false? If your frame should be available only under certain circumstances, such as when a particular document type is open, or a particular project type is current, your isAvailable implementation should include code to discover if these things are true and return a value accordingly.

Keep in mind that prompting the IDE to call isAvailable (by setting the askavailable attribute to "true") can impair overalll performance because the call may occur often. You should only handle availability when your frame's usefulness relies on context.

APIs you might find useful in writing code for this method include:

Related Topics

FrameViewSimple Sample

IFrameView Interface

FrameSvc Class

Frame Extension XML Reference