Статьи

Eclipse-Databinding 3.5 для GWT

Я большой поклонник GWT, но одна из реальных проблем при разработке приложений GWT заключается в том, что нет доступной инфраструктуры привязки данных для синхронизации ваших доменных объектов и UI-виджетов.

Как многие из вас знают, я еще больше поклонник Eclipse-Databinding, потому что он написан так, чтобы его можно было использовать с ЛЮБОЙ модельной технологией, которую вы хотите, и даже с более важной ЛЮБОЙ технологией пользовательского интерфейса, которую вы хотите, и практически в любой среде, которую вы хотите. (или, по крайней мере, портирование на него возможно без особых проблем).

Я рад сообщить, что дни без решения для привязки данных прошли навсегда, потому что вчера ночью я сделал компиляцию Eclipse-Databinding 3.5 под GWT и уже написал первые реализации WidgetProperty для Text и Label-Widgets.

Посмотрите это видео, чтобы увидеть его в действии

 

Код, использованный для создания этой небольшой презентации, выглядит следующим образом:

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

Если вы внимательно посмотрите на источники выше, первое, что вы заметите, — это использование org.eclipse.ufacekit.core.ubean, который является очень легкой частью реализации UFaceKit для модели предметной области . Модель предметной области имеет свою собственную концепцию уведомлений и отражающий API, похожий на EMF, но настолько легкий, насколько это возможно.

Реализация объекта домена выглядит так:

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

Рефлексивное API имеет то преимущество, что ему не нужно отражение для вызова методов, и, следовательно, его можно напрямую использовать в приложениях GWT, где нет доступных отражений. Это только начало многих вещей, которые UFaceKit собирается предоставить вам, начиная с полной поддержки привязки GWT-данных по JFace-Viewer, как реализации, к его высокоуровневой абстракции пользовательского интерфейса.

Для UFaceKit поддержка GWT знаменует новую веху, потому что теперь у нас есть решение для другого сообщества Java-разработчиков. Теперь мы поддерживаем:

  • SWT / JFace — включая реализацию Java5 JFace-Viewer
  • Qt — Qt-Databinding и Qt-JFace-Viewers
  • Swing — Swing-Databinding и Swing-Viewers (хотя для этого нужен некоторый TLC)
  • GWT — GWT-привязка данных и запуск GWT-просмотрщиков (Combo, List и Tree)
  • UBean — очень легкая модель, совместимая с GWT

Источники доступны из UFaceKit-репозитория (вам нужно установить Google-Eclipse-Plugin ) и Eclipse 3.5 в качестве цели (если вы не хотите видеть ошибки компиляции в вашей IDE)

От http://tomsondev.bestsolution.at/