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); } }