vogella training Android Training Eclipse Training

Eclipse JFace Overview

Lars Vogel,

Version 2.7

17.01.2012

Revision History
Revision 0.1 01.07.2007 Lars Vogel
created
Revision 0.2 - 2.7 12.09.2007 - 17.01.2012 Lars
Vogel
bug fixes and enhancements

Eclipse JFace Tutorial

This tutorial gives a overview about Eclipse JFace. It discusses the base concept of JFace Viewers and the JFace LocalResourceManager. The tutorial is is based on Eclipse 4.2 (Juno).


Table of Contents

1. Eclipse JFace Overview
2. Eclipse JFace Viewers
2.1. Eclipse JFace viewers
2.2. Standard JFace Viewers
3. JFace ComboViewer
4. Resource Manager for Colors, Fonts and Images
5. ControlDecorations and FieldAssists
5.1. ControlDecorations
5.2. FieldAssists
6. Thank you
7. Questions and Discussion
8. Links and Literature
8.1. Source Code
8.2. JFace Resources
8.3. Other JFace Resources
8.4. vogella Resources

1. Eclipse JFace Overview

Eclipse JFace is based upon the UI toolkit SWT. JFace provides classes and frameworks which simplify common SWT uses cases.

JFace does not hide the SWT API; therefore SWT knowledge is still required, if you program JFace. JFace provides Preferences and Preference pages, Wizards and Dialogs.

It also provides model based widgets sets, called JFace Viewers which simplify the mapping of a data model to a visual representation. For example you find the Viewers for ComboBoxes, Tables and Trees.

JFace provides helper classes to effectively manage your system resources, like colors, images and fonts.

JFace Data Binding is a framework which connects properties of objects. It is typically used to synchronize fields of the user interface with properties of model objects and allows to include validation and conversion in this synchronization process.

2. Eclipse JFace Viewers

2.1. Eclipse JFace viewers

Eclipse JFace Viewers allow to display a domain model in a list, tree or table without converting the domain model beforehand.

Viewer allows to set a ContentProvider which provides the data to the Viewer. The ContentProvider makes no assumption how the data model is displayed by the view.

You also define at least one LabelProvider to a Viewer. The LabelProvider defines how the data from the model will be displayed in the Viewer.

LabelProvider usually follows the template approach: you have an interface which describes an API and a template class, which delivers a reasonable implementation for the interface.

2.2. Standard JFace Viewers

JFace provides several standard Viewer. The following table lists the most important ones.

Table 1. JFace Viewers

Class Description
org.eclipse.jface.viewers.ComboViewer Displays a combo (drop-down box)
org.eclipse.jface.viewers.ListViewer Display a simple list
org.eclipse.jface.viewers.TreeViewer Displays a tree
org.eclipse.jface.viewers.TableViewer Displays a table


The related ContentProvider interfaces are:

Table 2. Content Provider

Class Description
IStructuredContentProvider Used for list, combo and table Viewer. Default implementation: ArrayContentProvider
ITreeContentProvider Used for trees, has additional methods to determine the children and the parents of elements.


Typical LabelProviders are:

Table 3. Label providers

Interface Template class Description
ILabelProvider LabelProvider Used for lists and trees, displays per element a icons and / or a text element.
ColumnLabelProvider CellLabelProvider Used for tables, defines a label provider per column.
ITableLabelProvider LabelProvider Old interface, don't use this anymore


3. JFace ComboViewer

A simple example for a JFace Viewer framework is the ComboViewer class. Assume the following data model.

			
package de.vogella.rcp.intro.first;

public class Person {
	private String firstName;
	private String lastName;

