JFace 数据绑定

1 介绍

1.1 Jface数据绑定

Jface数据绑定主要用于Eclipse的插件开发。例如,你可以绑定一个类的特定属性:’姓名‘ 至SWT的Text控件中。此时如果用户改变控件中的值,对象中的特定属性随之改变。

1.2 通过listener对改变进行响应

为了可以对java对象里属性的变化进行相应,Jface 数据绑定 需要将自己注册为特定属性的listener。 SWT和Jface支持这项操作。
Jface数据绑定同样可以用来检测领域模型( domain model)中特定属性的变化。

2 创建Jface 数据绑定

2.1 Java POJO 和Java Bean

Java中的数据模型通常以Java Plain Old Java Object (POJO) 模型 或者 Java Bean 模型定义(在MVC基础上)。

POJO是一种普通的Java对象。它包含业务逻辑或持久逻辑等,但不是JavaBean、EntityBean。其相对于javabean,没有那么严格的要求。

下面是一个POJO的例子:

package de.vogella.databinding.example;

public class Person  {
  private String name;

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }
} 

JavaBean的声明遵循一定的规则,包含getter/sitter(针对每一个属性),公有默认构造函数,可序列化等等。

下面是一个javabean的例子(包含 PropertyChangeSupport  ):
package de.vogella.databinding.example;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;

public class ModelObject {
  private PropertyChangeSupport changeSupport = 
      new PropertyChangeSupport(this);

  public void addPropertyChangeListener(PropertyChangeListener 
      listener) {
    changeSupport.addPropertyChangeListener(listener);
  }

  public void removePropertyChangeListener(PropertyChangeListener 
      listener) {
    changeSupport.removePropertyChangeListener(listener);
  }

  public void addPropertyChangeListener(String propertyName,
      PropertyChangeListener listener) {
    changeSupport.addPropertyChangeListener(propertyName, listener);
  }

  public void removePropertyChangeListener(String propertyName,
      PropertyChangeListener listener) {
    changeSupport.removePropertyChangeListener(propertyName, listener);
  }

  protected void firePropertyChange(String propertyName, 
      Object oldValue,
      Object newValue) {
    changeSupport.firePropertyChange(propertyName, oldValue, newValue);
  }
} 

其他类可以继承这个类:
package de.vogella.databinding.example;

public class Person extends ModelObject {
  private String name;

  public String getName() {
    return name;
  }

  public void setName(String name) {
    firePropertyChange("name", this.name, this.name = name);
  }
} 

2.2 POJO的数据绑定

POJO支持数据绑定,但是不支持变动通知(change notification)。所以POJO里的改变无法反映到用户界面上。但是用户界面上的改动可以反映到POJO中来。

2.3 Observable

绑定任意属性,需要用到java提供的observe方法。不同数据模型需要使用相应的工厂类:
Java提供了三种工厂类:
Factory Description
PojoProperties Used to create IObservableValues for Java objects.
BeanProperties Used to create IObservableValue objects for Java Beans.
WidgetProperties Used to create IObservableValues for properties of SWT widgets.

2.4 观察属性变化

数据模型
// if person is a POJO
IObservableValue myModel = PojoProperties.value("firstName").
  observe(person)
  

// alternatively if person is a bean use
// prefer using beans if you data model provides property change support  
IObservableValue myModel = BeansProperties.value("firstName").
  observe(person) 
SWT:

IObservableValue target = WidgetProperties.text(SWT.Modify).
  observe(firstNameText); 

成员变量的属性:比如我们需要绑定person类中adress属性下的country属性

IObservable model = PojoProperties.value(Person.class, 
    "address.country").observe(person); 


2.5 正文(context)数据绑定

DataBindingContext类允许对IObservableValues的对象进行连接/绑定。通过DataBindingContext类中bindValue方法,我们可以将两个IObservableValues的对象连接起来。第一个参数是目标对象,第二个参数是数据模型。在初始化阶段,数据模型会被复制到目标对象中去。
// create new Context
DataBindingContext ctx = new DataBindingContext();

// define the IObservables
IObservableValue target = WidgetProperties.text(SWT.Modify).
  observe(firstName);
IObservableValue model= BeanProperties.
  value(Person.class,"firstName").observe(person);

// connect them
ctx.bindValue(target, model); 

3 JFace plugins的数据绑定

在plugins的依赖中加入下列包即可:
  • org.eclipse.core.databinding

  • org.eclipse.core.databinding.beans

  • org.eclipse.core.databinding.property

  • org.eclipse.jface.databinding

4 补充

4.1 UpdateValueStrategy

bindValue方法的第三,四个选择性形参允许用户定义自己的UpdateValueStrategy。目的是允许用户定义同步的方法。

