| Java, Eclipse and Web programming Tutorials |
Version 0.7
Copyright © 2008 - 2010 Lars Vogel
23.02.2010
| Revision History | ||
|---|---|---|
| Revision 0.1 | 23.05.2008 | Lars Vogel |
| Created Article | ||
| Revision 0.2 | 25.12.2008 | Lars Vogel |
| Renamed projects, included ControlDecoration | ||
| Revision 0.3 | 22.03.2009 | Lars Vogel |
| Moved model to separate plugin | ||
| Revision 0.4 | 23.03.2009 | Lars Vogel |
| Introduced listviewer | ||
| Revision 0.5 | 10.06.2009 | Lars Vogel |
| Updated to Eclipse 3.5 (Galileo) | ||
| Revision 0.6 | 02.02.2010 | Lars Vogel |
| improved EMF | ||
| Revision 0.7 | 23.02.2010 | Lars Vogel |
| fixed typo | ||
Eclipse JFace Databinding
This article explains the Eclipse JFace Databinding. It explain how to connect your data model with the UI so that both will be automatically synchronized. It will demonstrate the usage of validators and field decorators. EMF databinding is also demonstrated.
The article assumes that you are familiar with Eclipse RCP development. In this article Eclipse 3.5 (Galileo) is used.
Table of Contents
Databinding provides a flexible way of connecting a domain model with the User Interface.
The Eclipse Data Binding connects your domain model and the user interface. Changes in both will be automatically synchronized. You can use default or customized data validators to check the data and can use converters to convert the data between the UI and the domain model.
We will build an application which displays the data of a person and lets you change the person in the UI. Can you also trigger a direct change in the model via a button. Changes in the UI and the model will be synchronized with each other.

We are going to re-use the same data model for several examples. Therefore we will create the data model in a separate plugin and re-use it.
Create a plugin project "de.vogella.databinding.person.model". Do not create an activator, do not select "This plug-in will make contributions to the UI" and select "No" for the question "Do you want to create a rich client application".

