Tabelle neu laden
Esther
- java
0 Slyh0 Esther0 Slyh0 Esther0 Lemmy Danger0 Esther0 Lemmy Danger0 Dominik
0 Esther
Hi
Ich initialisere eine Tabelle mit bestimmten Werten im Stil von:
JTable jtable = new JTable(Object[][] rowData, Object[] columnNames)
Zu einem späteren Zeitpunkt möchte ich dieselbe Tabelle aber mit dem inzwischen geänderten Object[][] laden.
Wie kann ich das am einfachsten realisieren?
Danke für eure Hilfe
Gruss E.
Hallo,
JTable jtable = new JTable(Object[][] rowData, Object[] columnNames)
Zu einem späteren Zeitpunkt möchte ich dieselbe Tabelle aber mit dem inzwischen geänderten Object[][] laden.
Die Daten der JTable befinden sich in einem Model. Konkret handelt es
sich dabei um eine Klasse, die javax.swing.table.TableModel implementiert.
JTable verwendet von Haus aus javax.swing.table.DefaultTableModel.
Du hast 2 Möglichkeiten:
1. Du weist der JTable eine neue TabelModel-Instanz zu. Hierfür mußt
du die Methode JTable.setModel(Model) verwenden.
Lege beispielweise ein neues DefaultTableModel-Objekt an. Es steht
ein Konstruktor zur Verfügung, der die Zelleninhalte und die
Spaltennamen aufnimmt. (Genau wie der Konstruktor von JTable.)
Übergib dieses Objekt der setModel-Methode.
2. Da du (jetzt) weißt, daß JTable eine Instanz von DefaultTableModel
als Model verwendet, kannst du dir mit der Methode JTable.getModel()
dieses Objekt geben lassen, es nach DefaultTableModel casten und
dann die Methode DefaultTableModel.setDataVector(Object[][], Object[])
dazu verwenden, um die Daten im Model festzulegen.
Wenn du sicher gehen willst, daß wirklich ein DefaultTableModel-
Objekt als Model verwendet wird, kannst du das Model auch nach dem
erzeugen der JTable von Hand setzen. Etwa so (ungetestet!):
DefaultTableModel dtm = new DefaultTableModel(data, columns);
JTable table = new JTable(dtm);
So könntest du dir auch gleich das Model (dtm) in einer Instanz-
variable speichern und müßtest dann nicht immer JTable.getModel()
aufrufen um an das Model zu kommen.
Falls dir die Geschichte mit dem Model spanisch vorkommt, würde ich
dir ein Java-Buch deiner Wahl (am besten http://www.javabuch.de oder
http://www.galileocomputing.de/openbook/javainsel3/), sowie die Tutorials
von Sun zum Thema (Links findest du in der API-Doku zu JTable und
TableModel) und den Java Almanach (http://javaalmanac.com/egs/?) empfehlen.
Gruß
Slyh
Hallo Slyh
Danke für deine ausführliche Antwort. Ich bin mir jedoch nicht sicher ob du mich richtig verstanden hast. Das Array, mit welchem ich ursprünglich die Tabelle fülle, wird später geändert (Aber völlig unabhängig von der Tabelle) Nun sollte die Tabelle neu geladen werden, das Array ist immernoch dasselbe...
G. E
Hallo,
Danke für deine ausführliche Antwort. Ich bin mir jedoch nicht sicher ob du mich richtig verstanden hast. Das Array, mit welchem ich ursprünglich die Tabelle fülle, wird später geändert (Aber völlig unabhängig von der Tabelle) Nun sollte die Tabelle neu geladen werden, das Array ist immernoch dasselbe...
Was denn nun? Wird das Array geändert oder wird es nicht geändert? :)
Und was meinst du damit, daß es geändert wird?
Ändern sich nur die Objekte selbst, die sich "im Array befinden"?
(Eigentlich sind es ja nur Referenzen auf die konkreten Objekte.
Ich meine die Objekte.) Oder ersetzt du auch einzelne Array-Elemente?
Im ersten Fall dürfte die Änderung direkt von der JTable übernommen.
(Mach zur Sicherheit mal ein Repaint.) Ansonsten mußt du wie von mir
beschrieben das TableModel updaten/neu setzen.
Falls du dir nicht sicher bist, dann beschreib dich mal möglichst genau
was für Daten du hast, was du am Array änderst und welches Ergebnis
du erwartest.
Gruß
Slyh
Hallo Slyh
OK, ich versuchs noch einmal. Es sind Bücherdaten, welche als Objekte aus einem Textfile eingelesen und in einen Vector geschrieben werden. Anschliessend wird der Vector in ein Array umgewandelt, sodass er in der Tabelle angezeigt werden kann (es gibt zwar eine Methode um Tabellen mit Vectoren zu laden, habe ich aber nicht hingekriegt:
public void initTable() {
String columnNames[] = {"ID", "Title", "Author", "Date"};
String rowData[][] = new String[bManager.vBooks.indexOf(bManager.vBooks.lastElement())+1][4];
for(int i=0; i<=bManager.vBooks.indexOf(bManager.vBooks.lastElement());i++) {
rowData[i][0] = String.valueOf((((Book)bManager.vBooks.elementAt(i)).bookID));
rowData[i][1] = (((Book)bManager.vBooks.elementAt(i)).author);
rowData[i][2] = (((Book)bManager.vBooks.elementAt(i)).title);
rowData[i][3] = (((Book)bManager.vBooks.elementAt(i)).year);
}
table = new JTable(rowData, columnNames);
table.setEnabled(false);
JScrollPane sp = new JScrollPane(table);
sp.setBounds(20,150,400,150);
cp.add(sp);
}
Zu einem späteren Zeitpunkt fügt der Benutzer ein neues Buch hinzu. Das Buch wird diesem Vector angefügt. Jetzt muss natürlich das Buch auch in der Tabelle angezeigt, dh. die Tabelle neu geladen werden.
Ich hoffe es ist verständlich geworden.
Danke.
Gruss Esther
Guude!
Hallo Slyh
Ich fühle mich jetzt einfach auch mal angesprochen ;-)
es gibt zwar eine Methode um Tabellen mit Vectoren zu laden, habe ich aber nicht hingekriegt:
Das hat mir anfangs auch Probleme bereitet, ist aber gar nicht so schwer und dabei noch wesentlich flexibler: Wenn Du zwei Vektoren hast, z.B. "vColNames" mit den Spaltennamen und "vData" mit den Tabellendaten (jedes Element des Datenvektors steht für eine Zeile und muss entweder einen weiteren Vektor oder ein Array für die jeweiligen Spalten der Zeile enthalten), weist Du die einem Tabellenmodell zu und registrierst dieses:
DefaultTableModel dtm = new DefaultTableModel(vData, vColNames);
JTable table = new JTable(dtm);
Das Buch wird diesem Vector angefügt. Jetzt muss natürlich das Buch auch in der Tabelle angezeigt, dh. die Tabelle neu geladen werden.
Füge das neue Buch doch direkt in die Tabelle ein:
Vector neueZeile = new Vector(4);
neueZeile.add(neuesBuch.bookID);
neueZeile.add(neuesBuch.author);
neueZeile.add(neuesBuch.title);
neueZeile.add(neuesBuch.year);
((DefaultTableModel)table.getModel()).addRow(neueZeile);
table.repaint();
Wie Slyh schon sagte, enthält das TableModel alle Tabelleninhalte. Wenn Du also mit den Daten einer Tabelle arbeiten möchtest, dann greife auf sie direkt über das Tabellenmodell zu. Gerade das DefaultTableModel bietet dazu eine ganze Reihe nützlicher Methoden (siehe http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/table/DefaultTableModel.html).
LG ausm Hesseland
Lemmy
Hallo Lemmy und Slyh
Ihr habt mich überzeugt, ich habe auf DefaultTableModel und Vectoren umgestellt. Der Code sieht so aus:
public void initTable() {
Vector vData = new Vector();
Vector vColumnNames = new Vector(4);
vColumnNames.add("ID");
vColumnNames.add("Title");
vColumnNames.add("Author");
vColumnNames.add("Date");
for(int i=0; i<=bManager.vBooks.indexOf(bManager.vBooks.lastElement());i++) {
String rowData[] = new String[4];
rowData[0] = String.valueOf((((Book)bManager.vBooks.elementAt(i)).bookID));
rowData[1] = (((Book)bManager.vBooks.elementAt(i)).author);
rowData[2] = (((Book)bManager.vBooks.elementAt(i)).title);
rowData[3] = (((Book)bManager.vBooks.elementAt(i)).year);
vData.add(rowData);
}
DefaultTableModel dtm = new DefaultTableModel(vData, vColumnNames);
JTable table = new JTable(dtm);
JScrollPane sp = new JScrollPane(table);
sp.setBounds(20,150,400,150);
cp.add(sp);
}
und jetzt hab ich den Schlammasel...:
Exception in thread "main" java.lang.ClassCastException
at javax.swing.table.DefaultTableModel.justifyRows(DefaultTableModel.jav
a:238)
at javax.swing.table.DefaultTableModel.setDataVector(DefaultTableModel.j
ava:194)
at javax.swing.table.DefaultTableModel.<init>(DefaultTableModel.java:131
)
at BookFrame.initTable(BookFrame.java:147)
at BookFrame.<init>(BookFrame.java:41)
at BookFrame.main(BookFrame.java:254)
Was nun? Woran liegt das wohl?
Gruss und Danke für eure Hilfe
Esther
Hallo Esther!
String rowData[] = new String[4];
Kann es sein, dass dies hier oben Deine Zeile 147 ist? Du hast die eckigen Klammern falsch gesetzt: "String[] rowData = new String[4];" sollte es heißen.
Ansonsten kann ich so auf die Schnelle nichts Falsches entdecken.
LG ausm Hesseland
Lemmy
Hallo Esther!
String rowData[] = new String[4];
Kann es sein, dass dies hier oben Deine Zeile 147 ist? Du hast die eckigen Klammern falsch gesetzt: "String[] rowData = new String[4];" sollte es heißen.
»»
das ist doch egal, beides ist gleich richtig und funktioniert gleich. Daran liegt es nicht...
Dominik
Guude!
das ist doch egal, beides ist gleich richtig und funktioniert gleich. Daran liegt es nicht...
Tatsächlich? Zumindest hab ich die Schreibweise so noch nicht gesehen. Dass es daran nicht liegen kann, ist schon klar, denn 1. hätte es der Compiler angemeckert und 2. erzeugt es keine ClassCastException. In Zeile 238 der Methode justifyRows() des DefaultTableModels heißt es:
((Vector)dataVector.elementAt(i)).setSize(getColumnCount());
Zeilen müssen also einen Vector anstelle eines Array enthalten, sonst kommt es hier zu der ClassCastException. Fehler meinerseits - sorry. Aber eigentlich doof von mir, nochmal zu antworten, denn Esther hatte es experimentell ja schon ermittelt und hinbekommen. Die Gans im Bauch drückt halt auf's Hirn... ;-)
LG ausm Hesseland
Lemmy
Hallo Lemmy
und muss entweder einen weiteren Vektor oder ein Array für die jeweiligen Spalten der Zeile enthalten)...
Also mit einem Array klappts nicht, mit einem Vector schon:-)
Gruss Esther