Field assist

Often, a user is expected to provide textual information in a simple field such as a text field or combo box. Although the application code that populates these fields is generally much simpler than code that populates a complex widget such as a table or tree, these "simple" fields usually place more burden on the user. The user must identify which fields require content, whether a field contains valid content, and what choices are expected. The JFace field assist support provides classes that help guide the user through input tasks.

The org.eclipse.jface.fieldassist package provides assistance in two ways. Control decorations allow you to place image decorations adjacent to a control in order to cue the user about the status of a particular field. Content proposal support allows you to provide a content assist popup that provides content choices for the user.

Control decorations

A control decoration is a rendered image that can be placed adjacent to a field in a window or dialog. Decorations may be placed adjacent to a control in one of six positions (top, center, or bottom to the left or right of the control). One or more control decorations may be defined for a control. The API for ControlDecoration allows you to hide and show the decoration, assign descriptive text to the decoration, and listen to events associated with the decoration.

Creating a control decoration

Creating a control decoration is straightforward. Clients simply specify the control to be decorated and SWT constants describing the position of the decoration relative to the control. Consider this snippet, in which an application creates a text control inside one of its dialogs:

// Create a text field
Text text = new Text(parent, SWT.BORDER);
text.setText("some text"); 

A decoration can then be created for the control.

// Create a control decoration for the control.
ControlDecoration dec = new ControlDecoration(text, SWT.TOP | SWT.LEFT);

Once the decoration is created, its image and text can be specified.

// Specify the decoration image and description
Image image = JFaceResources.getImage("myplugin.specialimage");
dec.setDescriptionText("This field is special");

Clients can use the setShowOnlyOnFocus method to specify whether the decoration should be shown only when the control has focus, or whether it should be shown at all times. The setShowHover method allows clients to configure whether the description text is shown in a hover when the mouse hovers over the decoration.

Laying out decorated controls

When adding decorations to controls that appear inside a dialog or window, you should make sure there is enough space adjacent to the control to render the decoration without overlapping other controls. For example, when using a grid layout in a dialog, there should be enough margin space between the cells in the grid so that a decoration can be shown adjacent to controls in the cells.

// Set the layout data to ensure there is enough space for the decoration
GridData data = new GridData(IDialogConstants.ENTRY_FIELD_WIDTH, SWT.DEFAULT);
data.horizontalIndent = image.getBounds().width;

The width of a decoration is simply the width of its image. However, layout can get more complicated if you are using decorations with different widths. If this is the case, you can simplify things by first creating field decorations to represent all of your control decorations.

Field decorations

A FieldDecoration is simply a data object that combines the image and text used to show a decoration. Once created, these field decorations can be registered in the FieldDecorationRegistry.

Field decoration registry

The field decoration registry allows you to register and access field decorations using a string id. This provides a convenient way for you to refer to decorations used throughout your application. You may choose to define API that exposes your decoration ids if you wish to make them available to other plug-ins. Note that registering a decoration does not manage the life-cycle of the images inside those decorations. Your application can decide how to manage these images. For example, the JFace image registry may be used to register and manage the image's life-cycle. Alternatively, your application may wish to create the image on demand and dispose of it when it is no longer needed. The javadoc for the registration methods in FieldDecorationRegistry explains the different ways that images can be specified when registering a decoration. To determine the margin width needed for decorations, you can use the FieldDecorationRegistry protocol to access the width of the largest decoration and create the necessary indent.

// Set the layout data
GridData data = new GridData(IDialogConstants.ENTRY_FIELD_WIDTH, SWT.DEFAULT);
data.horizontalIndent = FieldDecorationRegistry.getDefault().getMaximumDecorationWidth(); 

Although the field assist support does not dictate how decorations should be used, the registry does define standard decorations that can be used by applications to show certain states for a field. For example, the following snippet uses a standard decoration for indicating an error in a field:

