# jdesktop binding: jTable update nach Änderung...



## markusk21 (31. Mrz 2010)

Hallo zusammen,
ich habe in Netbeans eine JTable an ein Liste gebunden:

```
java.util.List<data.admin.Disziplin> wettkampfListe = session.createQuery("from data.admin.Disziplin").list();
```

Netbeans hat folgenden Code zum Binding erstellt:

```
org.jdesktop.beansbinding.ELProperty eLProperty = org.jdesktop.beansbinding.ELProperty.create("${wettkampfListe}");
        org.jdesktop.swingbinding.JTableBinding jTableBinding = org.jdesktop.swingbinding.SwingBindings.createJTableBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, eLProperty, jTable1);
        org.jdesktop.swingbinding.JTableBinding.ColumnBinding columnBinding = jTableBinding.addColumnBinding(org.jdesktop.beansbinding.ELProperty.create("${disziplinId}"));
        columnBinding.setColumnName("Disziplin Id");
        columnBinding.setColumnClass(Integer.class);
        columnBinding = jTableBinding.addColumnBinding(org.jdesktop.beansbinding.ELProperty.create("${wettkampfBezeichnung}"));
        columnBinding.setColumnName("Wettkampf Bezeichnung");
        columnBinding.setColumnClass(String.class);
 /* 
Noch einige andere Spalten...
*
*/
        columnBinding = jTableBinding.addColumnBinding(org.jdesktop.beansbinding.ELProperty.create("${gewertet}"));
        columnBinding.setColumnName("Gewertet");
        columnBinding.setColumnClass(Boolean.class);
        bindingGroup.addBinding(jTableBinding);
        jTableBinding.bind();org.jdesktop.beansbinding.Binding binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${wettkampf}"), jTable1, org.jdesktop.beansbinding.BeanProperty.create("selectedElement"));
        bindingGroup.addBinding(binding);
```
Die Tabelle ist edierbar und ich füge auch neue Datensätze hinzu.
Das Problem entsteht, wenn ich nach der Änderung (und Speicherung in der Datenbank) einen Datensatz hinzufüge. Dann kommt nämlich:

```
Exception in thread "AWT-EventQueue-0" java.lang.UnsupportedOperationException: Can not call this method on a managed binding
```

Die komplette Meldung kommt unten.
Bei einer Änderung in der Tabelle reagiert :

```
private void tableChange(javax.swing.event.TableModelEvent e) {
	// Zeilen von der ersten bis zur letzten Änderungsreihe werden gespeichert.
	if (this.bound) { // Wenn zum Neueinlesen der Daten die bindung unterbrochen wird, werden keine Änderungen gespeichert.
	    for (int i = e.getFirstRow(); i <= e.getLastRow(); i++) {
		logger.debug("TableChange! Disziplin " + i + " wird auf Vollständigkeit geprüft.");
		if ((this.wettkampfListe.get(i).getWettkampfBezeichnung().length()>=1)){
		    this.updateDisziplin(wettkampfListe.get(i));
		}
	    }
	}
    }
```
und ruft 

```
private void updateDisziplin(data.admin.Disziplin disziplin){
	logger.debug("Geänderte Disziplin \"" + disziplin.getWettkampfBezeichnung() + "\" wird gespeichert.");
	org.hibernate.Transaction tx = session.beginTransaction();
	session.update(disziplin);
	tx.commit();
    }
```

Ich schätze mal, hier bleibt das JTableBinding im Zustand "managed".

Wenn ich danach einen Datensatz hinzufüge wird diese Methode aufgerufen:

```
private void saveDisziplin(data.admin.Disziplin disziplin){
	logger.debug("Neue Disziplin \"" + disziplin.getWettkampfBezeichnung() + "\" wird gespeichert.");
	org.hibernate.Transaction tx = session.beginTransaction();
	session.save(disziplin);
	tx.commit();
	initWettkampfListe();

	this.bound = false;
	// TODO disziplin hinzufügen verursacht beim Speichern Fehler! Wenn vorher ein Datensatz geändert wurde...
	logger.debug("Unbind...");
	bindingGroup.unbind();
	logger.debug("rebind...");
	bindingGroup.bind();
	logger.debug("Erfolgreich!");
	this.bound = true;

    }
```

Ich habe keine Bessere Lösung als den neuen Datensatz in der Datenbank zu speichern, die Liste neu zu laden (initWettkampfListe()) und danach die bindingGroup neu zu verbinden, damit die neuen Daten in der Tabelle angezeigt werden.

Vielleicht ist auch das der falsche Ansatz - hab es durch try-and-error raus bekommen...

