Swing Daten zwischen JTable teilen

ChrisAv

Mitglied
Hallo zusammen,
ich brüte seit mehreren Tagen über ein Problem für welches ich keine Lösung finde.

Kurze Beschreibung des Problems:
Ich habe 2 CustomTableModel (beide vom AbstractTableModel abgeleitet), welche für JTable herhalten. Der JTable mit TableModel1 enthält Informationen zu Farben, der JTable des TableModel2 enthält Daten, die weiterverwendet werden. Beide Table werden in eigenen JPanel dargestellt.
Ich möchte erreichen, die Bezeichnung der Farbe (als Spalte dargestellt) aus JTable1 in einem Dropdownmenü einer Spalte im JTable2 zu nutzen.

Mein Weg bisher ist folgender:
Ich habe die Farbinformationen als Classvariable deklariert, um ohne Erzeugung einer Instance auf sie zugreifen zu können.
Java:
public class TableModel 1 extends AbstractTableModel {
	public static ArrayList<CustomType> colorInformation = new ArrayList<CustomType>();
}
Im TableModel2 greife ich bei der Formatierung der Spalte mit einem Dropdown (über eine JComboBox) auf die oben genannte Classvariable zu.
Java:
public class TableModel2 extends AbstractTableModel {
    private ArrayList<CustomType> colorList = new ArrayList<CustomType>();
	public void setUpColorColumn(TableColumn colorColumn){
        JComboBox comboBox = new JComboBox();
        colorList = TableModel1.colorInformation

        for (int i = 0; i < colorList.size(); i++){
            comboBox.addItem(colorList.get(i).getID());
        }
}

Mein Problem ist nun, dass die Daten im Dropdown des TableModel2 zwar dargestellt werden, sie jedoch bei einer Änderung der Daten in Table1 nicht aktualisiert werden.

Die einzige mir einfallende Lösung nutzt eine synchronized ArrayList. Da ich mich bisher jedoch noch nicht mit der Verwendung von Threads auseinander gesetzt habe, scheue ich eine „try-and-error“ Methode zu implementieren.

Habt ihr eine Idee, wie ich dieses Problem lösen kann?
 
erstmal Prinzipiell:

Wenn Objekt B auf Änderungen von Objekt A reagieren soll, dann muss entweder B sich mit einem Listener an A registrieren, oder A muss B aktualisieren.

Nun zu deinem Problem. So wie ich das verstanden habe, wird die Color-ComboBox in deinem Model erzeugt. Richtig? Das ist ein unschöner Ansatz, da du damit dein Datenmodell mit der Darstellung mischst und somit das MVC-Pattern verletzt.

Richtig wäre folgendes: Du hast ein Datenobjekt "CustomColor". Dies enthält den Name, die Farbinformation und eine ID. Wie du schon hast, wird es über die Tabelle 1 dargestellt und bearbeitet.

In Tabelle 2 enthält ein zweites Datenobjekt. Dies enthält unter anderem als Variable eine Farb-ID. Soweit so gut.
Nun willst du ja nicht die ID anzeigen, sondern via Drop-Down-Box eine Farbe auswählen.
Hierzu erstellst du dir eine ComboBox mit deinen CustomColor-Objekten. Diese Fügst du als Table-Cell-Renderer der Tabelle an der entsprechenden Spalte hinzu.

Um nun auf Änderungen in der Tabelle 1 zu reagieren, musst du nur die ComboBox per Listener an Tabelle 1 registrieren. Jedesmal wenn sich etwas ändert, würde ich dann die ComboBox neu befüllen oder (besser sogar) nur das entsprechende Element austauschen.

So, ich hoffe ich hab das verständlich genug ausgedrückt! *g*
 
Wenn beide JTables auf mehr oder weniger dieselbe Information zugreifen müssen, warum nicht ein gemeinsames TableModel verwenden?

Was ich auch noch merkwürdig finde: Was hat eine JComboBox in eimem TableModel verloren?
 
Wenn beide JTables auf mehr oder weniger dieselbe Information zugreifen müssen, warum nicht ein gemeinsames TableModel verwenden?

Was ich auch noch merkwürdig finde: Was hat eine JComboBox in eimem TableModel verloren?

scheinbar will er in der einen Table sich ein komplexes Color-Objekt schaffen wo er u.a. einen Namen vergeben kann. Den will er dann in der Combo anzeigen. Ist soweit ja ganz OK. Aber die ComboBox im Model find ich wie schon gesagt etwas "ungelungen" *g*
 
Wenn Objekt B auf Änderungen von Objekt A reagieren soll, dann muss entweder B sich mit einem Listener an A registrieren, oder A muss B aktualisieren.

Es fällt mir wie Schuppen von den Augen. Auf die Idee mit dem Listener bin ich nicht gekommen, an anderer Stelle habe ich ihn bereits verwendet. Vielen Dank für den Tipp! Ich versuch mir daran 🙂

Nun zu deinem Problem. So wie ich das verstanden habe, wird die Color-ComboBox in deinem Model erzeugt. Richtig? Das ist ein unschöner Ansatz, da du damit dein Datenmodell mit der Darstellung mischst und somit das MVC-Pattern verletzt.
Ich habe die ComboBox in das Model gesteckt, um das Model "im Paket" zu erzeugen. Wäre es richtig, den CellRenderer in den JFrame zu schreiben?

Um nun auf Änderungen in der Tabelle 1 zu reagieren, musst du nur die ComboBox per Listener an Tabelle 1 registrieren. Jedesmal wenn sich etwas ändert, würde ich dann die ComboBox neu befüllen oder (besser sogar) nur das entsprechende Element austauschen.
Ich denke ich werde zunächst die gesamte ComboBox neu füllen, dann brauche ich keine Differenzprüfung durchzuführen.

So, ich hoffe ich hab das verständlich genug ausgedrückt! *g*
Auf jeden Fall!

Ich benötige je ein eigenes TableModel, um die speziellen Anforderungen an die Table erfüllen zu können. Speziell hier die Aufbereitung der Daten. Ich könnte natürlich ein "Universalmodel" erstellen, jedoch müsste ich dann pro Table bestimmte Eigenschaften (z.B. Einfärbung der Zeile in Abhängigkeit der rgb-Werte) deaktivieren.
 
Ich könnte natürlich ein "Universalmodel" erstellen, jedoch müsste ich dann pro Table bestimmte Eigenschaften (z.B. Einfärbung der Zeile in Abhängigkeit der rgb-Werte) deaktivieren.
Sowas ist nicht Aufgabe des Models, das Model hält nur die Daten bereit und informiert alle Interessenten über deren Änderungen. Wie die Daten letztendlich dargestellt werden liegt dann in der Hoheit der graphischen Komponenten z.B. einer JTable.
Je komplexer das ganze wird, desto wichtiger ist es die Daten sauber von der Darstellung zu trennen.
 
Ich möchte euch noch einmal um Hilfe bitten. Ich habe einen TableModelListener an meinen Table1 (Farbinformationen) gehängt . Dieser Listener soll nun die Daten der JComboBox (als Vector) aktualisieren. Jedoch sind die Einträge erst sichtbar, wenn ich einen Eintrag der ComboBox ausgewählt habe. Vorher ist das Dropdown Menü "leer" (keine Einträge sichtbar, jedoch genügend Zeilen vorhanden). Zusätzlich habe ich versucht, die ComboBox nach Aufrufen des Table1 zu füllen. Dies funktioniert jedoch nicht.

Implementierung des TableModelListener:
Java:
        model.addTableModelListener(new TableModelListener() {

            public void tableChanged(TableModelEvent tme) {
                for (int i = 0; i < allColorSymbols.size(); i++){
                    symbolID.add(allColorSymbols.get(i).getID());
                }
                // Aktualisierung der static Methode im Panel des Table2. Eine wahrscheinlich sehr
                // unelegenate Methode.
                NavaidPanel.symbolID = symbolID;
            }
        });

Generell stellt sich mir die Frage, ob der Zugriff auf static Variablen einer Klasse der richtige Weg ist. Ich möchte die Daten der ComboBox aktualisieren, ohne eine Instanz des Tabels mit der ComboBox zu erstellen. Könnt ihr mir einen Denkanstoß geben, wie es besser (eleganter) klappt?
 
Zuletzt bearbeitet:

Zurück
Oben