Swing JTable Model View Problem

Hi,

ich bin ein Anfänger auf dem Swing gebiet und will folgenden Anwendungsfall realisieren:

Eine Gui stellt einen JTable mit initial 'n' Datensätzen bereit. Die Einträge sind ungefähr so aufgebaut

name, value, attr1, attr2, comment

.name - kann vom user geändert werden.
.value - hängt direkt vom name ab. Ändert sich permanent. Wird von einem Thread aus aktualisiert.
.attr1 - Attribut aus einer vordefinierten Liste
.attr2 - Attribut aus einer vordefinierten Liste, die von attr1 abhängt. D.h. die Liste ändert sich, wenn attr1 sich ändert.
.comment - kann vom user festgelegt werden.

Die Daten werden aus einer DB gelesen und sollen bei Klick auf einen Button in die Datenbank zurückgeschrieben werden. Selbstverständlich soll der User in der Lage sein, Einträge aus der JTable zu editieren, zu löschen, einzufügen.

Nun zu meinen Fragen:
Der Gedanke war, eine Komponente zu schreiben, die einen JTable bereitstellt. Das TableModel würde einfach eine Liste der Dateneinträge beinhalten.
-Was passiert jetzt, wenn der User einen Eintrag modifiziert, d.h. z.B. value ändert? Die Änderung soll ja nicht sofort in die DB geschrieben werden. Wir der Wert trotzdem sofort ins Model geschrieben, d.h. der Eintrag in der Liste, der zur row passt wird entsprechend modifiziert?
-Wenn der User Einträge löscht, dann kann ich die ja nicht direkt aus dem Model löschen, da ich nachher sonst nicht mehr wüsste, das ich ihn löschen muss.
-Was passiert, wenn einfach ein neuer Eintrag zwischen zwei Bestehenden eingefügt werden soll? Verschiebe ich die Einträge in meinem Model?

Das sollte fürs erste reichen. Später hätte ich noch Fragen zu Renderern, Editoren und so 😀

Vielen Dank für die Hilfe
Gruß
 
-Was passiert jetzt, wenn der User einen Eintrag modifiziert, d.h. z.B. value ändert? Die Änderung soll ja nicht sofort in die DB geschrieben werden. Wir der Wert trotzdem sofort ins Model geschrieben, d.h. der Eintrag in der Liste, der zur row passt wird entsprechend modifiziert?


Ich versuch die Frage mal zu beantworten. Leider bin ich selber relativ neu im Themengebiet JTable, aber sofern ich das meiner Arbeit mit JTable beurteilen kann, wird der Wert dann jeglich in der ArrayList (bzw. Vector/Map/Mehrdimensionales Array, jenachdem wie du die Daten eingelesen hast). Sofern du das genau in deinem TableModel festlegst, heißt du kannst die Funktion auch umschreiben,dass z.B: gleich die Daten in der Datenbank mit geändert werden.
 
disasterrecover hat gesagt.:
Das TableModel würde einfach eine Liste der Dateneinträge beinhalten.
-Was passiert jetzt, wenn der User einen Eintrag modifiziert, d.h. z.B. value ändert? Die Änderung soll ja nicht sofort in die DB geschrieben werden. Wir der Wert trotzdem sofort ins Model geschrieben, d.h. der Eintrag in der Liste, der zur row passt wird entsprechend modifiziert?

So wie ich das rausgehört habe, wird dein TableModel initial mit Daten aus der Datenbank gefüllt. Sprich deine Daten werden lokal in der Liste deines TableModels zwischengespeichert (gecached). Nun kommt es auf deine Implementierung des TableModels an. Alle Änderungen an der Table sollten natürlich grundsätzlich im TableModel landen, damit die Table ihre Daten immer aktuell anzeigen kann. Dies bedeutet nicht automatisch dass alle Änderungen auch gleichzeitig in der Datenbank gespeichert werden, außer(!!) dieses ist explizit im TableModel mit angegeben oder via PropertyChangeListener an deinen Datenobjekten realisiert, was aber offensichtlich nicht der Fall ist, so wie ich das bei dir rausgehört habe, da erst beim Drücken des Buttons die Daten wieder aus dem TableModel ausgelesen und in die Datenbank zurückgeschrieben werden sollen.

disasterrecover hat gesagt.:
-Wenn der User Einträge löscht, dann kann ich die ja nicht direkt aus dem Model löschen, da ich nachher sonst nicht mehr wüsste, das ich ihn löschen muss.

Doch, kannst du, allerdings musst du genau diesen Fall auch berücksichtigen, wenn du die Daten mit der Datenbank synchronisieren möchtest. Entweder merkst du dir an anderer Stelle via TableModel welche Datensätze du gelöscht hast und löscht diese dann beim Buttonklick manuell oder du vergleichst die IDs (gehe mal davon aus, dass deine lokalen Daten auch über eine eindeutige ID verfügen, sonst wird das zurücksynchronisieren schwer 🙂 ) der Datensätze beim zurückschreiben, schaust welche mit deinem Datenmodel nicht übereinstimmen und löscht diese.

disasterrecover hat gesagt.:
-Was passiert, wenn einfach ein neuer Eintrag zwischen zwei Bestehenden eingefügt werden soll? Verschiebe ich die Einträge in meinem Model?

