vertrackter Update mehrerer JTables

tobiaft

Mitglied
Hallo!

Nachdem ein Button gedrückt wurde und Daten per EJB in eine DB geschrieben wurden, sollen 2 JTables upgedatet werden. Das Problem liegt beim Update des Panel5, Panel9 wird problemlos upgedatet:
Code:
//update of Panel9
this.panel9.orderModel.getData();
this.panel9.orderbook.revalidate();
//update of Panel5
this.panel5.marketModel.getData();
this.panel5.marketTable.revalidate();

Im Panel5 sind auf mehreren Registerkarten eines JTabbedPane (=1 Markt) jeweils eine JScrollPane mit einem JTable geadded. Diese werden mittels einer Schleife erzeugt, je nachdem wie viele Märkte in der DB bestehen. Alle quasi-identischen JTables werden über ein gemeinsamesTableModel gemanagt. Meine Idee wäre, dass das AbstractTableModel es nicht handeln kann mehrere JTables upzudaten :confused: [siehe Screenshot]

Beide getData-Methoden sind nahezu identisch. Hier getData() des TableModels von Panel5:
Code:
/**
    * Method that fetches the data from the DB and sorts them alphabetically
    */
   public void getData() {
	    
	   Collection coll = null;
	   Collection sorted = new ArrayList();
       Iterator it = null;
	   
       try {
           coll = clientview.getMarketAssetsForMarket(this.marketVO);
       } catch (AccessDeniedException e) {            
           e.printStackTrace();
       } catch (Exception e) {            
           e.printStackTrace();
       }      
        
       it = coll.iterator();       
       MarketAssetVO first_marketassetVO = null;
       /**
        * While loop that adds the MarketAssetVOs alphabetically by assetname
        * to sorted-ArrayList. 
        */
	   while(it.hasNext()) {
	        first_marketassetVO = getFirstMarketAssetVO(coll);	        
	        sorted.add(first_marketassetVO);
		    coll.remove(first_marketassetVO); //remove s.th. it is not added twice
		    it = coll.iterator();
	   }
	   //cast sorted array-list (=collection) to array
	   marketassetVOs = (MarketAssetVO[]) sorted.toArray(new MarketAssetVO[0]);
	}
 

Anhänge

  • screenshot.jpg
    screenshot.jpg
    94,7 KB · Aufrufe: 105
tobiaft hat gesagt.:
Hallo!

Nachdem ein Button gedrückt wurde und Daten per EJB in eine DB geschrieben wurden, sollen 2 JTables upgedatet werden. Das Problem liegt beim Update des Panel5, Panel9 wird problemlos upgedatet:

- Manchmal muss ein invalidate() vor dem validate() aufgerufen werden
- Manchmal reicht ein revalidate() nicht aus, dann muss das o.a. Konstrukt ausgeführt werden
- Üblicherweise reicht ein fireTableDataChanged() - vor allem wenn sich nur die Daten in der Tabelle ändern. Wird jedoch mit dem Tabellengerüst gearbeitet und das Spaltenmodell z.B. geändert, ist ein fireTableStructureChanged() mitunter notwendig.
- Ich vermute, das Problem liegt in der Verwendung der JTabbedPane begründet, kann aber hier so aus der Ferne nichts weiter dazu sagen/testen, dafür fehlt mir das Projekt bzw. der Code zum Debuggen.
- Es kostet heute nichts mehr an Speicher oder Leistung, Variablen lange, sprechende Namen zu geben.
- Public Variablen sind in der OO-Welt verpönt.
 
OK, Danke erstmal!

Das Testen mit invalidate(), validate() und fireTableChanged() hat leider nicht funktioniert. Leider weiß ich auch nicht so recht, wie ich das Problem mit dem Debug-Modus rausfinden kann?
 
Moin,
mit dem Debuggen hast Du natürlich recht. Wenn es sich um ein Refresh-Problem handelt, hilft Dir Debuggen vermutlich nicht viel.
Ich schätze es sind mehr Informationen nötig über die Art und Weise der Datenhaltung und des Updates, um dem Fehler bzw. der Fehlerbehebung näher zu kommen.
 
Ich schätze es sind mehr Informationen nötig über die Art und Weise der Datenhaltung und des Updates, um dem Fehler bzw. der Fehlerbehebung näher zu kommen.
Das heisst, Du weisst an der Stelle auch nicht weiter, oder wie könnte ich zu mehr Infos beitragen?
 
Korrekt, so weiß ich gerade auch nicht weiter. Ich müsste mich da auch intensiv reinknien und mir den Code anschauen. Dabei wichtig wie gesagt, wie die Daten verwaltet werden - eigenes TableModel, als Array usw.? - und was bei dem buttonClick passiert bzw. passieren soll und wie der Zustand des oberen Panels ist, wenn der buttonClick ausgeführt wird. Möglicherweise ein "einfacher" Fehler, möglicherweise aber auch Swing-Fummelei mit der TabbePane.
 
