Back to Eclipse Corner Articles
Printer-friendly version

This article is known to apply to the following Eclipse project:

Help us keep this information up-to-date: let us know if this information applies to other projects or releases.

To comment on this article, ask questions, or propose corrections, please see bug 202795.


Eclipse Forms: New in 3.3

Eclipse Forms: New in 3.3

Summary

Eclipse Forms is a layer on top of SWT that allows you to achieve a web-like feel inside your desktop applications without having to resort to an embedded browser. In this article, the new features added to Eclipse Forms in version 3.3 are discussed. Readers are expected to be familiar with Eclipse Forms and its concepts. If that is not the case, a good starting point would be the article, Eclipse Forms: Rich UI for Rich Client Applications. Another valuable resource is the online documentation.

By Adam Archer, IBM Canada Ltd.
September 5, 2007

Introduction

Eclipse Forms is a layer on top of SWT that allows you to achieve a web-like feel inside your desktop applications without having to resort to an embedded browser. Due to its sophisticated functionality and relatively small footprint, its popularity has been constantly growing since its inception.

As the clients of forms has grown in numbers, so too has the complexity of their implementations. Developers are using forms to represent more complex resources and perform more in depth tasks than ever before. This requires a much higher level of interaction and more control over the layout and functionality of forms. One area that was lacking in previous versions was the variety of ways a developer could customize and make use of the form heading.

For this reason, the majority of the new features provided in 3.3 are related to forms headings. Clients of forms now have many more options at their disposal regarding what they can do with their headings. In addition, there have been some improvements to sections and some useful new APIs have been added.

Setup

Throughout this article code examples will be given to be added to an Eclipse view. To prepare for the remainder of the article, you can setup a plug-in project as follows:

  1. Open Eclipse 3.3 or later in a fresh workspace and close the welcome
  2. Select File > New > Project... > Plug-in Project
  3. Give the project a name and click Next twice
  4. Select Plug-in with a view and click Finish
  5. In the plug-in manifest editor, add a dependency to org.eclipse.ui.forms
  6. Open the class defining the view and overwrite its code as follows:
	public class SampleView extends ViewPart {
		private FormToolkit toolkit;
		private Form form;

		/**
		 * The constructor.
		 */
		public SampleView() {
		}

		/**
		 * This is a callback that will allow us to create the viewer and
		 * initialize it.
		 */
		public void createPartControl(Composite parent) {
			toolkit = new FormToolkit(parent.getDisplay());
			form = toolkit.createForm(parent);
			form.setText("Hello, Eclipse Forms");
		}

		/**
		 * Passing the focus request to the form.
		 */
		public void setFocus() {
			form.setFocus();
		}

		/**
		 * Disposes the toolkit
		 */
		public void dispose() {
			toolkit.dispose();
			super.dispose();
		}
	}

To test your view perform the following steps:

  1. Switch to the overview page of the plug-in manifest editor for your project
  2. Click the Launch an Eclipse application link
  3. When the new instance of Eclipse appears, select Window > Show View > Other... > Sample Category > Sample View

The view should look something like this:


Figure 1: A basic form in a view

Form Heading Improvements

As mentioned above, form headings have become much more powerful in 3.3. This portion of the article outlines all the new features and options that are available.

Title Rendering

By default, forms headings are rendered with the same background colour as the form, as seen in Figure 1. This does not make them stand out as a distinct area of the form and is also generally not very attractive. Previous to 3.3, two mutually exclusive alternatives were available to customize the background. Clients could either specify a background image to be tiled across the entire heading or an array of colours to generate a gradient background. The difficulty with this approach is that designers need to take into account the different platforms and system settings that may be present in a user's environment. The design must be appealing under all configurations. Since Eclipse supports so many different platforms, this was no easy task.

In 3.3, forms provides a simple mechanism to delegate painting a gradient on the heading to the FormToolkit. The toolkit provides a colour combination designed to work well under all supported configurations. Clients can access the colours directly through the following constants:

  • H_GRADIENT_START
  • H_GRADIENT_END
  • H_BOTTOM_KEYLINE1
  • H_BOTTOM_KEYLINE2

Although the colours are available as constants, you can have forms paint your heading with this configuration by modifying your form code as follows:

	public void createPartControl(Composite parent) {
		toolkit = new FormToolkit(parent.getDisplay());
		form = toolkit.createForm(parent);
		form.setText("Hello, Eclipse Forms");
		toolkit.decorateFormHeading(form);	// NEW LINE
	}