Press "Finish".
To use the databinding between the UI and the domain model in both directions the domain model needs to implement PropertyChangeSupport so that the Eclipse databinding can listen to changes in the model.
Create the package "de.vogella.databinding.person.model" and the following classes.
package de.vogella.databinding.person.model;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
public class Person implements PropertyChangeListener {
private String firstName;
private String lastName;
private boolean married;
private String gender;
private Integer age;
private Address address;
private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(
this);
public Person() {
}
public void addPropertyChangeListener(String propertyName,
PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(propertyName, listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.removePropertyChangeListener(listener);
}
public String getFirstName() {
return firstName;
}
public String getGender() {
return gender;
}
public String getLastName() {
return lastName;
}
public boolean isMarried() {
return married;
}
public void setFirstName(String firstName) {
propertyChangeSupport.firePropertyChange("firstName", this.firstName,
this.firstName = firstName);
}
public void setGender(String gender) {
propertyChangeSupport.firePropertyChange("gender", this.gender,
this.gender = gender);
}
public void setLastName(String lastName) {
propertyChangeSupport.firePropertyChange("lastName", this.lastName,
this.lastName = lastName);
}
public void setMarried(boolean isMarried) {
propertyChangeSupport.firePropertyChange("married", this.married,
this.married = isMarried);
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
propertyChangeSupport.firePropertyChange("age", this.age,
this.age = age);
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
address.addPropertyChangeListener("country", this);
propertyChangeSupport.firePropertyChange("address", this.address,
this.address = address);
}
@Override
public String toString() {
return firstName + " " + lastName;
}
@Override
public void propertyChange(PropertyChangeEvent event) {
propertyChangeSupport.firePropertyChange("address", null, address);
}
}
package de.vogella.databinding.person.model;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
public class Address {
private String street;
private String number;
private String postalCode;
private String city;
private String country;
private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(
this);
public void addPropertyChangeListener(String propertyName,
PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(propertyName, listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.removePropertyChangeListener(listener);
}
public Address() {
}
public Address(String postalCode, String city, String country) {
this.postalCode = postalCode;
this.city = city;
this.country = country;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
propertyChangeSupport.firePropertyChange("street", this.street,
this.street = street);
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
propertyChangeSupport.firePropertyChange("number", this.number,
this.number = number);
}
public String getPostalCode() {
return postalCode;
}
public void setPostalCode(String postalCode) {
propertyChangeSupport.firePropertyChange("postalCode", this.postalCode,
this.postalCode = postalCode);
}
public String getCity() {
return city;
}
public void setCity(String city) {
propertyChangeSupport.firePropertyChange("city", this.city,
this.city = city);
this.city = city;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
propertyChangeSupport.firePropertyChange("country", this.country,
this.country = country);
}
public String toString() {
String s = "";
s += street != null ? street + " " : "";
s += number != null ? number + " " : "";
s += postalCode != null ? postalCode + " " : "";
s += city != null ? city + " " : "";
s += country != null ? country + " " : "";
return s;
}
}
Select the file MANIFEST.MF in the directory "META-INF". Select the tab "Runtime". Press add and add the package "de.vogella.databinding.person.model". This will enable other plugin to use the classes from this package.

Create a new Eclipse RCP project "de.vogella.databinding.person.swt" use "Hello RCP" as a template (see Create your first Eclipse RCP application for details).
Add the plugin "de.vogella.databinding.person.model" as a dependency to your plugin.
Add the plugins "org.eclipse.core.databinding", "org.eclipse.core.databinding.beans", "org.eclipse.jface.databinding" and "org.eclipse.core.databinding.property" as a dependency to your plugin.
Add via extension a view to the RCP application and create the class "de.vogella.databinding.person.PersonView" for this view.
Add the view to the perspective.
See Eclipse RCP Tutorial for details). Use the "Hello RCP" as a template.
Then implement the following code.
package de.vogella.databinding.person.swt;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.beans.BeanProperties;
import org.eclipse.core.databinding.beans.BeansObservables;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.part.ViewPart;
import de.vogella.databinding.person.model.Address;
import de.vogella.databinding.person.model.Person;
public class PersonView extends ViewPart {
public static final String ID = "de.vogella.databinding.person.swt.View";
private Person person;
private Text firstName;
private Text ageText;
private Button marriedButton;
private Combo genderCombo;
private Text countryText;
public PersonView() {
}
@Override
public void createPartControl(Composite parent) {
person = new Person();
Address address = new Address();
address.setCountry("Deutschland");
person.setAddress(address);
person.setFirstName("John");
person.setLastName("Doo");
person.setGender("Male");
person.setAge(12);
person.setMarried(true);
// Lets put thing to order
Layout layout = new GridLayout(2, false);
parent.setLayout(layout);
Label firstLabel = new Label(parent, SWT.NONE);
firstLabel.setText("Firstname: ");
firstName = new Text(parent, SWT.BORDER);
GridData gridData = new GridData();
gridData.horizontalAlignment = SWT.FILL;
gridData.grabExcessHorizontalSpace = true;
firstName.setLayoutData(gridData);
Label ageLabel = new Label(parent, SWT.NONE);
ageLabel.setText("Age: ");
ageText = new Text(parent, SWT.BORDER);
gridData = new GridData();
gridData.horizontalAlignment = SWT.FILL;
gridData.grabExcessHorizontalSpace = true;
ageText.setLayoutData(gridData);
Label marriedLabel = new Label(parent, SWT.NONE);
marriedLabel.setText("Married: ");
marriedButton = new Button(parent, SWT.CHECK);
Label genderLabel = new Label(parent, SWT.NONE);
genderLabel.setText("Gender: ");
genderCombo = new Combo(parent, SWT.NONE);
genderCombo.add("Male");
genderCombo.add("Female");
Label countryLabel = new Label(parent, SWT.NONE);
countryLabel.setText("Country");
countryText = new Text(parent, SWT.BORDER);
Button button1 = new Button(parent, SWT.PUSH);
button1.setText("Write model");
button1.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
System.out.println("Firstname: " + person.getFirstName());
System.out.println("Age " + person.getAge());
System.out.println("Married: " + person.isMarried());
System.out.println("Gender: " + person.getGender());
System.out.println("Country: "
+ person.getAddress().getCountry());
}
});
Button button2 = new Button(parent, SWT.PUSH);
button2.setText("Change model");
button2.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
person.setFirstName("Lars");
person.setAge(person.getAge() + 1);
person.setMarried(!person.isMarried());
if (person.getGender().equals("Male")) {
} else {
person.setGender("Male");
}
if (person.getAddress().getCountry().equals("Deutschland")) {
person.getAddress().setCountry("USA");
} else {
person.getAddress().setCountry("Deutschland");
}
}
});
// Now lets do the binding
bindValues();
}
@Override
public void setFocus() {
}
private void bindValues() {
// The DataBindingContext object will manage the databindings
DataBindingContext bindingContext = new DataBindingContext();
IObservableValue uiElement;
IObservableValue modelElement;
// Lets bind it
uiElement = SWTObservables.observeText(firstName, SWT.Modify);
modelElement = BeansObservables.observeValue(person, "firstName");
// The bindValue method call binds the text element with the model
bindingContext.bindValue(uiElement, modelElement, null, null);
uiElement = SWTObservables.observeText(ageText, SWT.Modify);
modelElement = BeansObservables.observeValue(person, "age");
// Remember the binding so that we can listen to validator problems
// See below for usage
bindingContext.bindValue(uiElement, modelElement, null, null);
uiElement = SWTObservables.observeSelection(marriedButton);
modelElement = BeansObservables.observeValue(person, "married");
bindingContext.bindValue(uiElement, modelElement, null, null);
uiElement = SWTObservables.observeSelection(genderCombo);
modelElement = BeansObservables.observeValue(person, "gender");
bindingContext.bindValue(uiElement, modelElement, null, null);
// Address field is bound to the Ui
uiElement = SWTObservables.observeText(countryText, SWT.Modify);
modelElement = BeanProperties.value("address.country").observe(person);
bindingContext.bindValue(uiElement, modelElement, null, null);
}
}
The DataBindingContext object will manage the databindings. The bindValue method call binds the text element with the model. The first parameter is the UIElement with an update strategy (which defines then the update should take place) wrapped into a IObservableValue object, the second one does the same for the model object and the last parameter can be used to pass validators and converters to the binding. By passing null you get the default ones.
Run the example and test it. Each time you change the UI element then model changes automatically. If you change the model then the UI will also update.
The coding also demonstrate that Eclipse Databinding converts per default already the from the typical values and that it performs in standard already nice validation.
JFace provides a flexible way of defining a view, the data and the representation of data separately. The following focuses in using JFace with Eclipse Databinding. For a larger example of JFace please see JFace Tables With Eclipse RCP
The following will demonstrate how list, table and tree viewers can be used with Eclipse Databinding.
Create a new plugin "de.vogella.databinding.model".
In the databinding for JFace viewers it is possible to distinct between changes in the collection and changes in the individual object. The following focus on the propagation of changes from the collection to the UI, e.g. if an element will be added to the collection or if an element will be removed from the collection this change should be visible in the UI.
JFace databinding provides several classes which allows to bind lists to viewers. ObservableListContentProvider is a content provider which requires a list which implements IObservableCollection. We use WritableList as input.
Create a new Eclipse RCP project "de.vogella.databinding.person.listviewer" use "Hello RCP" as a template (see Create your first Eclipse RCP application for details).
Add again the dependency to your model and the databinding plugins to your plugin project.
Add a view to your application. Create the following class for this view.
package de.vogella.databinding.person.listviewer;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.databinding.observable.list.WritableList;
import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ListViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.ViewPart;
import de.vogella.databinding.person.model.Person;
public class View extends ViewPart {
private ListViewer viewer;
private WritableList input;
@Override
public void createPartControl(Composite parent) {
// Just a little bit layout
parent.setLayout(new GridLayout(3, false));
// Define the viewer
viewer = new ListViewer(parent);
viewer.setContentProvider(new ObservableListContentProvider());
List<Person> persons = new ArrayList<Person>();
// Just for testing we create sample data
createExampleData(persons);
input = new WritableList(persons, Person.class);
// Set the writeableList as input for the viewer
viewer.setInput(input);
Button delete = new Button(parent, SWT.PUSH);
delete.setText("Delete");
delete.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (!viewer.getSelection().isEmpty()) {
IStructuredSelection selection = (IStructuredSelection) viewer
.getSelection();
Person p = (Person) selection.getFirstElement();
input.remove(p);
}
}
});
Button add = new Button(parent, SWT.PUSH);
add.setText("Add");
add.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
Person p = new Person();
p.setFirstName("Test");
p.setLastName("Test");
input.add(p);
}
});
}
protected void createExampleData(List<Person> persons) {
Person p = new Person();
p.setFirstName("Joe");
p.setLastName("Darcey");
persons.add(p);
p = new Person();
p.setFirstName("Jim");
p.setLastName("Knopf");
persons.add(p);
p = new Person();
p.setFirstName("Jim");
p.setLastName("Bean");
persons.add(p);
}
@Override
public void setFocus() {
}
}
In this example the UI will be updated if you remove or add an element to the collection. Run this example and test it.