Dabei wichtig wie gesagt, wie die Daten verwaltet werden - eigenes TableModel, als Array usw.? - und was bei dem buttonClick passiert bzw. passieren soll und wie der Zustand des oberen Panels ist, wenn der buttonClick ausgeführt wird.
Mein Update habe ich in der Klasse Panel7 jetzt so geschrieben - ohne das es funktioniert - weil ich meine, dass es theoretisch so gehen müsste:
Code:
//send order to DB via clientview (EJB)
this.mainGrid.clientview.newOrderSimple(price,qty,buysell,marketVO,assetVO);
/**
* update of Panel5
* getData() fetches the data from the DB, stores them in an array and transfers them to the getValueAt()-method in the TableModel
*/
this.mainGrid.panel5.panel5TableModel.getData(); 
this.mainGrid.panel5.panel9TableModel.fireTableDataChanged();

Für die Tabelle in der Klasse Panel5 gibt es ein eigenes TableModel, wobei die Daten, die aus der mySQL-DB kommen zunächst in einer Collection gespeichert werden, dann sortiert und in ein Array umgewandelt werden:
Code:
//cast sorted array-list (=collection) to array
marketassetVOs = (MarketAssetVO[]) sorted.toArray(new MarketAssetVO[0]);
Der buttonClick soll Daten aus Textfeldern und JLabels auslesen und diese an die DB senden (siehe oben, erste Zeile des Codes).
Was meinst Du mit "Zustand des oberen Panels", wenn der Click ausgeführt wird?

Danke!
 
tobiaft hat gesagt.:
Mein Update habe ich in der Klasse Panel7 jetzt so geschrieben - ohne das es funktioniert - weil ich meine, dass es theoretisch so gehen müsste:
Code:
//send order to DB via clientview (EJB)
this.mainGrid.clientview.newOrderSimple(price,qty,buysell,marketVO,assetVO);
/**
* update of Panel5
* getData() fetches the data from the DB, stores them in an array and transfers them to the getValueAt()-method in the TableModel
*/
this.mainGrid.panel5.panel5TableModel.getData(); 
this.mainGrid.panel5.panel9TableModel.fireTableDataChanged();

1. Ich fange gleich an zu weinen. Oder zu singen: "Über sieben Referenzen musst du geh'n..." --> this.mainGrid.panel5.panel5TableModel.getData(); <-- zähl mal die ReferenzPUNKTE. Schon mal was von OO, Kapselung, getter-setter gehört?
2. Du rufst getData() auf panel5 auf, löst aber auf panel9 ein fireTableDateChanged aus. Entweder kann das so nicht hinhauen, oder Du unterschlägst mir die Info, dass bei getData() auch noch die Datenbasis der Tabelle in panel9 geändert wird. Ansonsten ergibt das keinen Sinn.

Was meinst Du mit "Zustand des oberen Panels", wenn der Click ausgeführt wird?

Danke!

Wie gesagt, wenn es sich um ein Refreshproblem handelt, kann es sein, dass es wichtig ist, welcher TAB gerade vorne in der Ansicht ist.
 
Diese werden mittels einer Schleife erzeugt, je nachdem wie viele Märkte in der DB bestehen. Alle quasi-identischen JTables werden über ein gemeinsamesTableModel gemanagt.
Darin lag der Fehler, d.h. das gemeinsame TableModel für mehrere JTables wurde nicht geupdatet, wenn einmal fireTableDataChanged() aufgerufen wurde.
Gelöst habe ich es mit einem Array von TableModels, so dass jedes Table der Registerkarten ein einzelnes TableModel bekommen hat, dass ich dann eben auch einzeln mit der fireTableDataChanged ansprechen konnte ;-)

Code:
//initialize array of TableModels
for (int i=0; i<20; i++) {
   panel5TableModel[i] = null;
}
in der Schleife:
Code:
panel5TableModel[i] = new Panel5TableModel(this.mainGrid, tempVO);
marketTable.setModel(panel5TableModel[i]);
Update-Aufruf:
Code:
panel5TableModel[i].fireTableDataChanged();

@ Snape:
Ich fange gleich an zu weinen. Oder zu singen: "Über sieben Referenzen musst du geh'n..." --> this.mainGrid.panel5.panel5TableModel.getData(); <-- zähl mal die ReferenzPUNKTE. Schon mal was von OO, Kapselung, getter-setter gehört?
Ich weiß, finde es auch nicht schön, wusste aber leider nicht, wie ich bei meiner verschachtelten Klassenstruktur der GUI sonst darauf zugreifen soll. OK, ich kann natürlich auch die Referenzen direkt nach unten mit übergeben und dann jeweils getter- und setter-Methoden aufrufen. Aber ist das dann so viel besser von der Übersichtlichkeit her? Es wird dann eben jeder Klasse irgendeine andere Referenz mit übergeben.

Vielleicht check ich es auch nur nicht, und es geht im Grunde viel einfacher?
 
Zurück