4.2 converter 和 validator

Validator允许用户在同步进行之前进行验证,而converter允许用户在目标与数据模型之间进行转换。
// define a validator to check that only numbers are entered
IValidator validator = new IValidator() {
  @Override
  public IStatus validate(Object value) {
    if (value instanceof Integer) {
      if (value.toString().matches(".*\\d.*")) {
        return ValidationStatus.ok();
      }
    }
    return ValidationStatus.error(value.toString() +"is not a number");
  }
};

// create UpdateValueStrategy and assign
// to the binding
UpdateValueStrategy strategy = new UpdateValueStrategy();
strategy.setBeforeSetValidator(validator);

Binding bindValue = 
  ctx.bindValue(widgetValue, modelValue, strategy, null); 

4.3 ControlDecorators

JFace数据绑定允许用户使用Decorator对数据输入进行实时响应。
比如:

// The following code assumes that a Validator is already defined
Binding bindValue = 
  ctx.bindValue(widgetValue, modelValue, strategy, null);

// add some decorations to the control
ControlDecorationSupport.create(bindValue, SWT.TOP | SWT.LEFT); 

5 JFace Viewer 数据绑定

5.1 Viewer绑定

Viewer的数据绑定需要对input进行区分,针对collection和单独对象,需要进行不同的处理。
比如,针对一个collection,我们需要用contentProvider对数据的改变发出通知。例如ObservableListContentProvider类,它继承了contentProvider并且实现了IObservableList接口。Properties类允许用户使用selfList方法对用户提供的list进行封装。
// use ObservableListContentProvider
viewer.setContentProvider(new ObservableListContentProvider());

// create sample data
List<Person> persons = createExampleData();

// wrap the input into a writable list
IObservableList input = 
   Properties.selfList(Person.class).observe(persons);

// set the IObservableList as input for the viewer
viewer.setInput(input); 

5.2 观察list的成员

如果需要观测list的成员,我们可以用ObservableMapLabelProvider类。
ObservableListContentProvider contentProvider = 
  new ObservableListContentProvider();
  
// create the label provider including monitoring 
// of the changes of the labels
IObservableSet knownElements = contentProvider.getKnownElements();

final IObservableMap firstNames = BeanProperties.value(Person.class,
  "firstName").observeDetail(knownElements);
final IObservableMap lastNames = BeanProperties.value(Person.class,
  "lastName").observeDetail(knownElements);
  
IObservableMap[] labelMaps = { firstNames, lastNames };

ILabelProvider labelProvider = 
  new ObservableMapLabelProvider(labelMaps) {
  public String getText(Object element) {
    return firstNames.get(element) + " " + lastNames.get(element);
    }
  }; 

5.3 viewerSupport

如果list中对象的所有属性均需要显示出来,我们可以使用viewerSupport。viewerSupport会自己负责创建contentProvider和labelProvier。这样使用起来更方便。
// the MyModel.getPersons() method call returns a List<Person> object
// the WritableList object wraps this object in an IObservableList

input = new WritableList(MyModel.getPersons(), Person.class);

// The following  creates and binds the data 
// for the Table based on the provided input
// no additional label provider / 
// content provider / setInput required

ViewerSupport.bind(viewer, input, 
    BeanProperties.
    values(new String[] { "firstName", "lastName", "married" })); 

5.4 Master/Detail 模式数据绑定

// assume we have Todo domain objects
// todos is a of type: List<Todo>
final ComboViewer viewer = new ComboViewer(parent, SWT.DROP_DOWN);
viewer.setContentProvider(ArrayContentProvider.getInstance());
viewer.setLabelProvider(new LabelProvider() {
  public String getText(Object element) {
    Todo todo = (Todo) element;
    return todo.getSummary();
  };
});
viewer.setInput(todos);

// create a Label to map to
Label label = new Label(parent, SWT.BORDER);
// parent has a GridLayout assigned
label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));


DataBindingContext dbc = new DataBindingContext();

// for binding to the label
IObservableValue target = WidgetProperties.text().observe(label);

// observe the selection
IViewerObservableValue selectedTodo = ViewerProperties
    .singleSelection().observe(viewer);
// observe the summary attribute of the selection
IObservableValue detailValue = 
  PojoProperties
    .value("summary", String.class)
    .observeDetail(selectedTodo)

dbc.bindValue(target, detailValue); 

5.5  Chaining properties

IObservableValue viewerSelectionSummaryObservable = 
  ViewerProperties.singleSelection()
    .value(BeanProperties.value("summary", String.class))
    .observe(viewer); 


IListProperty siblingNames = BeanProperties.
  value("parent").list("children").values("name");
IObservableList siblingNamesObservable = 
  siblingNames.observe(node); 



  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值