Using the code above, the form will appear as follows:


Figure 2: A basic form with a decorated heading

Toolbar Layout Changes

As developers started using forms to achieve more and more complex goals, the variety of content placed in the head client grew exponentially. Previous to 3.3 the head client on the FormHeading was added to the same row as the title. This approach severely limited the space that developers had to work with and limited the usefulness of the feature.

In 3.3 the head client has been moved to the second row of the heading. The toolbar, by default will remain on the first row with the title, although the option is available to move it to the second row using the following line of code: form.setToolBarVerticalAlignment(SWT.BOTTOM);

To see the effects for yourself you can add a simple head client and toolbar by modifying your code as follows:

	public void createPartControl(Composite parent) {
		toolkit = new FormToolkit(parent.getDisplay());
		form = toolkit.createForm(parent);
		form.setText("Hello, Eclipse Forms");
		toolkit.decorateFormHeading(form);
		form.setHeadClient(toolkit.createButton(form.getHead(), "This is the head client", SWT.PUSH));	// NEW LINE
		form.getToolBarManager().add(new Action("This is the toolbar") { });	// NEW LINE
		form.getToolBarManager().update(true);	// NEW LINE
		form.setToolBarVerticalAlignment(SWT.BOTTOM); // NEW LINE
	}

With this code the form will appear as follows:


Figure 3: A form with a head client and the toolbar aligned to the bottom

If the last line from the sample above is commented out, then the default alignment will be used for the toolbar and the form will render like this:


Figure 4: A form with a head client and default toolbar alignment

Message Handling

One very important aspect of rich user interface design is ensuring that when a user makes a mistake, they are notified immediately and assisted in correcting it. In large, complex forms it may be difficult to determine what is wrong without obvious visual cues.

For this reason, in 3.3 the error message handling framework has been improved. Messages of types defined in org.eclipse.jface.dialogs.IMessageProvider will now be represented with text between the title and the toolbar on the form heading (or in place of the toolbar if it is not used). In addition to displaying a textual representation of the message, an appropriate image will be displayed in the header in place of the form's image until the message is resolved.

By default, the message will be displayed as static text, but an IHyperlinkListener can be added to the form to turn the message into a hyperlink that will inform the listener of any clicks.

Here is a code sample demonstrating how to add a message to your form and register a hyperlink listener:

		toolkit.decorateFormHeading(form);
		form.setHeadClient(toolkit.createButton(form.getHead(), "This is the head client", SWT.PUSH));
		form.getToolBarManager().add(new Action("This is the toolbar") { });
		form.getToolBarManager().update(true);
		form.addMessageHyperlinkListener(new HyperlinkAdapter());	// NEW LINE
		form.setMessage("This is an error message", IMessageProvider.ERROR);	// NEW LINE

With these changes, the form will appear as follows:


Figure 5: A form with an error message and a message hyperlink listener

Drop-Down Menus

With the development of more complicated forms comes a wider variety of interactions that may be required. To help developers make useful functions quickly accessible, a new menu manager is now available. It can be retrieved and used to populate a menu which will be rendered next to the form's title when it is not empty.

Below is a code snippet demonstrating how to add a menu to your form heading (note that the changes from the message handling section have been removed):

		toolkit.decorateFormHeading(form);
		form.setHeadClient(toolkit.createButton(form.getHead(), "This is the head client", SWT.PUSH));
		form.getToolBarManager().add(new Action("This is the toolbar") { });
		form.getToolBarManager().update(true);
		form.getMenuManager().add(new Action("This is the menu") { });	// NEW LINE

When the menu button is clicked, the menu will appear at the cursor as shown below:


Figure 6: A form with a menu

The menu can also be accessed by right-clicking on the title or title image.

Drag and Drop Support

In some cases, forms represent objects that have meaning to other workbench components. For instance, you could have a form based editor that allows you to edit the contents of a proprietary file type that will be referenced elsewhere. In 3.3, API has been created to add drag and drop support to your forms. This support allows you to drag your forms so they can be dropped into other areas. With this feature you would be able to, for instance, drag your form into other files to quickly and easily create references to the associated object. This saves the user from having to remember a URL or browse back to the item from a different editor.

