WindowBuilder 上的双向数据绑定似乎不起作用
Bidirectional databinding on WindowBuilder seems not to work
我正在 Java7 SE 上使用 Eclipse Juno、WindowBuilder、"Swing Automatic Databinding" (beansbinding-1.2.1.jar
) 开发我的第一个 JDialog。
我很想测试自动数据绑定
我仅在 Eclipse 数据绑定 GUI 的帮助下获得了 class 用户的编辑对话框。
package it.marcuzzi.databindtest;
public class User {
private String name;
private int age;
public User() {}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
}
我的对话框打开,其文本字段包含来自用户实例的正确初始值。当我修改文本字段文本然后单击“确定”按钮时,我看不到 User 实例有任何变化。
这是我的对话代码.....
package it.marcuzzi.databindtest;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import org.jdesktop.beansbinding.AutoBinding;
import org.jdesktop.beansbinding.BeanProperty;
import org.jdesktop.beansbinding.BindingGroup;
import org.jdesktop.beansbinding.Bindings;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class UserJDialog extends JDialog {
private static final long serialVersionUID = 7043021546503322090L;
private BindingGroup m_bindingGroup;
private JPanel m_contentPane;
private it.marcuzzi.databindtest.User user = new it.marcuzzi.databindtest.User();
private JTextField nameJTextField;
private JTextField ageJTextField;
private JButton btnOk;
public static void main(String[] args) {
try {
UserJDialog dialog = new UserJDialog();
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
public UserJDialog() {
user.setName("marco");
user.setAge(10);
setBounds(100, 100, 450, 300);
m_contentPane = new JPanel();
setContentPane(m_contentPane);
//
GridBagLayout gridBagLayout = new GridBagLayout();
gridBagLayout.columnWidths = new int[] { 0, 0, 0 };
gridBagLayout.rowHeights = new int[] { 0, 0, 0, 0, 0, 0 };
gridBagLayout.columnWeights = new double[] { 0.0, 1.0, 1.0E-4 };
gridBagLayout.rowWeights = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 1.0E-4 };
m_contentPane.setLayout(gridBagLayout);
JLabel nameLabel = new JLabel("Name:");
GridBagConstraints labelGbc_0 = new GridBagConstraints();
labelGbc_0.insets = new Insets(5, 5, 5, 5);
labelGbc_0.gridx = 0;
labelGbc_0.gridy = 0;
m_contentPane.add(nameLabel, labelGbc_0);
nameJTextField = new JTextField();
GridBagConstraints componentGbc_0 = new GridBagConstraints();
componentGbc_0.insets = new Insets(5, 0, 5, 0);
componentGbc_0.fill = GridBagConstraints.HORIZONTAL;
componentGbc_0.gridx = 1;
componentGbc_0.gridy = 0;
m_contentPane.add(nameJTextField, componentGbc_0);
JLabel ageLabel = new JLabel("Age:");
GridBagConstraints labelGbc_1 = new GridBagConstraints();
labelGbc_1.insets = new Insets(5, 5, 5, 5);
labelGbc_1.gridx = 0;
labelGbc_1.gridy = 1;
m_contentPane.add(ageLabel, labelGbc_1);
ageJTextField = new JTextField();
GridBagConstraints componentGbc_1 = new GridBagConstraints();
componentGbc_1.insets = new Insets(5, 0, 5, 0);
componentGbc_1.fill = GridBagConstraints.HORIZONTAL;
componentGbc_1.gridx = 1;
componentGbc_1.gridy = 1;
m_contentPane.add(ageJTextField, componentGbc_1);
btnOk = new JButton("Ok");
btnOk.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println( "Name: "+user.getName()+"\tAge: "+user.getAge());
UserJDialog.this.setVisible(false);
}
});
GridBagConstraints gbc_btnOk = new GridBagConstraints();
gbc_btnOk.gridx = 1;
gbc_btnOk.gridy = 4;
m_contentPane.add(btnOk, gbc_btnOk);
if (user != null) {
m_bindingGroup = initDataBindings();
}
}
protected BindingGroup initDataBindings() {
BeanProperty<it.marcuzzi.databindtest.User, java.lang.String> nameProperty = BeanProperty.create("name");
BeanProperty<javax.swing.JTextField, java.lang.String> textProperty = BeanProperty.create("text");
AutoBinding<it.marcuzzi.databindtest.User, java.lang.String, javax.swing.JTextField, java.lang.String> autoBinding = Bindings
.createAutoBinding(AutoBinding.UpdateStrategy.READ_WRITE, user, nameProperty, nameJTextField, textProperty);
autoBinding.bind();
//
BeanProperty<it.marcuzzi.databindtest.User, java.lang.Integer> ageProperty = BeanProperty.create("age");
BeanProperty<javax.swing.JTextField, java.lang.String> textProperty_1 = BeanProperty.create("text");
AutoBinding<it.marcuzzi.databindtest.User, java.lang.Integer, javax.swing.JTextField, java.lang.String> autoBinding_1 = Bindings
.createAutoBinding(AutoBinding.UpdateStrategy.READ_WRITE, user, ageProperty, ageJTextField, textProperty_1);
autoBinding_1.bind();
//
BindingGroup bindingGroup = new BindingGroup();
bindingGroup.addBinding(autoBinding);
bindingGroup.addBinding(autoBinding_1);
//
return bindingGroup;
}
public it.marcuzzi.databindtest.User getUser() {
return user;
}
public void setUser(it.marcuzzi.databindtest.User newUser) {
setUser(newUser, true);
}
public void setUser(it.marcuzzi.databindtest.User newUser, boolean update) {
user = newUser;
if (update) {
if (m_bindingGroup != null) {
m_bindingGroup.unbind();
m_bindingGroup = null;
}
if (user != null) {
m_bindingGroup = initDataBindings();
}
}
}
}
绑定更新策略都是READ_WRITE所以我不明白为什么它不更新用户实例!
任何想法 ?
谢谢,
马可
实际上,它正在更新 User 实例,但您的小部件不会收到有关它的通知。您必须在设置器中触发 PropertyChangeEvent。这是一个例子:
import java.beans.*;
public class Foo {
private int bar;
private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
public int getBar() { return bar; }
public void setBar(int bar) {
int oldValue = this.bar;
this.bar = bar;
pcs.firePropertyChange("bar", oldValue, bar);
}
public void addPropertyChangeListener(PropertyChangeListener pcl) {
pcs.addPropertyChangeListener(pcl);
}
public void removePropertyChangeListener(PropertyChangeListener pcl) {
pcs.removePropertyChangeListener(pcl);
}
}
我正在 Java7 SE 上使用 Eclipse Juno、WindowBuilder、"Swing Automatic Databinding" (beansbinding-1.2.1.jar
) 开发我的第一个 JDialog。
我很想测试自动数据绑定
我仅在 Eclipse 数据绑定 GUI 的帮助下获得了 class 用户的编辑对话框。
package it.marcuzzi.databindtest;
public class User {
private String name;
private int age;
public User() {}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
}
我的对话框打开,其文本字段包含来自用户实例的正确初始值。当我修改文本字段文本然后单击“确定”按钮时,我看不到 User 实例有任何变化。 这是我的对话代码.....
package it.marcuzzi.databindtest;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import org.jdesktop.beansbinding.AutoBinding;
import org.jdesktop.beansbinding.BeanProperty;
import org.jdesktop.beansbinding.BindingGroup;
import org.jdesktop.beansbinding.Bindings;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class UserJDialog extends JDialog {
private static final long serialVersionUID = 7043021546503322090L;
private BindingGroup m_bindingGroup;
private JPanel m_contentPane;
private it.marcuzzi.databindtest.User user = new it.marcuzzi.databindtest.User();
private JTextField nameJTextField;
private JTextField ageJTextField;
private JButton btnOk;
public static void main(String[] args) {
try {
UserJDialog dialog = new UserJDialog();
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
public UserJDialog() {
user.setName("marco");
user.setAge(10);
setBounds(100, 100, 450, 300);
m_contentPane = new JPanel();
setContentPane(m_contentPane);
//
GridBagLayout gridBagLayout = new GridBagLayout();
gridBagLayout.columnWidths = new int[] { 0, 0, 0 };
gridBagLayout.rowHeights = new int[] { 0, 0, 0, 0, 0, 0 };
gridBagLayout.columnWeights = new double[] { 0.0, 1.0, 1.0E-4 };
gridBagLayout.rowWeights = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 1.0E-4 };
m_contentPane.setLayout(gridBagLayout);
JLabel nameLabel = new JLabel("Name:");
GridBagConstraints labelGbc_0 = new GridBagConstraints();
labelGbc_0.insets = new Insets(5, 5, 5, 5);
labelGbc_0.gridx = 0;
labelGbc_0.gridy = 0;
m_contentPane.add(nameLabel, labelGbc_0);
nameJTextField = new JTextField();
GridBagConstraints componentGbc_0 = new GridBagConstraints();
componentGbc_0.insets = new Insets(5, 0, 5, 0);
componentGbc_0.fill = GridBagConstraints.HORIZONTAL;
componentGbc_0.gridx = 1;
componentGbc_0.gridy = 0;
m_contentPane.add(nameJTextField, componentGbc_0);
JLabel ageLabel = new JLabel("Age:");
GridBagConstraints labelGbc_1 = new GridBagConstraints();
labelGbc_1.insets = new Insets(5, 5, 5, 5);
labelGbc_1.gridx = 0;
labelGbc_1.gridy = 1;
m_contentPane.add(ageLabel, labelGbc_1);
ageJTextField = new JTextField();
GridBagConstraints componentGbc_1 = new GridBagConstraints();
componentGbc_1.insets = new Insets(5, 0, 5, 0);
componentGbc_1.fill = GridBagConstraints.HORIZONTAL;
componentGbc_1.gridx = 1;
componentGbc_1.gridy = 1;
m_contentPane.add(ageJTextField, componentGbc_1);
btnOk = new JButton("Ok");
btnOk.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println( "Name: "+user.getName()+"\tAge: "+user.getAge());
UserJDialog.this.setVisible(false);
}
});
GridBagConstraints gbc_btnOk = new GridBagConstraints();
gbc_btnOk.gridx = 1;
gbc_btnOk.gridy = 4;
m_contentPane.add(btnOk, gbc_btnOk);
if (user != null) {
m_bindingGroup = initDataBindings();
}
}
protected BindingGroup initDataBindings() {
BeanProperty<it.marcuzzi.databindtest.User, java.lang.String> nameProperty = BeanProperty.create("name");
BeanProperty<javax.swing.JTextField, java.lang.String> textProperty = BeanProperty.create("text");
AutoBinding<it.marcuzzi.databindtest.User, java.lang.String, javax.swing.JTextField, java.lang.String> autoBinding = Bindings
.createAutoBinding(AutoBinding.UpdateStrategy.READ_WRITE, user, nameProperty, nameJTextField, textProperty);
autoBinding.bind();
//
BeanProperty<it.marcuzzi.databindtest.User, java.lang.Integer> ageProperty = BeanProperty.create("age");
BeanProperty<javax.swing.JTextField, java.lang.String> textProperty_1 = BeanProperty.create("text");
AutoBinding<it.marcuzzi.databindtest.User, java.lang.Integer, javax.swing.JTextField, java.lang.String> autoBinding_1 = Bindings
.createAutoBinding(AutoBinding.UpdateStrategy.READ_WRITE, user, ageProperty, ageJTextField, textProperty_1);
autoBinding_1.bind();
//
BindingGroup bindingGroup = new BindingGroup();
bindingGroup.addBinding(autoBinding);
bindingGroup.addBinding(autoBinding_1);
//
return bindingGroup;
}
public it.marcuzzi.databindtest.User getUser() {
return user;
}
public void setUser(it.marcuzzi.databindtest.User newUser) {
setUser(newUser, true);
}
public void setUser(it.marcuzzi.databindtest.User newUser, boolean update) {
user = newUser;
if (update) {
if (m_bindingGroup != null) {
m_bindingGroup.unbind();
m_bindingGroup = null;
}
if (user != null) {
m_bindingGroup = initDataBindings();
}
}
}
}
绑定更新策略都是READ_WRITE所以我不明白为什么它不更新用户实例! 任何想法 ?
谢谢, 马可
实际上,它正在更新 User 实例,但您的小部件不会收到有关它的通知。您必须在设置器中触发 PropertyChangeEvent。这是一个例子:
import java.beans.*;
public class Foo {
private int bar;
private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
public int getBar() { return bar; }
public void setBar(int bar) {
int oldValue = this.bar;
this.bar = bar;
pcs.firePropertyChange("bar", oldValue, bar);
}
public void addPropertyChangeListener(PropertyChangeListener pcl) {
pcs.addPropertyChangeListener(pcl);
}
public void removePropertyChangeListener(PropertyChangeListener pcl) {
pcs.removePropertyChangeListener(pcl);
}
}