T.M. SoftStudio

feci quod potui, faciant meliora potentes

Купить полную версию книги "Среда разработки Eclipse 4: Руководство разработчика"

Графические системы SWT и JFace

Связывание данных

Платформа Eclipse предоставляет программный интерфейс связывания данных, представленный библиотеками org.eclipse.core.databinding.* и org.eclipse.jface.databinding.*, которые обеспечивают связывание свойств Widget-компонентов и объектов данных.

Связывание данных (Data Binding) представляет собой синхронизацию двух источников данных таким образом, что изменение данных одного объекта автоматически отражается в другом объекте. Сам механизм связывания основан на Observer-шаблоне программирования, в котором связываемый объект имеет список своих зависимостей, или объектов-наблюдателей, и уведомляет их автоматически об изменениях своего состояния, вызывая соответствующие методы объектов-наблюдателей.

WindowBuilder-плагин обеспечивает связывание данных с помощью мастера JFace Automating Databinding раздела WindowBuilder | SWT Designer | Databinding команды New, команды Bindings контекстного меню визуальной области редактирования и окна Structure, а также с помощью вкладки Bindings WindowBuilder-редактора, которая имеет функциональность, аналогичную функциональности команды Bindings контекстного меню.

Для создания связывания данных с помощью мастера JFace Automating Databinding в окне Package Explorer перспективы Java среды Eclipse щелкнем правой кнопкой мышки на узле проекта, созданного с помощью мастера SWT/JFace Java Project, и в контекстном меню выберем команду New | Other | Java | Class и нажмем кнопку Next, введем имя пакета main и имя класса Data и нажмем кнопку Finish.

В окне редактора исходного кода дополним код класса Data:

package main;

import java.io.Serializable;

public class Data implements Serializable{

private String data;

public String getData() {

return data;

}

public void setData(String data) {

this.data = data;

}}

Теперь класс Data является JavaBeans-компонентом, представляющим данные приложения.

В окне Package Explorer щелкнем правой кнопкой мышки на узле класса Data и в контекстном меню выберем команду New | Other | WindowBuilder | SWT Designer | Databinding | JFace Automating Databinding и нажмем кнопку Next, в окне мастера выберем переключатель org.eclipse.swt.widgets.Shell (рис. 5.4) и нажмем кнопку Next.

Рис. 5.4. Окно мастера JFace Automating Databinding

В поле Properties: выберем свойство data класса Data и нажмем кнопку Finish.

В результате будет создано окно Shell, включающее в себя текстовое поле, содержимое которого синхронизировано со свойством data класса Data (рис. 5.5).

Рис. 5.5. SWT-приложение, имеющее связывание свойства Text-компонента со свойством JavaBeans-компонента

Связывание данных данного SWT-приложения устанавливается с помощью создания объекта org.eclipse.core.databinding.DataBindingContext, который отвечает за хранение информации обо всех связываниях данных приложения.

Связывание данных вносится в DataBindingContext-объект с помощью методов класса DataBindingContext:

  • Метод bindList() – синхронизирует два списка java.util.List<E>.

  • Метод bindSet() – синхронизирует два набора java.util.Set<E>.

  • Метод bindValue() – синхронизирует два объекта.

В данном SWT-приложении применяется метод bindValue() для синхронизации свойства Text-компонента со свойством JavaBeans-компонента. При этом свойство Text-компонента и свойство JavaBeans-компонента обертываются в объекты org.eclipse.core.databinding.observable.value.IObservableValue, обеспечивающие отслеживание изменений значений свойств.

Обертывание свойства Text-компонента в IObservableValue-объект производится с помощью статического метода observeText(Widget widget) класса-фабрики org.eclipse.jface.databinding.swt.SWTObservables, а обертывание свойства JavaBeans-компонента – с помощью статического метода observeValue(Object pojo, String propertyName) класса-фабрики org.eclipse.core.databinding.beans.PojoObservables.