Due to the complex nature of SWT's drag and drop functionality, a programmatic example will not be given here. The methods that can be used to add the support to your form are Form.addTitleDragSupport(int operations, Transfer[] transferTypes, DragSourceListener listener) and Form.addTitleDropSupport(int operations, Transfer[] transferTypes, DropTargetListener listener). For more information on using these methods, see the Form class javadoc or the Adding Drag and Drop to an SWT Application article from Eclipse Corner.

Once drag support has been properly added to the form, the title will change colours as the cursor nears and enters the draggable area. This effect is shown below.


Figure 7: A draggable form with the cursor near the title


Figure 8: A draggable form with the cursor over the title

Section Improvements

Sections have become the fundamental building blocks of most forms created today. A common approach to form design is to have several columns of adjacent sections. However, when sections are given text clients that are taller than their title text, the title area grows accordingly to accommodate the client. Unfortunately, this means that adjacent sections with similar content will not line up properly and may look sloppy.

In 3.3, new API has been added to ExpandableComposite to allow designers to account for this limitation. There is a method, ExpandableComposite.getTextClientHeightDifference() that will return the number of pixels the title area was increased by to accommodate the text client. This can be used to set the ExpandableComposite.descriptionVerticalSpacing field (default is 0) or the ExpandableComposite.clientVerticalSpacing field (default is 3). These fields specify the padding to place above the description and the client area respectively. Note that if there is no description, then the descriptionVerticalSpacing field will have no affect.

Here is a code snippet from the org.eclipse.ui.forms.examples.internal.rcp.SecondPage class from the org.eclipse.ui.forms.examples plug-in that demonstrates usage of this feature:

		Section s1 = createTableSection(form, toolkit, "First Table Section", true);
		Section s2 = createTableSection(form, toolkit, "Second Table Section", false);
		s2.descriptionVerticalSpacing = s1.getTextClientHeightDifference();

Below is a pair of images to demonstrate the different this makes. These screenshots were both created using the Form Examples plug-in:


Figure 9: A pair of sections aligned using getTextClientHeightDifference()


Figure 10: A pair of sections without custom alignment

Shared-Header Form Editor

The org.eclipse.ui.forms.editor.FormEditor class provides a starting point for creating multi-page editors with form pages. One common use case of this class is to use form pages that all have the same titles, head clients and toolbar items. To achieve this prior to 3.3, implementers had to have all of their child pages create the headers in the same way. This not only meant that there was a lot of overhead and code duplication involved in achieving a consistent look, but also that the editor was using system resources excessively to create copies of all the same controls.

In 3.3 the org.eclipse.ui.forms.editor.SharedHeaderFormEditor class has been added to allow the header area to be shared among all the pages. In order to implement this properly, subclasses must override the createHeaderContents(IManagedForm headerForm) class to populate the header. In addition, any header controls that require life cycle management should be wrapped with the IFormPart interface. Also, child pages of the SharedHeaderFormEditor should not have their own header or else two headers will be displayed.

Message Manager

As discussed above, support has been added to show messages in the form heading. To make the handling of multiple messages within a form easier, a message manager has been made available in 3.3 through the IManagedForm interface. The manager is provided as an interface (IMessageManager).

The message manager will track multiple messages for the user at a time and will show text-based on the most severe message present at any given time (ERROR > WARNING > INFO). It also provides the ability, when adding a message, to associate a control with it. If this is done, the message manager will decorate the specified control with an image appropriate to the message type.

If the message label in the form heading is configured to be a hyperlink (as discussed earlier in this article), the href attribute of the HyperlinkEvent will be an array of IMessage objects. This array is used internally by the message manager to create a tooltip for the hyperlink. It is also available for clients to do whatever they like with the information once the link is clicked.

The advantages of this API are, first, that it inherently allows many messages to be retained on a form at once and, second, that it hides the details of how control decoration is performed.

A good example implementation of this API is in the org.eclipse.ui.forms.examples.internal.rcp.ErrorMessagesPage class from the org.eclipse.ui.forms.examples plug-in. Below are two screenshots of the implementation:


Figure 11: An example implementation of the message manager showing its tooltip


Figure 12: An example of what can be done with a HyperlinkListener using the message manager

Conclusion

This article has outlined the new features added to Eclipse Forms in version 3.3. Its goal was to pick up where the previous forms article left off and to help clients of the plug-in make better use of the tools at their disposal to increase the quality of the Rich UIs. Feedback can be sent to platform-ua-dev@eclipse.org.