Составное значение в BindingBeans не обновляется
У меня есть простой 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());
}
}
1 ответ
Чтобы получить правильный бин, вам нужно запускать события
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, я бы обновил их установщики на
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.
Но, как отмечалось ранее, у меня нет опыта работы с этой обязательной структурой. Поэтому не уверен, решит ли это вашу проблему, и я не проверял ее (не планируя сначала загрузить / установить эту платформу).