В методе main() данного SWT-приложения Shell-окно создается в специальном UI-потоке, для которого определен контекст доступа к IObservable-объектам, обеспечивающий уведомление IObservable-объектами своих слушателей. Такой контекст представлен объектом org.eclipse.core.databinding.observable.Realm.

Для демонстрации связывания данных во вкладке Design WindowBuilder-редактора перенесем в Shell-окно элемент Button раздела Controls Palette-палитры и два раза щелкнем по нему мышкой – в результате будет сгенерирован код создания Button-компонента и присоединения к нему слушателя событий выбора компонента. Дополним код обработчика событий компонента:

Button btnNewButton = new Button(this, SWT.NONE);

btnNewButton.addSelectionListener(new SelectionAdapter() {

@Override

public void widgetSelected(SelectionEvent e) {

data.setData("Hello");

setData(data);

}});

В выделенных строках кода изменяется значение свойства data объекта Data и вызывается метод, обновляющий DataBindingContext-контекст.

После запуска приложения выбором команды Run As | Java Application контекстного меню окна Package Explorer при нажатии кнопки окна приложения в текстовом поле появится значение свойства JavaBeans-компонента "Hello".

Для того чтобы в обработчике событий кнопки не обновлять DataBindingContext-контекст вызовом метода setData(), изменим код класса Data согласно листинга 5.1 и код метода initDataBindings() согласно листинга 5.2.

Листинг 5.1. Код класса Data с поддержкой связывания

package main;

import java.io.Serializable;

import java.beans.*;

public class Data implements Serializable{

private String data;

private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);

public void addPropertyChangeListener(String propertyName,

PropertyChangeListener listener) { propertyChangeSupport.addPropertyChangeListener(propertyName, listener);}

public void removePropertyChangeListener(PropertyChangeListener listener) {

propertyChangeSupport.removePropertyChangeListener(listener);

}

public String getData() {

return data;

}

public void setData(String data) {

propertyChangeSupport.firePropertyChange("data", this.data, this.data = data);

}}

Листинг 5.2. Код метода initDataBindings() создания DataBindingContext-контекста

private DataBindingContext initDataBindings() {

IObservableValue dataObserveWidget = SWTObservables.observeText(

dataText, SWT.Modify);

IObservableValue dataObserveValue = BeansObservables.observeValue(data, "data");

DataBindingContext bindingContext = new DataBindingContext();

bindingContext.bindValue(dataObserveWidget, dataObserveValue, null,

null);

return bindingContext;}

Для создания связывания данных с помощью вкладки Bindings WindowBuilder-редактора во вкладке Design WindowBuilder-редактора перенесем в Shell-окно элемент Label раздела Controls Palette-палитры и перейдем на вкладку Bindings.

Во вкладке Bindings в поле Target выберем Label-компонент, в поле Properties – его свойство text. В поле Model кнопкой Widgets переключимся на компоненты и выберем Text-компонент, а в нижнем поле Properties – его свойство text и нажмем кнопку создания связывания (рис. 5.6).

Рис. 5.6. Создание связывания с помощью вкладки Bindings WindowBuilder-редактора

В окне мастера Create Data Binding нажмем кнопку OK.

В результате метод initDataBindings() дополнится кодом:

IObservableValue lblNewLabelObserveTextObserveWidget = SWTObservables.observeText(lblNewLabel);

IObservableValue dataTextObserveTextObserveWidget = SWTObservables.observeText(dataText, SWT.Modify);

bindingContext.bindValue(lblNewLabelObserveTextObserveWidget, dataTextObserveTextObserveWidget, null, null);

Убедимся что вызов метода initDataBindings() производится после создания Label-компонента, и во вкладке Design WindowBuilder-редактора в области визуального редактирования нажмем на Label-компоненте правой кнопкой мышки и в контекстном меню выберем команду Horizontal alignment | Fill, гарантируя отображение текста метки.

Теперь после запуска приложения изменение текста в текстовом поле приведет к автоматическому изменению текста метки.


JFace-приложения