(Re-)Binding SWT forms with WindowBuilder
A very common case in UI applications are forms which are bound to exchangeable model objects. For example, one might want to bind this address form in such a way that you can set a new
Addressobject at any time with the UI reflecting that change:
The plain old binding can be created easily using WindowBuilder:
The resulting code might look like this:
public class AddressViewPart extends ViewPart { private DataBindingContext bindingContext; private Address address; private Text textName; @Override public void createPartControl(Composite parent) { parent.setLayout(new GridLayout(3, false)); Label lblName = new Label(parent, SWT.NONE); lblName.setText(Messages.YetAnotherViewPart_lblName_text); textName = new Text(parent, SWT.BORDER); textName.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1)); // ... bindingContext = initDataBindings(); } protected DataBindingContext initDataBindings() { DataBindingContext bindingContext = new DataBindingContext(); // IObservableValue textNameValue = WidgetProperties.text(SWT.Modify).observe(textName); IObservableValue addressNameValue = PojoProperties.value("name").observe(address); bindingContext.bindValue(textNameValue, addressNameValue, null, null); // return bindingContext; } }The tricky part is to bind this in such a way that the model object can be exchanged at any time. There are three possible ways:
1) Dispose bindings
The easiest way is to dispose all bindings and just re-bind whenever a new model object appears:
public class AddressViewPart extends ViewPart { // ... protected void setAddress(Address address) { this.address = address; if (bindingContext != null) bindingContext.dispose(); bindingContext = initDataBindings(); } // ... }Unfortunately, WindowBuilder insists on putting the
initDataBindingscall increatePartControl. Also, if you are usingControlDecorationSupportyou will stumble upon Bug 341713 – DataBinding ControlDecorationSupport not disposed when DataBindingContext is disposed.2) Binding to a WritableValue
Another way is to use a detail binding to a
WritableValuewhich can be changed at any time:public class AddressViewPart extends ViewPart { private WritableValue addressValue = new WritableValue(); protected void setAddress(Address address) { this.addressValue.setValue(address); } protected DataBindingContext initDataBindings() { // ... IObservableValue addressNameValue = PojoProperties.value("name").observeDetail(addressValue); // ... } }Such a Binding can be created in WindowBuilder:
3) Bean binding
Yet another way is to make the ViewPart itself a
BeanwithPropertyChangeSupport:public class AddressViewPart extends ViewPart { private PropertyChangeSupport changes = new PropertyChangeSupport(this); private Address address; public Address getAddress() { return address; } public void setAddress(Address address) { changes.firePropertyChange("address", this.address, this.address = address); } public void addPropertyChangeListener(PropertyChangeListener l) { changes.addPropertyChangeListener(l); } public void removePropertyChangeListener(PropertyChangeListener l) { changes.removePropertyChangeListener(l); } protected DataBindingContext initDataBindings() { //... IObservableValue addressNameValue = BeanProperties.value("address.name").observe(this); //... } }While I like this way conceptionally, in practice it has the problems of Java’s PropertyChangeSupport being cumbersome. Also, JFace Data Binding doesn’t allow to mix Beans and Pojos, so if the Address object in the example is a Pojo, one will get
NoSuchMethodException: Address.addPropertyChangeListener(java.beans.PropertyChangeListener). And there seems to be no way to generate such a binding in WindowBuilder.
-
quote of the day- Jessica Savitch"No matter how many goals you have achieved, you must set your sights on a higher one."
- Jessica Savitch
-
my recent tweets
- RT @Milanello: Photo: This picture is featured in today's Gazzetta dello Sport. You Indonesians going to love this - http://bit.ly/oqAPki 6 months ago
- @simamaung: Rada lami loading-na kang tapi sae pisan euy. Keren lah simamaung mah :) 7 months ago
- Violent Games Credited With Reducing Crime Levels: http://t.co/PgnMUyH ... Is this true? 8 months ago
- RT @SidMohede: "A truly rich man is one whose children run into his arms even when his hands are empty." I'm truly rich indeed! :) 8 months ago
- Ha! RT @SidMohede: I know money can't buy happiness, but it can buy yummy peanut butter, which is pretty much the same thing for me :) 10 months ago
-
calendar
-
categories
- development (6)
- system administration (4)
- Uncategorized (5)
-
archive
-
tags
-
Blogroll
-
Meta