Das ist ein bisschen trickey, da du die Daten aus der Datenbank beziehst. Lokal könntest du deine Datenstruktur via einer sortierten Liste (LinkedList eignet sich dafür glaub ich ganz gut) vorhalten. Dort kannst du ohne weiteres deine Datensätze dann anhand der RowNr mittendrin einfügen und die entsprechenden Events feuern. Jedoch musst du darauf achten, dass diese Reihenfolge dann beim Speichern der Daten in die Datenbank nicht verloren geht. Dort müsstest du dann die Reihenfolge mit ablegen, damit du sie beim erneuten Auslesen wieder in der richtigen Reihenfolge in dein TableModel reinschreiben kannst.

Grüße,
ymene
 
Danke erstmal.

Ich denke ich werde die Originaldaten in einer separaten Liste vorhalten. D.h. das Model hat dann eine Liste mit den Daten wie sie auf der Gui zu sehen sind (die fleißig manipuliert werden kann) und eine mit den initialen Daten. Damit kann man sich dann was zusammenbauen, was beim Speichern dafür sorgt, dass die Daten korrekt zurückgeschrieben werden. Hört sich das einigermaßen plausibel an?

Jetzt habe ich aber noch ein paar weitere, technisch detailliertere Fragen.

Ich habe auf der Gui zwei Comboboxen, die voneinander abhängig sind. D.h. wenn die eine sich ändert, sollte die andere das Model tauschen. Wer ist denn für soetwas verantwortlich? Sollte das TableModel auch die Combobox Models bereitstellen und für deren Update sorgen? D.h. Combo1 ändert was, das wird ans Model kommuniziert und dadurch wird dann combo2 geändert.

Wie funktioniert das mit den Zellen-Editoren? Ich kann ja per Klasse oder auch per Spalte eine Editor Klasse festlegen. Zunächst, wer beantwortet die Frage, ob eine Zelle editierbar ist, das TableModel? Was passiert nach Beendigung des Editiervorgangs? Die Änderung wird ja ins TableModel geschrieben. Mache ich das manuell?

Danke und Gruß
 
Ich denke ich werde die Originaldaten in einer separaten Liste vorhalten. D.h. das Model hat dann eine Liste mit den Daten wie sie auf der Gui zu sehen sind (die fleißig manipuliert werden kann) und eine mit den initialen Daten. Damit kann man sich dann was zusammenbauen, was beim Speichern dafür sorgt, dass die Daten korrekt zurückgeschrieben werden. Hört sich das einigermaßen plausibel an?

Das wäre der erste, nahe liegende Ansatz. Kann aber diffizil werden, man sollte sich GENAU überlegen, ob das reicht. Leider kenne ich mich mit Datenbanken nicht so aus, deswegen weiß ich nicht, welche Möglichkeiten es da gibt, gezielt einzelne Updates zu machen. Aber angenommen, man löscht z.B. die erste Zeile. Wie sollte man dann Vorgehen, um die in der DB notwendingen Änderungen zu bestimmen? Man schaut sich jeweilst die erste Zeile der alten und neuen Daten an, und merkt: Die sind unterschiedlich. Also muss die erste Zeile aktualisiert werden. Und dann die zweite, und dritte... und nur die letzte Zeile wird in der DB gelöscht. D.h. dann hat man die komplette DB neu geschrieben, obwohl man nur die erste Zeile hätte löschen müssen.

Ich könnte mir aber vorstellen, dass es Vorteile bringen könnte, tatsächlich die Änderungen zu verfolgen. Jemand, der sich mit DBs besser auskennt, könnte da vielleicht konkreter werden, aber: Es müßte doch möglich sein, jeden einzelnen TableModelEvent auf eine Datenbankaktion abzubilden. Wenn man sich die Beispiele oben bei TableModelEvent so ansieht, sieht das doch schon fast perfekt nach Datenbank-Befehlen aus. Ggf. noch den jeweils neuen Wert (bei INSERT und UPDATE) dazuspeichern, das müßte doch gehen :reflect:

Ein Vorteil: Man kriegt den "Undo"-Button praktisch gratis dazu 😀



Ich habe auf der Gui zwei Comboboxen, die voneinander abhängig sind. D.h. wenn die eine sich ändert, sollte die andere das Model tauschen. Wer ist denn für soetwas verantwortlich? Sollte das TableModel auch die Combobox Models bereitstellen und für deren Update sorgen? D.h. Combo1 ändert was, das wird ans Model kommuniziert und dadurch wird dann combo2 geändert.

ComboBoxes haben eigene Modelle, da sollte das TableModel eigentlich nichts damit zu tun haben....
 
ComboBoxes haben eigene Modelle, da sollte das TableModel eigentlich nichts damit zu tun haben....

Genau. Aber wer stellt die Modelle bereit? Mein Dateneintrag hat ja bspw. attr1=a und aatr2=ac (siehe unten). Könnte/sollte dann nicht das TableModel den Editoren die Models bereitstellen? Oder macht man das einfach ganz getrennt ... Wäre ja irgendwie auch weniger kompliziert. Anders müsste man ja bei Change der combo1 das Model informieren, welches dann combo2 triggert..

combo1:
a,b,c

wenn oben a ausgewählt wird:
combo2
aa,ab,ac
wenn oben b ausgewählt wird:
combo2
ba,bb,bc
...

Editoren für die Combos würde ich so setzen:
new DefaultCellEditor(new JComboBox comboBox(aModel))
 
Hmmja... Wer weiß denn wann (und woher) welche Auswahlmöglichkeiten man in der zweiten ComboBox hat, wenn in der ersten ein bestimmter Eintrag gewählt wurde? Das TableModel enthält ja eigentlich erstmal nur die Daten, die auch wirklich in der Tabelle liegen, und eigentlich nicht die, die drin liegen könnten (d.h. nicht die Optionen - die stehen im ComboBoxModel).
 

Zurück
Oben