Java BindingBean中的复合值未更新

Java BindingBean中的复合值未更新,java,swing,jtable,beans-binding,Java,Swing,Jtable,Beans Binding,我有一个简单的POJO,如下所示: class A{ private int a; private int b; public int getC(){ return a + b; } //getters and setters for a and b } 此实体使用BindingBeans绑定到JTable。对a和b所做的任何更改都会正确处理并显示在JTable中,但c不会更新 我想如果a或b更新了,我需要启动一个属性更改事件或其他什

我有一个简单的POJO,如下所示:

class A{
    private int a;
    private int b;

    public int getC(){
        return a + b;
    }

    //getters and setters for a and b
}
此实体使用BindingBeans绑定到JTable。对a和b所做的任何更改都会正确处理并显示在JTable中,但c不会更新

我想如果a或b更新了,我需要启动一个属性更改事件或其他什么,但我真的没有想法。有什么想法吗

编辑:

我创建了一个简单的示例:

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.Serializable;


public class POJO implements Serializable{

    private static final Gson gson = new GsonBuilder().create();

    private Integer a;
    private Integer b;

    public Integer getC() {
        return a + b;
    }

    public Integer getA() {
        return a;
    }

    public void setA(Integer a) {
        this.a = a;
    }

    public Integer getB() {
        return b;
    }

    public void setB(Integer b) {
        this.b = b;
    }

    @Override
    public String toString(){
        return gson.toJson(this);
    }
}
主课呢

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTable;
import org.jdesktop.beansbinding.AutoBinding;
import org.jdesktop.beansbinding.BeanProperty;
import org.jdesktop.swingbinding.JTableBinding;
import org.jdesktop.swingbinding.SwingBindings;


public class Example implements ActionListener{

    private JTable table;
    private JFrame frame;
    private JTableBinding tableBinding;
    private List<POJO> elements;

    public static void main(String [] args){
        new Example();
    }

    public Example(){
        initData();
        initGui();
        initBindings();
        frame.pack();
    }

    private void initData(){
        elements = new ArrayList<POJO>();
        POJO pojoA = new POJO();
        pojoA.setA(1);
        pojoA.setB(2);
        POJO pojoB = new POJO();
        pojoB.setA(3);
        pojoB.setB(4);
        elements.add(pojoA);
        elements.add(pojoB);
    }

    private void initGui(){
         frame = new JFrame();
         table = new JTable();
         frame.getContentPane().setLayout(new BorderLayout());
         JPanel tablePanel = new JPanel();
         tablePanel.setLayout(new GridLayout());
         tablePanel.add(table);
         frame.getContentPane().add(BorderLayout.CENTER,tablePanel);
         JButton button = new JButton("Show Current Elements");
         button.addActionListener(this);
         frame.getContentPane().add(BorderLayout.SOUTH,button);
         frame.setLocationRelativeTo(null);
         frame.setVisible(true);
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    private void initBindings(){
        tableBinding = SwingBindings.createJTableBinding(
                AutoBinding.UpdateStrategy.READ_WRITE, elements,
                table);
        addBinding("a", "A", Integer.class, true);
        addBinding("b", "B", Integer.class, true);
        addBinding("c", "C", Integer.class, false);
        tableBinding.bind();
    }

    private void addBinding(String properyName, String columnName, Class clazz, boolean editable) {
        BeanProperty beanProperty = BeanProperty.create(properyName);
        JTableBinding.ColumnBinding columnBinding = tableBinding.addColumnBinding(beanProperty);
        columnBinding.setColumnName(columnName);
        columnBinding.setColumnClass(clazz);
        columnBinding.setEditable(editable);
    }

    public void actionPerformed(ActionEvent ae) {
        StringBuilder builder = new StringBuilder();
        for(POJO pojo : elements){
            builder.append(pojo.toString() + "\n");
        }
        JOptionPane.showMessageDialog(null, "The elements are:\n\n" + builder.toString());
    }
}
导入java.awt.BorderLayout;
导入java.awt.GridLayout;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.util.ArrayList;
导入java.util.List;
导入javax.swing.JButton;
导入javax.swing.JFrame;
导入javax.swing.JOptionPane;
导入javax.swing.JPanel;
导入javax.swing.JTable;
导入org.jdesktop.beansbinding.AutoBinding;
导入org.jdesktop.beansbinding.BeanProperty;
导入org.jdesktop.swingbinding.JTableBinding;
导入org.jdesktop.swingbinding.SwingBindings;
公共类示例实现ActionListener{
专用JTable表;
私有JFrame;
私有JTableBinding表绑定;
私有列表元素;
公共静态void main(字符串[]args){
新例子();
}
公共示例(){
initData();
initGui();
initBindings();
frame.pack();
}
私有void initData(){
元素=新的ArrayList();
POJO pojoA=新POJO();
布乔刚毛(1);
pojoA.setB(2);
POJO pojoB=新POJO();
setA(3);
pojoB.setB(4);
元素。添加(pojoA);
元素。添加(pojoB);
}
私有void initGui(){
frame=新的JFrame();
table=新的JTable();
frame.getContentPane().setLayout(新的BorderLayout());
JPanel tablePanel=新的JPanel();
setLayout(新的GridLayout());
tablePanel.add(表);
frame.getContentPane().add(BorderLayout.CENTER,tablePanel);
JButton按钮=新JButton(“显示当前元素”);
addActionListener(这个);
frame.getContentPane().add(BorderLayout.SOUTH,按钮);
frame.setLocationRelativeTo(空);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
私有void initBindings(){
tableBinding=SwingBindings.createJTableBinding(
AutoBinding.UpdateStrategy.READ_WRITE,元素,
表);
addBinding(“a”,“a”,Integer.class,true);
addBinding(“b”,“b”,Integer.class,true);
addBinding(“c”,“c”,Integer.class,false);
tableBinding.bind();
}
私有void addBinding(字符串properyName、字符串columnName、类clazz、布尔可编辑){
BeanProperty BeanProperty=BeanProperty.create(PropertyName);
JTableBinding.ColumnBinding ColumnBinding=tableBinding.addColumnBinding(beanProperty);
columnBinding.setColumnName(columnName);
columnBinding.setColumnClass(clazz);
columnBinding.setEditable(可编辑);
}
已执行的公共无效行动(行动事件ae){
StringBuilder=新的StringBuilder();
用于(POJO POJO:元素){
append(pojo.toString()+“\n”);
}
JOptionPane.showMessageDialog(null,“元素为:\n\n”+builder.toString());
}
}

为了获得正确的bean,您需要触发事件

private final PropertyChangeSupport = new PropertyChangeSupport( this );

public void setA(Integer a) {
  Integer old = this.a;
  this.a = a;
  propertyChangeSupport.firePropertyChange( "A", old, this.a );
}
C是一个派生属性。如果你只有一个接受者而没有接受者,不确定它是否会起作用。但在C发生变化的情况下,您很可能需要触发一个事件。因为当A或B改变时它会改变,所以我会将它们的setter更新为

public void setA(Integer a) {
  Integer oldA = this.a;
  Integer oldC = getC();
  this.a = a;
  propertyChangeSupport.firePropertyChange( "A", oldA, this.a );
  propertyChangeSupport.firePropertyChange( "C", oldC, getC() );
}
当然,这同样适用于B属性


但正如前面所评论的,我没有使用该绑定框架的经验。因此,我不确定这是否能解决您的问题,而且我还没有对它进行测试(不打算先下载/安装该框架)。

您不应该有一个添加a和b的setC方法,而不是在getC中进行测试吗?我在你的类中没有看到任何名为c的属性,也没有相同的setter。同意,但在我的应用程序上下文中,设置c没有意义。C是a和b的简单组合。当a或b更新时,我希望C的更改反映在表中。它们当前不是。可能使用CellEditorListener?如果更改
a
b
,将如何通知绑定。你不应该让这些私有化,为它创建getter和setter,并触发属性更改(例如,使用PropertyChangeSupport)@Robin请查看我的编辑,了解我如何创建绑定