Also, die Frage(n) lautet (lauten):
Wie füge ich einer gebundenen JTable einen Datensatz hinzu,
speziell, wenn vorher ein anderer Datensatz geändert wurde und ein Teil der Bindung im Zustand managed verbleibt.
Oder wie bekomme ich den Zustand der bindung auf den Status not managed?

Die Komplette Fehlermeldung:

```
DEBUG [AWT-EventQueue-0] (DisziplinenFrame.java:77) - Neue Disziplin "wdz" wird gespeichert.
DEBUG [AWT-EventQueue-0] (DisziplinenFrame.java:85) - Unbind...
Exception in thread "AWT-EventQueue-0" java.lang.UnsupportedOperationException: Can not call this method on a managed binding
DEBUG [AWT-EventQueue-0] (DisziplinenFrame.java:87) - rebind...
        at org.jdesktop.beansbinding.Binding.throwIfManaged(Binding.java:1337)
        at org.jdesktop.beansbinding.Binding.bind(Binding.java:943)
        at org.jdesktop.beansbinding.BindingGroup.bind(BindingGroup.java:143)
        at gui.admin.DisziplinenFrame.saveDisziplin(DisziplinenFrame.java:88)
        at gui.admin.DisziplinenFrame.access$200(DisziplinenFrame.java:19)
        at gui.admin.DisziplinenFrame$2.actionPerformed(DisziplinenFrame.java:60)
        at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
        at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
        at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
        at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
        at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
        at java.awt.Component.processMouseEvent(Component.java:6263)
        at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
        at java.awt.Component.processEvent(Component.java:6028)
        at java.awt.Container.processEvent(Container.java:2041)
        at java.awt.Component.dispatchEventImpl(Component.java:4630)
        at java.awt.Container.dispatchEventImpl(Container.java:2099)
        at java.awt.Component.dispatchEvent(Component.java:4460)
        at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4574)
        at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4238)
        at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
        at java.awt.Container.dispatchEventImpl(Container.java:2085)
        at java.awt.Window.dispatchEventImpl(Window.java:2475)
        at java.awt.Component.dispatchEvent(Component.java:4460)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
```

Das verursachende binding hab ich auch gefunden:

```
ERROR [AWT-EventQueue-0] (DisziplinenFrame.java:94) - org.jdesktop.swingbinding.JTableBinding$ColumnBinding [name=null, sourceObject=null, sourceProperty=org.jdesktop.beansbinding.ELProperty[ValueExpression[${intern}]], targetObject=null, targetProperty=org.jdesktop.swingbinding.JTableBinding$ColumnProperty@396ab2e8, validator=null, converter=null, sourceNullValue=null, targetNullValue=null, sourceUnreadableValueSet=false, sourceUnreadableValue=null, bound=false]: Bound (false), Managed: (true)
ERROR [AWT-EventQueue-0] (DisziplinenFrame.java:97) - Managed Binding:
ERROR [AWT-EventQueue-0] (DisziplinenFrame.java:98) - Source: null: org.jdesktop.beansbinding.ELProperty[ValueExpression[${intern}]]
ERROR [AWT-EventQueue-0] (DisziplinenFrame.java:99) - Target: null: org.jdesktop.swingbinding.JTableBinding$ColumnProperty@396ab2e8
ERROR [AWT-EventQueue-0] (DisziplinenFrame.java:100) -
```


----------



## markusk21 (2. Apr 2010)

Hat niemand eine Idee?
Gehe ich das ganze falsch an?
Ich brauche eine JTable, die die Daten einer Hibernate-Abfage darstellt und in der diese Daten geändert und sofort gespeichert werden.
Datensätze löschen und hinzufügen soll natürlich auch möglich sein.


----------



## markusk21 (8. Apr 2010)

Niemand?
Ich komm immer noch nicht weiter...

Ich gehe auch alternative Wege - Tabelle kommt mir halt am praktischsten vor:
Ich habe aus einer Hibernate-Abfrage eine java.util.List mit Datensätzen (oder auch nicht, bei Neustart). Die Datensätze sollen möglichst in der Anzeige gleich ediert werden, oder auch gelöscht und hinzugefügt werden.

Einen Umweg über eine Extra-Eingabemaske würde ich gern vermeiden.

Gruß
Markus


----------



## markusk21 (28. Apr 2010)

Also, ich hab es gelöst - indem ich das Binding rausgeschmissen hab und alles von Hand gebaut hab:

Ein eigenes Tablemodel für jede Tabelle - Änderungen werden gleich in die Datenbank gespeichert. 
Ist nur etwas blöd für jede Tabelle, wenn nur eine Spalte anders ist, ein eigenes Modell zu programmieren.
Vielleicht finde ich da auch noch ne Lösung...


----------