The example before should how you can use databinding to synchronize changes between the UI and the model. If you only need to use to update the model from the UI you can use the class PojoObservables.
Create a new Eclipse RCP project "de.vogella.databinding.personpojo" use "Hello RCP" as a template (see Create your first Eclipse RCP application for details).
Create the following domain model.
package de.vogella.databinding.personpojo.model;
public class PersonPojo {
private String firstName;
private String lastName;
private boolean married;
private String gender;
private Integer age;
public PersonPojo() {
}
public String getFirstName() {
return firstName;
}
public String getGender() {
return gender;
}
public String getLastName() {
return lastName;
}
public boolean isMarried() {
return married;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setGender(String gender) {
this.gender = gender;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public void setMarried(boolean isMarried) {
this.married = isMarried;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
Add the plugins "org.eclipse.core.databinding", "org.eclipse.core.databinding.beans" and "org.eclipse.jface.databinding"as a dependency to your plugin.
Create a view with the ID "de.vogella.databinding.personpojo.myview" and implement the following code.
package de.vogella.databinding.personpojo;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.beans.PojoObservables;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.part.ViewPart;
import de.vogella.databinding.personpojo.model.PersonPojo;
public class MyView extends ViewPart {
public static final String ID = "de.vogella.databinding.personpojo.myview";
private PersonPojo person;
private Text firstName;
private Button married;
public MyView() {
person = new PersonPojo();
person.setFirstName("Joe");
person.setLastName("Jim");
}
@Override
public void createPartControl(Composite parent) {
Layout layout = new GridLayout(2, false);
parent.setLayout(layout);
Label label = new Label(parent, SWT.NONE);
label.setText("FirstName");
firstName = new Text(parent, SWT.BORDER);
Label marriedLabel = new Label(parent, SWT.NONE);
marriedLabel.setText("Maried");
married = new Button(parent, SWT.CHECK);
bindValues();
Button button1 = new Button(parent, SWT.PUSH);
button1.setText("Write model");
button1.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
System.out.println(person.getFirstName());
System.out.println(person.isMarried());
}
});
}
private void bindValues() {
DataBindingContext bindingContext = new DataBindingContext();
bindingContext.bindValue(SWTObservables.observeText(firstName,
SWT.Modify), PojoObservables.observeValue(person, "firstName"),
null, null);
bindingContext.bindValue(SWTObservables.observeSelection(married),
PojoObservables.observeValue(person, "married"), null, null);
}
@Override
public void setFocus() {
}
}
Add your view to the perspective.
Run the example and test it. Each time you change the UI element then model changes automatically.
This chapter will demonstrate the usage of validators and decorators for the controls.
The result will look like the following.

Create a new Eclipse RCP project "de.vogella.databinding.validation" use "Hello RCP" as a template.
In your new project re-create the pojo example. Re-create the dependencies to the required plugins.
Create the following class "StringLongerThenTwo" which implements org.eclipse.core.databinding.validation.IValidator.
package de.vogella.databinding.validation.validators;
import org.eclipse.core.databinding.validation.IValidator;
import org.eclipse.core.databinding.validation.ValidationStatus;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.fieldassist.ControlDecoration;
public class StringLongerThenTwo implements IValidator {
private final String message;
private final ControlDecoration controlDecoration;
public StringLongerThenTwo(String message,
ControlDecoration controlDecoration) {
super();
this.message = message;
this.controlDecoration = controlDecoration;
}
@Override
public IStatus validate(Object value) {
if (value instanceof String) {
String s = (String) value;
// We check if the string is longer then 2 signs
if (s.length() > 2) {
controlDecoration.hide();
return Status.OK_STATUS;
} else {
controlDecoration.show();
return ValidationStatus.error(message);
}
} else {
throw new RuntimeException(
"Not supposed to be called for non-strings.");
}
}
}
To use the validator you have to use your own UpdateValueStrategy. We are also adding a label to the UI which displays the status in case something is wrong in this field. We are also registering a change listener to the field "lastName" and changing the background color of the field if the input is not correct. So you see both how to use a decorator and how to change a field based on the values.
The following shows the coding for the view with the ID "de.vogella.databinding.validation.personview".
package de.vogella.databinding.validation;
import org.eclipse.core.databinding.AggregateValidationStatus;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.beans.PojoObservables;
import org.eclipse.core.databinding.observable.ChangeEvent;
import org.eclipse.core.databinding.observable.IChangeListener;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.fieldassist.ControlDecoration;
import org.eclipse.jface.fieldassist.FieldDecoration;
import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.part.ViewPart;
import de.vogella.databinding.validation.model.PersonPojo;
import de.vogella.databinding.validation.validators.StringLongerThenTwo;
public class PersonViewValidation extends ViewPart {
private static final String MESSAGE = "Name must be longer two letters";
public static final String ID = "de.vogella.databinding.validation.personview";
private PersonPojo person;
private Text firstName;
private Label errorLabel;
private IObservableValue uiElement;
private ControlDecoration firstNameDecorator;
private ControlDecoration lastNameDecorator;
private Text lastName;
public PersonViewValidation() {
}
@Override
public void createPartControl(Composite parent) {
person = new PersonPojo();
person.setFirstName("Lars");
person.setLastName("Vogel");
person.setGender("m");
person.setAge(12);
// Lets put thing to order
Layout layout = new GridLayout(2, false);
parent.setLayout(layout);
// Firstname
Label nameLabel = new Label(parent, SWT.None);
nameLabel.setText("Firstname: ");
firstName = new Text(parent, SWT.BORDER);
// Create the decorator which make the error message look really nice
firstNameDecorator = createDecorator(firstName, MESSAGE);
GridData gridData = new GridData();
gridData.horizontalAlignment = SWT.FILL;
gridData.grabExcessHorizontalSpace = true;
firstName.setLayoutData(gridData);
// Lastname
nameLabel = new Label(parent, SWT.None);
nameLabel.setText("Lastname: ");
lastName = new Text(parent, SWT.BORDER);
// Create the decorator which make the error message look really nice
lastNameDecorator = createDecorator(lastName, MESSAGE);
lastName.setLayoutData(gridData);
Button button1 = new Button(parent, SWT.PUSH);
button1.setText("Write model");
button1.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
System.out.println(person.getFirstName());
System.out.println(person.getLastName());
}
});
// Button should take 2 rows
gridData = new GridData();
gridData.horizontalSpan = 2;
button1.setLayoutData(gridData);
// This label will display all errors of all bindings
Label descAllLabel = new Label(parent, SWT.NONE);
descAllLabel.setText("All Validation Problems:");
errorLabel = new Label(parent, SWT.NONE);
gridData = new GridData();
gridData.horizontalAlignment = SWT.FILL;
gridData.grabExcessHorizontalSpace = true;
gridData.horizontalAlignment = GridData.FILL;
gridData.horizontalSpan = 1;
errorLabel.setLayoutData(gridData);
bindValues();
}
@Override
public void setFocus() {
}
private ControlDecoration createDecorator(Text text, String message) {
ControlDecoration controlDecoration = new ControlDecoration(text,
SWT.LEFT | SWT.TOP);
controlDecoration.setDescriptionText(message);
FieldDecoration fieldDecoration = FieldDecorationRegistry.getDefault()
.getFieldDecoration(FieldDecorationRegistry.DEC_ERROR);
controlDecoration.setImage(fieldDecoration.getImage());
return controlDecoration;
}
private void bindValues() {
// The DataBindingContext object will manage the databindings
DataBindingContext bindingContext = new DataBindingContext();
// First we bind the text field to the model
// Here we define the UpdateValueStrategy
UpdateValueStrategy update = new UpdateValueStrategy();
update.setAfterConvertValidator(new StringLongerThenTwo(MESSAGE,
firstNameDecorator));
// Bind fistName
bindingContext.bindValue(SWTObservables.observeText(firstName,
SWT.Modify), PojoObservables.observeValue(person, "firstName"),
update, null);
// Bind lastName
bindingContext.bindValue(SWTObservables.observeText(lastName,
SWT.Modify), PojoObservables.observeValue(person, "lastName"),
new UpdateValueStrategy()
.setAfterConvertValidator(new StringLongerThenTwo(
MESSAGE, lastNameDecorator)), null);
// We listen to all errors via this binding
uiElement = SWTObservables.observeText(errorLabel);
// This one listenes to all changes
bindingContext.bindValue(uiElement, new AggregateValidationStatus(
bindingContext.getBindings(),
AggregateValidationStatus.MAX_SEVERITY), null, null);
// Lets change the color of the field lastName
uiElement.addChangeListener(new IChangeListener() {
@Override
public void handleChange(ChangeEvent event) {
if (uiElement.getValue().equals("OK")) {
lastName.setBackground(Display.getCurrent().getSystemColor(
SWT.COLOR_WHITE));
} else {
lastName.setBackground(Display.getCurrent().getSystemColor(
SWT.COLOR_RED));
}
}
});
}
}
Eclipse EMF can be used together with Eclipse Databinding. The following assumes that you have already basic EMF knowledge. See here to learn about Eclipse EMF .
Create an EMF model "person.genmodel" with the following properties:
firstName - String
lastName - String
gender - String
isMarried - boolean
Create a new view "eclipsedatabinding.EMFExample" similar to UIExample and add this view to the perspective.
package eclipsedatabinding;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.emf.databinding.EMFObservables;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.part.ViewPart;
import domainmodelemf.DomainmodelemfFactory;
import domainmodelemf.DomainmodelemfPackage;
import domainmodelemf.IPerson;
public class EMFExample extends ViewPart {
public static final String ID = "eclipsedatabinding.EMFExample";
private IPerson lars;
public EMFExample() {
}
@Override
public void createPartControl(Composite parent) {
// Lets put thing to order
Layout layout = new GridLayout(2, false);
parent.setLayout(layout);
// Initialize the model
DomainmodelemfPackage.eINSTANCE.eClass();
// Retrieve the default factory singleton
DomainmodelemfFactory factory = DomainmodelemfFactory.eINSTANCE;
lars = factory.createIPerson();
lars.setFirstName("Lars");
lars.setLastName("Vogel");
lars.setGender("m");
// New text element
Text firstName = new Text(parent, SWT.NONE);
DataBindingContext bindingContext = new DataBindingContext();
firstName.setText("Hallo");
GridData gridData = new GridData();
gridData.horizontalAlignment = GridData.FILL;
gridData.horizontalSpan = 2;
firstName.setLayoutData(gridData);
bindingContext.bindValue(SWTObservables.observeText(firstName, SWT.Modify), EMFObservables.observeValue(lars,DomainmodelemfPackage.Literals.IPERSON__FIRST_NAME), null, null);
Button button1 = new Button(parent, SWT.PUSH);
button1.setText("Write model");
button1.addMouseListener(new MouseListener(){
@Override
public void mouseDoubleClick(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseDown(MouseEvent e) {
System.out.println(lars.getFirstName());
}
@Override
public void mouseUp(MouseEvent e) {
// TODO Auto-generated method stub
}
});
Button button2 = new Button(parent, SWT.PUSH);
button2.setText("Change model");
button2.addMouseListener(new MouseListener(){
@Override
public void mouseDoubleClick(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseDown(MouseEvent e) {
lars.setFirstName("Lars2");
}
@Override
public void mouseUp(MouseEvent e) {
// TODO Auto-generated method stub
}
});
}
@Override
public void setFocus() {
// TODO Auto-generated method stub
}
}
Thank you for practicing with this tutorial.
Please note that I maintain this website in my private time. If you like the information I'm providing please help me by donating.For questions and discussion around this article please use the www.vogella.de Google Group. Also if you note an error in this article please post the error and if possible the correction to the Group.
I believe the following is a very good guideline for asking questions in general and also for the Google group How To Ask Questions The Smart Way.
http://www.vogella.de/code/codeeclipse.html Source Code of Examples