Version 2.7
Copyright © 2008, 2009, 2010, 2011, 2012 Lars Vogel
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 | ||
Table of Contents
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.
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.
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 |
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();
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.
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.
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();
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.

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.
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