- 浏览: 229686 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
annyliyear:
找到的ExtJS实现多选下拉框3个代码 -
yinboxian:
源码太乱了
JXTA中使用JxtaServerPipe和JxtaBiDiPipe实现双向可靠的通信 -
yinboxian:
我的peers第一次执行时可以得到正确的结果,以后就不行了。不 ...
JXTA中基于管道监听方式通信 -
cuizhenfu#gmail.com:
http://www.cnblogs.com/cuizhf
JXTA中使用JxtaServerPipe和JxtaBiDiPipe实现双向可靠的通信 -
luxing44530:
请问, jsp页面如果在 META-INF 中, 改怎么访问? ...
Servlet3.0 新特性之模块化实践
18.4 数据绑定(JFace data binding framework)
在SWT编程中,界面组件对数据的读写是一项很繁重的工作,比如说“第16.2节 向导式对话框”就是较典型的示例。而SWT组件的数据绑定框架的推出将会大大简化这项工作,不过此框架在Eclipse3.2还是测试状态,它所在包是org.eclipse.jface.internal.databinding,包名带internal字样说明它还是仅限于内部使用。相信不久之后此框架将正式发布。
18.4.1 准备工作
先将数据绑定框架的支持包加入到myswt项目的库引用,它的路径是:C:\eclipse\plugins\org.eclipse.jface.databinding_1…0.jar。另外,如果你还想看它的源代码,其源代码包在:C:\eclipse\plugins\org.eclipse.rcp.source_3.2…\src\org.eclipse.jface.databinding_1…\src.zip。
图18.7 JFace data binding的库引用
接着创建两个数据类People和City,如下所示:
public class People {
private String name; // 姓名
private boolean sex; // 性别 true男,flase女
private int age; // 年龄
private List<String> interests;// 兴趣
private List<City> cities;// 此人所工作过的城市
// ------------以下为字段的Setter/Getter方法-------------------
public String getName() { return name; }
public void setName(String string) { name = string; }
public boolean isSex() { return sex; }
public void setSex(boolean sex) { this.sex = sex; }
public int getAge() { return age;}
public void setAge(int i) { age = i; }
public void setInterests(List<String> interests) {
this.interests = interests;
}
public List<String> getInterests() {
if (interests == null) return Collections.emptyList(); //空值是最容易出BUG的地方,
return interests; //尽量不要返回空值
}
public void setCities(List<City> cities) {
this.cities = cities;
}
public List<City> getCities() {
if (cities == null) return Collections.emptyList();
return cities;
}
}
public class City {
private String name;
private String desc;
public City() {}
public City(String name, String desc) {
this.name = name;
this.desc = desc;
}
public String getDesc() { return desc; }
public void setDesc(String desc) { this.desc = desc; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
@Override
public String toString() { return name + "," + desc; }
}
然后再创建一个静态工厂类,这个工厂类是通用的,它主要是用来组装一个普遍可用的DataBindingContext对象。DataBindingContext是数据绑定框架的容器,也是我们以后编程中最常用到的一个类,其代码如下所示。
创建DataBindingContext对象不需要参数,同时它也应该及时销毁。DataBindingContext对象为界面组件提供数据绑定服务,如果界面组件没有了,DataBindingContext对象也就没有必要存在了。所以在工厂类的第一个方法createContext(Control control),它传入一个Control对象,我们监听此界面组件的销毁事件,当它被销毁时也顺带把DataBindingContext对象一起销毁。
public class DataBindingContextFactory {
private DataBindingContextFactory() {}
public static DataBindingContext createContext(Control control) {
final DataBindingContext context = createContext();
control.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
context.dispose();
}
});
return context;
}
public static DataBindingContext createContext() {
DataBindingContext context = new DataBindingContext();
context.addObservableFactory(new NestedObservableFactory(context));
context.addObservableFactory(new BeanObservableFactory(context, null, new Class[] { Widget.class }));
context.addObservableFactory(new SWTObservableFactory());
context.addObservableFactory(new ViewersObservableFactory());
context.addBindSupportFactory(new DefaultBindSupportFactory());
context.addBindingFactory(new DefaultBindingFactory());
context.addBindingFactory(new ViewersBindingFactory());
return context;
}
}
18.4.2 数据绑定的简单示例
让我们来看一个最简单的数据绑定实例,其运行效果如图18.8所示。图中按钮用于打印出数据对象的值,这样能方便我们在学习时,随时查看数据对象的变化。图中文本框将用来做数据绑定。
图18.8 示例效果图
示例代码如下所示:
//--------------文件名:JFaceDataBinding1 ----------
final People bean = new People(); //数据
Button button = new Button(shell, SWT.NONE);
button.setText("打印数据");
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
System.out.println("---------------------------------");
System.out.println("name=" + bean.getName());
System.out.println("age=" + bean.getAge());
System.out.println("sex=" + bean.isSex());
System.out.println("interests=" + Arrays.toString(bean.getInterests().toArray()));
System. out.println("cities=" + Arrays.toString(bean.getCities().toArray()));
}
});
Text nameText = new Text(shell, SWT.BORDER);
DataBindingContext ctx = DataBindingContextFactory.createContext(shell);
ctx.bind(nameText, new Property(bean, "name"), null);
程序说明:ctx.bind(…)是最关键的是一句,它把数据对象People的属性name封装在一个Property对象中,然后和text绑定在一起。当我们在文本框中输入或修改字符,其变化值将直接更新到People对象的name属性里。
如果你想将sex属性和nameText文本框的其他属性绑定在一起,可以这样:
ctx.bind(new Property(nameText, "enabled"), new Property(bean, "sex"),null);
ctx.bind(new Property(nameText, "visible"), new Property(bean, "sex"),null);
18.4.3 使用BindSpec类定义特殊绑定
更复杂的绑定行为需要运行BindSpec类,该类将涉及到很多JFace数据绑定知识。
1.用BindSpec来作验证
在上面的示例中,ctx.bind(…)的第三个参数设成了空值,该参数为BindSpec类型,可以用它来定义数据的特殊绑定行为。下面的示例就是用BindSpec类来定义一个输入值验证,示例中把age属性绑定在nameText文本框上,并限制文本框只能输入数值,且不能为0。
//--------------文件名:JFaceDataBinding2.java-----------------------
BindSpec spec = new BindSpec(null, null, new MyValidator(), null);
ctx.bind(ageText, new Property(bean, "age"), spec);
其中MyValidator的代码如下。它实现了IValidator接口的两个方法,前一个方法isPartiallyValid比后一个方法isValid被调用的次数要多得多,所以一般用前者进行简单一点的验证,用后者进行较为耗资源的验证。比如说用户登录,isPartiallyValid可以去验证密码是不是数字与及长度是否足够,isValid就可以连接到数据库验证密码是否正确。在本示例,由于对数值验证很简单,不会占太多资源,所以完全可以把isValid里的验证合并到isPartiallyValid中。
private static class MyValidator implements IValidator {
//文本框每次输入字符都将执行此方法
public ValidationError isPartiallyValid(Object value) {
if (NumberUtils.isNumber((String) value))
return null;
else
return new ValidationError(ValidationError.ERROR, "无效的数字");
}
//文本框第一次设值时执行一次此方法,输入完成失去焦点时再执行一次
public ValidationError isValid(Object value) {
if ("0".equals(value))
return ValidationError.error("不允许等于0");
else
return null;
}
}
2.用BindSpec来作值转化
有时候数据模型应用到界面的值需要转化一下,界面的值更新到数据模型前也需要转化一下。如图所示,数据模型中的sex属性是布尔值,而界面显示则是男女字符串,这时sex属性在应用到下拉框之前就需要先转成字符串,而下拉框的字符串选择值更新到sex属性之前也需要转成相应的布尔值。
图18.9 下拉框绑定及值转换化
下面的代码实现了图18.9的效果:
//--------------文件名:JFaceDataBinding3.java-----------------------
// 界面组件
Combo combo = new Combo(shell, SWT.READ_ONLY);
combo.setItems(new String[] { "男", "女" });
// 数据绑定
DataBindingContext ctx = DataBindingContextFactory.createContext(shell);
BindSpec spec = new BindSpec(new BooleanToStringConverter(), new StringToBooleanConverter(), null, null);
ctx.bind(new Property(combo, SWTProperties.SELECTION), new Property(bean, "sex"), spec);
BindSpec构造函数的第一个IConverter参数是数据模型到界面前的转化,第二个IConverter参数是界面更新到数据模型前的转化。SWTProperties.SELECTION意思是指绑定到下拉框的选择。两个IConverter类的实现代码如下:
private static class BooleanToStringConverter implements IConverter {
public Object convert(Object fromObject) {
if ((Boolean) fromObject)
return "男";
else
return "女";
}
public Object getFromType() { return Boolean.TYPE; } //输入值的类型
public Object getToType() { return String.class; } //转化后值的类型
}
private static class StringToBooleanConverter implements IConverter {
public Object convert(Object fromObject) {
return "男".equals(fromObject);
}
public Object getFromType() { return String.class; }
public Object getToType() { return Boolean.TYPE; }
}
3.利用BindSpec的值转化来显示验证错误信息
在本小节的第一个示例对文本框输入做了验证,但是验证的错误信息没有显示出来,本实例将用BindSpec来实现显示错误信息的功能。实现方法是把验证返回的ValidationError类和一个Label绑定在一起,如下代码所示:
//--------------文件名:JFaceDataBinding4.java-----------------------
// 界面组件
Text ageText = new Text(shell, SWT.BORDER);
ageText.setLayoutData(new RowData(50, -1));
Label errorLable = new Label(shell, SWT.BORDER);
errorLable.setLayoutData(new RowData(100, -1));
// 数据绑定
DataBindingContext ctx = DataBindingContextFactory.createContext(shell);
BindSpec spec = new BindSpec(null, null, new MyValidator(), null);
Binding binding = ctx.bind(ageText, new Property(bean, "age"), spec); //取到Binding对象
//将ValidationError类的错误信息和Label做绑定
ValidationErrorToStringConverter converter1 = new ValidationErrorToStringConverter();
ReadOnlyConverter converter2 = new ReadOnlyConverter(String.class, ValidationError.class);
BindSpec spec2 = new BindSpec(converter1, converter2, null, null);
ctx.bind(errorLable, binding.getPartialValidationError(), spec2); // 绑定isPartiallyValid方法的错误
ctx.bind(errorLable, binding.getValidationError(), spec2); // 绑定isValid方法的错误
在以上代码中创建了两个IConverter类,第一个ValidationErrorToStringConverter是把ValidationError转化成一个字符串,其代码如下。这个类可以通用,所以写成一个单独的类。
public class ValidationErrorToStringConverter implements IConverter {
public Object convert(Object fromObject) {
return fromObject == null ? null : fromObject.toString();
}
public Object getFromType() { return ValidationError.class; }
public Object getToType() { return String.class; }
}
第二个ReadOnlyConverter类是定义界面到数据模型的转化,由于错误显示是单向的,不需要界面到数据模型的转化,所以此类的convert方法简单的返回空值。这个类也可以通用,所以写成一个单独的类。
public class ReadOnlyConverter implements IConverter {
private Object from, to;
public ReadOnlyConverter(Object from, Object to) {
this.from = from;
this.to = to;
}
public Object convert(Object fromObject) { return null; }
public Object getFromType() { return from; }
public Object getToType() { return to; }
}
18.4.4 TableViewer的数据绑定
本实例将演示如何对TableViewer做数据绑定,把某People的Cities属性显示在表格中。除了显示记录之外,实例还演示了如何用WritableValue对象来绑定表格的当前选择。本实例完整的代码见JFaceDataBinding5.java。
图18.10 TableViewer的数据绑定
首先要做一下数据准备,在JFaceDataBinding5.java里创建几个City对象,如下所示:
final People bean = new People();// 数据
ArrayList<City> cities = new ArrayList<City>(3);
cities.add(new City("桂林", "山水甲天下"));
cities.add(new City("深圳", "曾经的开放特区"));
cities.add(new City("南宁", "广西的省会城市"));
cities.add(new City("北京", "中国首都"));
bean.setCities(cities);
TablePresentationModel tableModel = new TablePresentationModel(bean.getCities());
TablePresentationModel是针对TableViewer自创的一个数据类,存放了WritableValue对象,和表格显示的City数据集。其中WritableValue对象用来保存表格的当前选择。
public class TablePresentationModel {
private List<City> input;
private WritableValue selected;
public TablePresentationModel(List<City> input) {
this.input = input;
this.selected = new WritableValue(City.class);
this.selected.setValue(input.get(1));// 默认选择第二条记录
}
public List<City> getInput() { return input; }
public void setInput(List<City> input) { this.input = input; }
public WritableValue getSelected() { return selected; }
public void setSelected(WritableValue selected) { this.selected = selected; }
}
接着在JFaceDataBinding5.java里创建表格和一个标签,标签用来显示表格的当前选择。同时把TablePresentationModel 对象tableModel绑定到表格和标签上。
TableViewer tv = new TableViewer(shell, SWT.BORDER | SWT.FULL_SELECTION);
Table table = tv.getTable();
table.setLayoutData(new RowData(150, 70));
table.setHeaderVisible(true); // 显示表头
table.setLinesVisible(true); // 显示表格线
TableLayout layout = new TableLayout();
table.setLayout(layout);
layout.addColumnData(new ColumnWeightData(13));
new TableColumn(table, SWT.NONE).setText("名称");
layout.addColumnData(new ColumnWeightData(40));
new TableColumn(table, SWT.NONE).setText("注释");
Label label = new Label(shell, SWT.BORDER);
// 数据绑定
DataBindingContext ctx = DataBindingContextFactory.createContext(shell);
TableModelDescription dec = new TableModelDescription(new Property(tableModel, "input", City.class, true), new String[] { "name", "desc" });
ctx.bind(new Property(tv, ViewersProperties.CONTENT), dec, null);
ctx.bind(new Property(tv, ViewersProperties.SINGLE_SELECTION), tableModel.getSelected(), null);
ctx.bind(label, new Property(tableModel.getSelected(), "name", String.class, false), null);
程序说明:
● Property(tableModel, "input", City.class, true)封装了tableModel的input属性,第四个参数true指出input属性是一个集合,第三个参数指出此集合的元素是City类型。{ "name", "desc" }指要取出City的name、desc属性显示在表格中。然后所有这些信息都封装在TableModelDescription对象中。
● ViewersProperties.CONTENT表示数据和表格的内容绑定。
● ViewersProperties.SINGLE_SELECTION表示数据和表格的当前所选记录绑定
● 在最后一个bind方法将表格当前选择记录的name属性显示在标签上。
● 用数据绑定框架,不需要设置TableViewer的内容器和标签器了。
18.4.5 Combo绑定和联动
如图18.11所示,本示例将把People数据对象里的interests值填充到一个下拉框,右边的标签将显示下拉框的选择值。
图18.11 Combo绑定和联动
//--------------文件名:JFaceDataBinding6.java-----------------------
final People bean = new People();// 数据
ArrayList<String> interests = new ArrayList<String>(3);
interests.add("阅读");
interests.add("旅行");
interests.add("运动");
bean.setInterests(interests);
………
// 界面组件
Combo combo = new Combo(shell, SWT.BORDER);
Label label = new Label(shell, SWT.BORDER);
label.setLayoutData(new RowData(100, -1));
// 数据绑定
DataBindingContext ctx = DataBindingContextFactory.createContext(shell);
ctx.bind(new Property(combo, SWTProperties.ITEMS), new Property(bean, "interests", String.class, true), null);
WritableValue selectedItem = new WritableValue(String.class);
selectedItem.setValue("旅行"); //设置初选值
ctx.bind(new Property(combo, SWTProperties.SELECTION), selectedItem, null);
ctx.bind(label, selectedItem, null);
程序说明:
● SWTProperties.ITEMS意思是指将interests属性设定为Combo的Items。
● 这里联动的实现还是依靠WritableValue对象,你可以把它看作是JFace绑定框架的一个中转站。先是和下拉框的当前选择记录(SWTProperties.SELECTION)绑定在一起,然后再和label标签绑定在一起。当然也可以直接绑定ctx.bind(label, new Property(combo, SWTProperties.SELECTION), null);不过这样就没法设置下拉框的初选值了。
不过Combo在实际中的应用场景更多是如图18.12那样的,在下拉框预设一些年龄的初始值,然后所选择值将更新到数据对象的age属性中。
图18.12 年龄的绑定
实现代码如下:
//--------------文件名:JFaceDataBinding7.java-----------------------
// 界面组件
Combo combo = new Combo(shell, SWT.BORDER);
// 绑定初始数据
DataBindingContext ctx = DataBindingContextFactory.createContext(shell);
WritableList ageList = new WritableList(String.class);
ageList.add("0");
ageList.add("10");
ageList.add("20");
ageList.add("30");
ctx.bind(new Property(combo, SWTProperties.ITEMS), ageList, null);
ageList.add("100"); // 以后还可以再加进新项,将实现反映到界面上
combo.remove("100");// 如果从界面删除某项,ageList也会跟着删除该项。
// 初选绑定
ctx.bind(new Property(combo, SWTProperties.SELECTION), new Property(bean, "age"), null);
程序说明:WritableList和以前用过的WritableValue都属于IObservable接口,这个接口下具有一个庞大的继承体系,针对不同的组件和应用情况都有相应的实现类。
相关推荐
RCP jface 数据绑定 例子 测试 范例 RCP jface 数据绑定 例子 测试 范例 RCP jface 数据绑定 例子 测试 范例
基于_JFace_Text_Framework_构建全功能代码编辑器
JFace数据绑定(中文版),适合于开发信息管理系统,界面程序,涉及到数据绑定的人群
IBM官方网站的JFace Text Framework教程,教大家如何实现代码提示,字体着色,语法分析等方法。是一个非常好的教程。
It explain how to connect your data model with the UI so that both will be automatically synchronized. It will demonstrate the usage of validators and field decorators. EMF databinding is also ...
JFace教程 网盘
jface programing
SWT自带的DateTime控件属实不好用,而且无法绑定到其他控件上。因此自己写一个日历控件用着方便,功能大致如下: 1、日历控件可自定义设置常见的几种日期格式; 2、可以绑定注册到其他控件如:文本框、按钮、标签上...
swt/Jface用到的最基本的jar包
Eclipse SWT_JFace开发实战精解
快速学习swt jface eclipse 开发
《Eclipse SWT/Jface核心应用》全面介绍了SWT、JFace和RCP的相关知识。全书共分5篇,第1篇介绍了SWT产生的背景以及SWT的一些基本概念和基础知识。第2篇介绍了SWT基本控件的使用,以及事件处理、布局等SWT基本知识的...
SWT JFACE 编程笔记 , 比较适合刚 解除 java swt jface 的开发人员
SWT/JFace开发实例
SWT Jface知识点,Eclipse SWT/JFace核心应用
swt jface jar swt jface jar swt jface jar