	public Person(String firstName, String lastName) {
		this.firstName = firstName;
		this.lastName = lastName;

	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

}

		

Given this data model, here is an example how you could use a ComboViewer in a Part (View).

			
// This happens in the method which creates the user interface
// parent is the composite which is available
GridLayout layout = new GridLayout(2, false);
parent.setLayout(layout);
Label label = new Label(parent, SWT.NONE);
label.setText("Select a person:");
final ComboViewer viewer = new ComboViewer(parent, SWT.READ_ONLY);
viewer.setContentProvider(new ArrayContentProvider());
viewer.setLabelProvider(new LabelProvider() {
	@Override
	public String getText(Object element) {
		if (element instanceof Person) {
			Person person = (Person) element;
			return person.getFirstName();
		}
		return super.getText(element);
	}
});

Person[] persons = new Person[] { new Person("Lars", "Vogel"),
	new Person("Tim", "Taler"), new Person("Jim", "Knopf") };
// Set set the input to the viewer this input will be send to the
// content provider
viewer.setInput(persons);

// React to the selection of the viewer
// Note that the viewer return the real object and not just a string
// representation
viewer.addSelectionChangedListener(new ISelectionChangedListener() {
	@Override
	public void selectionChanged(SelectionChangedEvent event) {
		IStructuredSelection selection = (IStructuredSelection) event
			.getSelection();
		System.out.println(((Person) selection.getFirstElement())
			.getLastName());
	}
});


		

Setting and getting a selection works with the pure data model.

			

// You can select a object directly via the domain object
Person person = persons[0];
viewer.setSelection(new StructuredSelection(person));

// Get the selection, returns the data model object
StructuredSelection selection = (StructuredSelection) viewer.getSelection();
Person p = (Person) selection.getFirstElement();
		

4. Resource Manager for Colors, Fonts and Images

SWT is based on the native widgets of the OS system. Whenever a SWT widget is allocated, a corresponding OS specific widget is created.

The Java garbage collector cannot automatically clean-up these references.

Fortunately all widgets which are created based on a parent widget are automatically disposed when the parent Composite is disposed.

If you develop Eclipse plug-ins, the Composite of a Part is automatically disposed once the Part is closed. Therefore these SWT widgets are handled automatically in Eclipse plug-in projects.

This rule does not apply for colors, fonts and images, as these may be re-used in other places. For this reason they need to get explicitly disposed. Fortunately JFace provides the class LocalResourceManager.

LocalResourceManager is created with a reference to a Composite. If this Composite is disposed, the resources created by the LocalResourceManager will also be disposed.

			
// Create the manager and bind to a widget
LocalResourceManager resManager = 
	new LocalResourceManager(JFaceResources.getResources(), composite);

// Create resources
Color color = resManager.createColor(new RGB(200, 100, 0));
Font font = resManager.createFont(FontDescriptor.createFrom("Ariel", 10, SWT.BOLD));
// Get an imageDescriptor and create Image from it
Image image = resManager.createImage(imageDescriptor);
		

The createImage() expects an ImageDescriptor class. To get one ImageDescriptor from a image file stored in your current plug-in use the following:

			
Bundle bundle = FrameworkUtil.getBundle(this.getClass());
URL url = FileLocator.find(bundle, new Path("icons/alt_window_32.gif"), null);
ImageDescriptor image = ImageDescriptor.createFromURL(url);
		

To create the Image from the ImageDescriptor you can use the createImage() method.

5. ControlDecorations and FieldAssists

The org.eclipse.jface.fieldassist package provides assistance to provide information about the possible inputs and status of an input field, e.g. text field or combo box.

5.1. ControlDecorations

The ControlDecorations class allow to place image decorations on SWT controls to show additional information about the control. These decorations can also have descriptions which are displayed once the user places the mouse over them. During the layout of your screen you need to make sure that enough space is available to display these decorations.

The following shows how to create ControlDecorations and how to set a description and an icon to it.

				
// Create the decoration for the text UI component
final ControlDecoration deco = new ControlDecoration(text, SWT.TOP | SWT.RIGHT);

// Re-use an existing image
Image image = FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_INFORMATION).getImage();
// Set description and image
deco.setDescriptionText("This is a tooltip text");
deco.setImage(image);
// Hide deco if not in focus
deco.setShowOnlyOnFocus(false);
			

You can also hide and show the decoration.

				
deco.hide();
deco.show();
			

5.2. FieldAssists

A ContentProposalAdapter provides the help on the input of a field.

In the following example the content proposal should get activated via certain keys ("." and "#") as well as the key combination "CTRL+Space".

Change the View.java to the following.

				
Text text = new Text(parent, SWT.BORDER);

// Create the decoration for the text UI component
final ControlDecoration deco = new ControlDecoration(text, SWT.TOP
	| SWT.RIGHT);

// Re-use an existing image
Image image = FieldDecorationRegistry.getDefault()
	.getFieldDecoration(FieldDecorationRegistry.DEC_INFORMATION)
	.getImage();

// Set description and image
deco.setDescriptionText("Use CNTL + SPACE to see possible values");
deco.setImage(image);

// Hide deco if not in focus
deco.setShowOnlyOnFocus(false);

// Also if the text UI componet is not empty hide the decoration
text.addModifyListener(new ModifyListener() {
	@Override
	public void modifyText(ModifyEvent e) {
		Text text = (Text) e.getSource();
		if (text.getText().length() > 0) {
		  deco.hide();
		} else {
		  deco.show();
		}
	}
});

// Help the user with the possible inputs
// "." and "#" will also activate the content proposals
char[] autoActivationCharacters = new char[] { '.', '#' };
KeyStroke keyStroke;
//
try {
	keyStroke = KeyStroke.getInstance("Ctrl+Space");
	ContentProposalAdapter adapter = new ContentProposalAdapter(text,
		new TextContentAdapter(),
		new SimpleContentProposalProvider(new String[] {
			"ProposalOne", "ProposalTwo", "ProposalThree" }),
			keyStroke, autoActivationCharacters);
	} catch (ParseException e1) {
	e1.printStackTrace();
}

			

If use the result should look similar to the following.

Running application with ControlDecoration and FieldAssists

6. Thank you

Please help me to support this article:

Flattr this

7. Questions and Discussion

Before posting questions, please see the vogella FAQ. If you have questions or find an error in this article please use the www.vogella.com Google Group. I have created a short list how to create good questions which might also help you.

8. Links and Literature

8.1. Source Code

Source Code of Examples

8.4. vogella Resources

Eclipse RCP Training (German) Eclipse RCP Training with Lars Vogel

Android Tutorial Introduction to Android Programming

GWT Tutorial Program in Java and compile to JavaScript and HTML

Eclipse RCP Tutorial Create native applications in Java

JUnit Tutorial Test your application

Git Tutorial Put everything you have under distributed version control system