// Create a control decoration to indicate an error.
ControlDecoration dec = new ControlDecoration(text, SWT.TOP | SWT.LEFT);
FieldDecoration errorFieldIndicator = FieldDecorationRegistry.getDefault().

Content proposals

In addition to annotating fields with decorations, applications may provide a content proposal assistant that activates a proposal popup for a field. You may install a ContentProposalAdapter on an arbitrary control in order to provide this behavior. The following snippet installs a content proposal adapter on a text control. Note that this text control could be a control created directly by the application or one obtained from a decorated field.

autoActivationCharacters = new char[] { '#', '(' };
keyStroke = KeyStroke.getInstance("Ctrl+Space");
// assume that myTextControl has already been created in some way
ContentProposalAdapter adapter = new ContentProposalAdapter(
	myTextControl, new TextContentAdapter(), 
	new SimpleContentProposalProvider(new String [] {"ProposalOne", "ProposalTwo", "ProposalThree"}),
	keyStroke, autoActivationCharacters);

In order to get and set the content of the control when the user chooses a proposal in the popup, the adapter must be supplied with an instance of IControlContentAdapter, which can retrieve and set the contents of a particular kind of control. For text fields, you can use the class TextContentAdapter. However, you have the flexibility to implement IControlContentAdapter to use the content proposal adapter with any other kind of control.

When creating a content proposal adapter, you must also specify an instance of IContentProposalProvider, from which the proposals themselves are retrieved. This provider is responsible for returning an array of content proposals. The proposals themselves are specified as instances of IContentProposal, from which the label and content of the proposal can be obtained, in addition to other information, such as a detailed description of the proposal.

In the example above, the SimpleContentProposalProvider is used. This provider is defined by specifying a simple array of Strings as the content proposals. The simple provider implements the necessary protocol to map each string into the expected IContentProposal. The flexibility of IContentProposalProvider allows you to implement a proposal provider with advanced features, such as filtering the proposals based on the control's content, providing explanatory labels in the popup instead of the actual content that will be inserted, and specifying the expected cursor position after a proposal is inserted. See the Field Assist Example and search for implementors of IContentProposalProvider for advanced usage.

Configuring a content proposal adapter

We've seen that the basic definition for a content proposal adapter includes the control for which the proposals are provided, the content adapter used to alter the content of the control, and the proposal provider that defines the list of proposals in the popup. In addition to these basics, there are many ways that the content proposal adapter can be configured:

The Field Assist Example allows you to configure these various options in the example preferences and try out the different combinations. For example, the adapter can be configured so that it is invoked explicitly with a keystroke and inserts the proposal content into the control, causing it to behave much like the text editor content assist. See the javadoc for more specifics about each of these methods and how they interact with each other.

Auto complete fields

The content proposal adapter methods can be used to configure an adapter so that it behaves more like the type-ahead field completion used in web browser URL or search fields. AutoCompleteField can be used when this style of interaction is desired. Clients need only specify the list of completions when defining an auto complete field. Configuration of the content proposal adapter and proposal provider will be handled internally.

Workbench field assist

Field assist support at the JFace level gives your application a lot of flexibility in determining how to decorate fields and show proposals for field content. This is desirable for stand-alone JFace applications or stand-alone rich client applications. However, if your application is intended to integrate with other plug-ins, such as the Eclipse SDK or third-party plug-ins, you will probably want to use the field assist support in a way that is consistent with other plug-ins. The workbench defines utility classes that use field assist for specific kinds of interactions.

For example, the class ContentAssistCommandAdapter configures a content proposal adapter for content-assist style insertion. It provides a handler for the workbench-level content assist command, so that the content proposal popup is opened when the user invokes the keystroke or trigger sequence that has been specified in the workbench key bindings. It can optionally provide a control decoration with the content assist light bulb image. See the org.eclipse.ui.fieldassist package for more detail about workbench-level field assist.

This package is expected to evolve as the workbench expands its use of field assist and standardizes the use of decorations for certain field states.