2

Here is a simple example of the problem I am running into.

I have a simple class:

public class Test{
    Integer a;
    Integer b;

    //getters and setters

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

}

Note that it has a property called C which is the sum of a and b.

I then bind this to a JTable like so:

List<Test> testList = new ArrayList<Test>();
...add some Test objects to the list
ObservableList observableList = ObservableCollections.observableList(testList);
JTable table = new JTable();
JTableBinding tableBinding = SwingBindings.createJTableBinding(AutoBinding.UpdateStrategy.READ_WRITE, observableList, table); 

I then use the following code to add the bindings for each property a, b, and c of the test object. (Note this is just the generic code I use)

BeanProperty beanProperty = BeanProperty.create(properyName);
JTableBinding.ColumnBinding columnBinding = tableBinding.addColumnBinding(beanProperty);
columnBinding.setColumnName(columnName);
columnBinding.setColumnClass(clazz);
columnBinding.setEditable(editable);

Now this will correctly display the table, but the problem happens when I update either a or b in the table. Since c is calculated off a and b, I expect c to update when one of these values changes. This does not happen.

I guess the table needs refreshed to reflect the new value of the entities?

Can anyone explain what I need to do to make this happen? Do I need to add some aditional beans binding property?

Here is the beans binding library I am using:

<dependency>
  <groupId>org.jdesktop</groupId>
  <artifactId>beansbinding</artifactId>
  <version>1.2.1</version>
</dependency>


org.jdesktop.swingbinding.SwingBindings
divibisan
  • 11,659
  • 11
  • 40
  • 58
user489041
  • 27,916
  • 55
  • 135
  • 204

4 Answers4

1

For reference, the underlying problem is discussed here, and manual solutions are adduced here for both DefaultTableModel and AbstractTableModel. In effect, a change to a or b must notify any TableModelListener that c may have changed. This may help guide your search for a suitable beans binding property.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • I appreciate the leads, but I am still racking my brain on this one. Does the solution have to do with overriding the getVale function, or does it have to do with refreshing the table somehow? Any help would be greatly appreciated. – user489041 Feb 09 '13 at 23:34
  • The essential thing is to fire a `TableModelEvent` that includes `c` when either `a` or `b` changes; `fireTableRowsUpdated()` in `setValueAt()` for the whole row is a simple expedient. – trashgod Feb 10 '13 at 00:06
  • It looks like the table model that JTableBinding uses does not extend AbstractTabelModel. Im not sure if firing this event will be able to happen – user489041 Feb 10 '13 at 00:24
1

With help from this question here, I was able to get the required functionality by overriding the setVale function on my JTable to:

@Override
public void setValueAt(Object value, int row, int col)
{
    super.setValueAt(value, row, col);
    tableBinding.unbind();
    tableBinding.bind();
    revalidate();
}

Thanks for the leads trashgod

Community
  • 1
  • 1
user489041
  • 27,916
  • 55
  • 135
  • 204
  • I see that "`JTableBinding` works by installing a custom model on the target `JTable`." I wonder if `refresh()` would do as as well as `bind()/unbind()`; `revalidate()` shouldn't be required. – trashgod Feb 10 '13 at 02:48
  • I tried removing the bind/unbind and replaced it with a call to refresh on the JTableBinding. This did not update the composite column (if thats the right term for it). I think were kind of on the same page that this probably is not the correct way to do this (the bind/unbind way). – user489041 Feb 10 '13 at 03:11
  • Yes, it seems a bit heavy-handed. Is there any way to override `setValueAt()` in `JTableBinding.BindingTableModel`? – trashgod Feb 10 '13 at 03:29
  • Negative, its a private inner class of JTableBinding. If it wasnt, that would have solved all my problems. – user489041 Feb 10 '13 at 16:22
  • That makes sense. The next thing I'd try is adding a `PropertyChangeListener` to the `JTableBinding` instance and looking for updates to `a` or `b`. – trashgod Feb 10 '13 at 16:29
0

Just write this two lines after update or insert

bindingGroup.unbind();
bindingGroup.bind();
seenukarthi
  • 8,241
  • 10
  • 47
  • 68
Hatem Badawi
  • 536
  • 4
  • 9
  • Please explain what the code does instead posting only code. – seenukarthi Apr 07 '15 at 05:37
  • this code was to unbind and bind the bindingGroup to refresh the jtable content but i add another comment about using jtablebinding instead of using the bindinggroup ; because the the bindingGroup.unbind(); bindingGroup.bind(); in some cases give error so when the list binded to the jtable changed you need to update or refresh the binding to that jtable by calling the unbind of the jtablebinding and then call the jtablebinding.bind() ; for the jtable to be updated with the new data – Hatem Badawi Apr 10 '15 at 02:05
0

i fix it a little this solve the problem ; you not allowed to unbind the main bindingGroup but you specify the jtablebinding to update it like this

Binding b = bindingGroup.getBindings().get(0);
b.unbind();
b.bind();
Hatem Badawi
  • 536
  • 4
  • 9