Recently I have started using JFace Binding. Unfortunately there are not many resources available on the web with non-trivial examples.
Let present example of master-detail view: a drop-down list and two text fields which display some details regarding option chosen from the list.
POJO Category. It contains two fields: name and description which will be displayed as details of the object chosen from the drop-down list:
import java.beans.PropertyChangeListener;
import java.io.Serializable;
/**
* Domain object representing category
*
*/
public class Category implements Serializable {
private static final long serialVersionUID = -5542167952605551865L;
private String name;
private String description;
/**
* Default constructor
*/
public Category() {
// Do nothing
}
/**
* Constructor
*
* @param name
* name of a category
* @param description
* description of a category
*/
public Category(String name, String description) {
this.name = name;
this.description = description;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the description
*/
public String getDescription() {
return description;
}
/**
* @param description the description to set
*/
public void setDescription(String description) {
this.description = description;
}
}
Class of model that will be used to bind the data to the view:
import java.util.List;
/**
* Model for displaying categories
*
*/
public class CategoriesModel extends AbstractModelObject {
private List categories;
private IDataManager dataManager;
private Category category;
/**
* The constructor
*/
public CategoriesModel() {
this.dataManager = Activator.getDataManager();
this.categories = this.dataManager.getAllCategories();
}
/**
* @return the category
*/
public Category getCategory() {
return this.category;
}
/**
* @param category
* the category to set
*/
public void setCategory(Category category) {
this.category = category;
}
/**
* @return the categories
*/
public List getCategories() {
return categories;
}
/**
* @param categories the categories to set
*/
public void setCategories(List categories) {
this.categories = categories;
}
}
Class of view (in this case it is Eclipse View containing managed form):
import java.util.logging.Logger;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.beans.BeansObservables;
import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.databinding.observable.list.WritableList;
import org.eclipse.core.databinding.observable.map.IObservableMap;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;
import org.eclipse.jface.databinding.viewers.ObservableMapLabelProvider;
import org.eclipse.jface.databinding.viewers.ViewersObservables;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.forms.ManagedForm;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.part.ViewPart;
/**
* Allows to view list of categories and their details
*
*/
public class CategoryView extends ViewPart {
private Logger logger = Logger.getLogger(CategoryView.class.getName());
private static final String FORM_TITLE = Messages
.getString("category.view.form.title");
private FormToolkit formToolkit;
private CategoriesModel model;
private Text nameText;
private Text descriptionText;
private ComboViewer categoriesComboViewer;
private DataBindingContext dbc;
/**
* {@inheritDoc}
*/
@Override
public void createPartControl(Composite parent) {
model = new CategoriesModel();
ManagedForm mForm = new ManagedForm(parent);
ScrolledForm scrolledForm = mForm.getForm();
FormToolkit formToolkit = mForm.getToolkit();
Composite formBody = scrolledForm.getBody();
formToolkit.decorateFormHeading(scrolledForm.getForm());
scrolledForm.setText(FORM_TITLE);
formBody.setLayout(new GridLayout(2, true));
categoriesComboViewer = new ComboViewer(formBody, SWT.DROP_DOWN
| SWT.READ_ONLY);
GridData comboGridData = new GridData();
comboGridData.horizontalSpan = 2;
comboGridData.horizontalAlignment = GridData.FILL;
categoriesComboViewer.getCombo().setLayoutData(comboGridData);
nameText = formToolkit.createText(formBody, "", SWT.NONE);
GridData nameGridData = new GridData();
nameGridData.horizontalSpan = 2;
nameGridData.horizontalAlignment = GridData.FILL;
nameText.setLayoutData(nameGridData);
descriptionText = formToolkit.createText(formBody, "", SWT.MULTI);
GridData textGridData = new GridData();
textGridData.horizontalSpan = 2;
textGridData.horizontalAlignment = GridData.FILL;
textGridData.heightHint = 100;
descriptionText.setLayoutData(textGridData);
formToolkit.paintBordersFor(formBody);
bindData();
}
/**
* {@inheritDoc}
*/
@Override
public void setFocus() {
// Do nothing
}
/**
* This method binds the value from UI layer to the model object
*/
protected void bindData() {
dbc = new DataBindingContext();
// Seting content provider for combo viewer
ObservableListContentProvider categoryViewerContentProvider = new ObservableListContentProvider();
categoriesComboViewer.setContentProvider(categoryViewerContentProvider);
IObservableMap[] attributeMaps = BeansObservables.observeMaps(
categoryViewerContentProvider.getKnownElements(),
Category.class, new String[] { "name" });
categoriesComboViewer.setLabelProvider(new ObservableMapLabelProvider(
attributeMaps));
categoriesComboViewer.setInput(new WritableList(model.getCategories(),
Category.class));
// Observing changes in selection in combo viewer
IObservableValue selection = ViewersObservables
.observeSingleSelection(categoriesComboViewer);
// Observing the properties of the current selection
IObservableValue detailNameObservable = BeansObservables
.observeDetailValue(Realm.getDefault(), selection, "name",
String.class);
IObservableValue detailDescriptionObservable = BeansObservables
.observeDetailValue(Realm.getDefault(), selection,
"description", String.class);
// Binding the Text widgets to the name and description details
// (selection's properties).
dbc.bindValue(SWTObservables.observeText(nameText, SWT.None),
detailNameObservable, new UpdateValueStrategy(false,
UpdateValueStrategy.POLICY_NEVER), null);
dbc.bindValue(SWTObservables.observeText(descriptionText, SWT.None),
detailDescriptionObservable, new UpdateValueStrategy(false,
UpdateValueStrategy.POLICY_NEVER), null);
}
/**
* {@inheritDoc}
*/
public void dispose() {
if (formToolkit != null) {
formToolkit.dispose();
}
super.dispose();
}
}
AbstractModelObject which provides methods required by JFace Binding (it’s not checked on compilation level):
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
/**
* Provides minimal JavaBeans support for model objects
*
*/
public abstract class AbstractModelObject {
private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(
this);
/**
* @param listener
*/
public void addPropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(listener);
}
/**
* @param propertyName
* @param listener
*/
public void addPropertyChangeListener(String propertyName,
PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(propertyName, listener);
}
/**
* @param listener
*/
public void removePropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.removePropertyChangeListener(listener);
}
/**
* @param propertyName
* @param listener
*/
public void removePropertyChangeListener(String propertyName,
PropertyChangeListener listener) {
propertyChangeSupport.removePropertyChangeListener(propertyName,
listener);
}
/**
*
* @param propertyName
* @param oldValue
* @param newValue
*/
protected void firePropertyChange(String propertyName, Object oldValue,
Object newValue) {
propertyChangeSupport.firePropertyChange(propertyName, oldValue,
newValue);
}
}