Eclipse-Databinding 3.5 for GWT
Join the DZone community and get the full member experience.
Join For FreeI’m a big fan of GWT but one of the real pain points when developing GWT applications is that there’s no databinding framework available to synchronize your domain objects and UI-Widgets.
As many of you know I’m an even bigger fan of Eclipse-Databinding because it is written so that it can be used with ANY Model-Technology you want and even more important ANY UI-Technology you want and in fairly every environment you want (or at least porting to it is possible without too much trouble).
I’m happy to announce that the days without a databinding solution are gone forever now because yesterday in the night I made Eclipse-Databinding 3.5 compile under GWT and already wrote the first WidgetProperty implementations for Text and Label-Widgets.
Take a look at this video to see it in action
The code used to create this small presentation looks like this:
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.observable.value.ComputedValue;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.ufacekit.core.ubean.databinding.observables.UBeansObservables;
import org.eclipse.ufacekit.ui.gwt.databinding.GWTObservables;
import org.eclipse.ufacekit.ui.gwt.databinding.IWidgetValueProperty;
import org.eclipse.ufacekit.ui.gwt.databinding.WidgetProperties;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
/**
* Entry point classes define <code>onModuleLoad()</code>.
*/
public class GWTDatabindingExample implements
EntryPoint {
/**
* This is the entry point method.
*/
public void onModuleLoad() {
final Label titleLabel = new Label();
final TextBox firstNameField = new TextBox();
final TextBox lastNameField = new TextBox();
final Person p = new Person();
p.setFirstname("Tom");
p.setLastname("Schindl");
DataBindingContext dbc = new DataBindingContext(
GWTObservables.getRealm()
);
IWidgetValueProperty uiProp = WidgetProperties.text();
dbc.bindValue(
uiProp.observe(firstNameField),
UBeansObservables.observeValue(
GWTObservables.getRealm(), p, Person.FIRST_NAME
)
);
dbc.bindValue(
uiProp.observe(lastNameField),
UBeansObservables.observeValue(
GWTObservables.getRealm(), p, Person.LAST_NAME
)
);
ComputedValue titleValue =
new ComputedValue(GWTObservables.getRealm()) {
private IObservableValue last =
UBeansObservables.observeValue(
GWTObservables.getRealm(), p, Person.LAST_NAME
);
private IObservableValue first =
UBeansObservables.observeValue(
GWTObservables.getRealm(), p, Person.FIRST_NAME
);
@Override
protected Object calculate() {
return last.getValue().toString().toUpperCase()
+ ", " + first.getValue()
;
}
};
dbc.bindValue(uiProp.observe(titleLabel), titleValue);
RootPanel.get("titleContainer").add(titleLabel);
RootPanel.get("firstNameFieldContainer").add(
firstNameField
);
RootPanel.get("lastNameFieldContainer").add(
lastNameField
);
}
}
If you take a close look to the sources above the first thing you’ll spot is the usage of org.eclipse.ufacekit.core.ubean which is very light weight domain model implementation part of UFaceKit. The domain model has it’s own notification concept and a reflective API similar to EMF but is as light weight as possible.
A domain object implementation looks like this:
import org.eclipse.ufacekit.core.ubean.UBaseBean;
import org.eclipse.ufacekit.core.ubean.notify.Notification;
public class Person extends UBaseBean {
public static final int FIRST_NAME = 1;
public static final int LAST_NAME = 2;
private String lastname;
private String firstname;
public void add(int featureId, Object value) {
throw new IllegalArgumentException(
"No multi feature with id '"+featureId+"'"
);
}
@SuppressWarnings("unchecked")
public <V> V get(int featureId) {
if (featureId == FIRST_NAME) {
return (V) getFirstname();
} else if (featureId == LAST_NAME) {
return (V) getLastname();
}
throw new IllegalArgumentException(
"No feature with id '"+featureId+"'"
);
}
public void remove(int featureId, Object value) {
throw new IllegalArgumentException(
"No multi feature with id '"+featureId+"'"
);
}
public void set(int featureId, Object value) {
if( featureId == FIRST_NAME ) {
setFirstname((String) value);
} else if( featureId == LAST_NAME ) {
setLastname((String) value);
} else {
throw new IllegalArgumentException(
"No feature with id '"+featureId+"'"
);
}
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
notifyListeners(
new Notification(
this,
Notification.SET,
LAST_NAME,
this.lastname,
this.lastname = lastname
)
);
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
notifyListeners(
new Notification(
this,
Notification.SET, FIRST_NAME,
this.firstname,
this.firstname = firstname
)
);
}
}
The reflective API has the advantage that it doesn’t need reflection to call methods and thus is directly usable within GWT applications where no reflection is available. This is only the start of the many things UFaceKit is going to provide to you starting from full GWT-Databinding support over JFace-Viewer like implemenations to it’s highlevel UI-Abstraction.
For UFaceKit the support of GWT marks a new milestone because now we have a solution for another Java-Developer Community. We now support:
- SWT/JFace – including a Java5 JFace-Viewer implementation
- Qt – Qt-Databinding and Qt-JFace-Viewers
- Swing – Swing-Databinding and Swing-Viewers (though this needs some TLC)
- GWT – GWT-Databinding and start of GWT-Viewers (Combo, List and Tree)
- UBean – a very lightweight model technology compatible with GWT
The sources are available from the UFaceKit-repository (you need to have the Google-Eclipse-Plugin installed) and an Eclipse 3.5 as the target (if you don’t want to see compile errors in your IDE)
From http://tomsondev.bestsolution.at/
Opinions expressed by DZone contributors are their own.
Comments