了解Eclipse中的JFace数据绑定,第1部分: 数据绑定的优缺点
时间:2011-02-11 IBM Scott Delap
很多流行的 Web 应用程序都有视图层的特性,视图层足够智能可以将请求和应答变量与 HTML 输入标记同步。此过程可以轻松地完成,因为用户输入是通过 Web 应用程序的结构层和 HTTP 来路由的。而另一方面,Java GUI 应用程序经常都不能支持这种特性。无论是用 Standard Widget Toolkit (SWT) 编写还是用 Swing 编写,这些 Java GUI 应用程序的域对象与其 GUI 控件 (通常也称为 组件) 之间通常都没有定义好的路径。
样本(boilerplate)数据同步
打乱顺序最糟糕的结果是造成数据混乱,最幸运的结果是大块样本同步代码出现 bug。参考 清单 1 中的代码引用。这是一个称为 FormBean 的简单的域对象的定义。当一个对话框需要使用此数据时,对话框必须从域对象中提取此数据并将数据插入组件才能显示,如位于构建程序的末尾的方法调用中所示。相应地,在用户更改信息后,必须将此数据从 GUI 组件中提取出来并放回域模型中。这种往复过程是通过 syncBeanToComponents() 和 syncComponentsToBean() 方法来执行的。最后,请注意对 GUI 组件的引用在对象范围内必须保持可用,这样才能在同步方法中访问这些组件。
清单 1. 没有数据绑定的 Swing 对话框
package com.nfjs.examples;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.builder.DefaultFormBuilder;
import javax.swing.*;
import java.awt.event.ActionEvent;
public class NoBindingExample {
private JFrame frame;
private JTextField firstField;
private JTextField lastField;
private JTextArea descriptionArea;
private FormBean bean;
public NoBindingExample() {
frame = new JFrame();
firstField = new JTextField();
lastField = new JTextField();
descriptionArea = new JTextArea(6, 6);
DefaultFormBuilder builder =
new DefaultFormBuilder(new FormLayout("r:p, 2dlu, f:p:g"));
builder.setDefaultDialogBorder();
builder.append("First:", firstField);
builder.append("Last:", lastField);
builder.appendRelatedComponentsGapRow();
builder.appendRow("p");
builder.add(new JLabel("Description:"),
new CellConstraints(1,
5, CellConstraints.RIGHT,
CellConstraints.TOP),
new JScrollPane(descriptionArea),
new CellConstraints(3,
5, CellConstraints.FILL,
CellConstraints.FILL));
builder.nextRow(2);
builder.append(new JButton(new MessageAction()));
frame.add(builder.getPanel());
frame.setSize(300, 300);
bean = new FormBean();
syncBeanToComponents();
}
private void syncBeanToComponents() {
firstField.setText(bean.getFirst());
lastField.setText(bean.getLast());
descriptionArea.setText(bean.getDescription());
}
private void syncComponentsToBean() {
bean.setFirst(firstField.getText());
|