PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : TableSorter Java


Gast
2004-02-16, 11:29:28
Bei mir funktioniert der TableSorter von Sun nicht richtig, obwohl ich ihn nach Anleitung benutzt habe:

class Oberflaeche(){
...
...
tabellenModel = new DefaultTableModel();
tabellenSorter = new TableSorter(tabellenModel);
tabelle = new JTable(tabellenSorter);
tabellenSorter.addMouseListenerToHeaderInTable(tabelle);
}


Wenn ich auf die Spalte klicke zum Sortieren kommt auf der Konsole nur "Sorting ...
Compares: 0"

Außerdem hab ich den Verdacht, daß, wenn die Tabelle vom User editerbar ist, derTableSorter nichts davon weiß, wenn der User etwas an der Tabelle ändert.

Woran kann das liegen?

HellHorse
2004-02-16, 15:50:00
Also bei mir funktioniert die Demo richtig, auch wenn ich die Spalten verschiebe und Zellen editiere. Leider ist der Stringvergleich nicht caseinsensitiv, aber das lässt sich leicht flicken.

Original geschrieben von Gast
Außerdem hab ich den Verdacht, daß, wenn die Tabelle vom User editerbar ist, derTableSorter nichts davon weiß, wenn der User etwas an der Tabelle ändert.

Das sollte nicht der Fall sein. Der TableSorter (in der Demo) leitet ja die Editierung an das eigentliche Model weiter und sortiert aufgrund der Daten, die das Model liefert. In der Demo funktioniert es problemlos.

public void setValueAt(Object aValue, int aRow, int aColumn) {
checkModel();
model.setValueAt(aValue, indexes[aRow], aColumn);
}

Zum Überprüfen kannst du ja mal DEBUG auf true setzten.

Mehr kann ich anhand des wenigen Codes nicht sagen, da ich nicht weiss, was du sonst noch abgeändert hast. Ausser vielleicht, dass es bei einem leeren Model nicht viel zu sortieren gibt ;). Bei meiner Version ist all das System.out auskommnntiert und die Instanzvariable compares erfüllt keinen Zweck mehr.
Ansonsten kann ich dir nur raten, das Beispiel inkrementell abzuändern, so dass du schnell merkst, wenn du etwas verbockt hast.

Die Demo ist aber weder vorbildlich noch einfach zu verstehen.

Gast
2004-02-16, 16:22:03
Ich benutzte den TableSorter: http://www.cs.umb.edu/~bill/java/tools/jdk-1.4.0/usr/demo/J2SE/demo/jfc/TableExample/src/TableSorter.java

Der kennt auch das TableModel:
public void tableChanged(TableModelEvent e) {
System.out.println("Sorter: tableChanged");

for (int j = 0; j < model.getRowCount(); j++) {
for (int i = 0; i < model.getColumnCount(); i++) {
System.out.println(model.getValueAt(j, i));
}
}

reallocateIndexes();

super.tableChanged(e);
} gibt die Tabelle wieder korrekt aus.


Es wird auch "sorting..." ausgegeben, aber die Tabelle sortiert sich nicht.

HellHorse
2004-02-16, 17:36:32
Bis auf die Formatierung, das einkommentierte System.out und der neue Konstruktor ist das der genau gleiche Code.

compares zählt die Anzahl Vergleiche die gemacht wurden.
Compares: 0
bedeutet also, dass nichts verglichen wurde. Ich vermute daher dass dein Model leer ist.

Ersetze

System.out.println("Sorting ...");

mit

System.out.println("Sorting "+TableSorter.this.model.getRowCount()+" rows");
System.out.println("Sorting "+TableSorter.this.model.getColumnCount()+" columns");

Beide Werte sollten natürlich grösser als 0 sein.

Gast
2004-02-16, 18:59:26
Hmm, der Zeilenanzahl ist immer Null. Die Spaltenanzahl stimmt.

Eingefügt werden die Eiträge hier
if (e.getActionCommand() == "OK") {
MeinTableCellRenderer.geladen = false;
aktiviereMenüNormal(true);
DVD dvd = new DVD(ob.getDVDHinzufuegen());
v = dvd.erzeugeVektor();
ob.getTabellenModel().addRow(v);
ob.löscheDVDHinzufuegen();
}

ob = Oberflaeche

bzw hier:


//Laden
if (e.getActionCommand() == "ApproveSelection" && ob.getSpeichernLaden().getDialogType() == 0 && e.getSource() == ob.getSpeichernLaden()) {
MeinTableCellRenderer.geladen = true;
try {
ob.setTabellenModel(new DefaultTableModel());
ObjectInputStream i = new ObjectInputStream(new FileInputStream(ob.getSpeichernLaden().getSelectedFile()));
ob.setTabellenModel((DefaultTableModel) i.readObject());
i.close();
} catch (FileNotFoundException e1) {
} catch (IOException e1) {
} catch (ClassNotFoundException e1) {
}
aktiviereMenüNormal(true);
}

Nur an o.g. Stellen werden Einträge hinzugefügt.

Wenn ich vorher keine Datei geladen habe, ist copmares auch nicht Null

HellHorse
2004-02-16, 20:58:32
Original geschrieben von Gast
Hmm, der Zeilenanzahl ist immer Null. Die Spaltenanzahl stimmt.

Offensichtlich haut da was beim Hinzufügen nicht hin, ich würde mal mein eigenes schreiben. Einfach von AbstractTableModel erben.

Original geschrieben von Gast
Eingefügt werden die Eiträge hier

...
v = dvd.erzeugeVektor();
ob.getTabellenModel().addRow(v);
...
}

Hier hast du komischerweise ein DefaultTableModel und nicht den TableSorter, der ja ein Proxy für das eigentliche TableModel ist :???:
Wie sieht dieser Vektor aus? Was ist da für Zeugs drin? Überprüf doch mal, ob die Anzahl Zeilen im Model nach dem hinzufügen grösser ist als vorher.
Original geschrieben von Gast

...
ob.setTabellenModel(new DefaultTableModel());
...
ob.setTabellenModel((DefaultTableModel) i.readObject());
...
}

Hier auch DefaultTableModel und nicht den TableSorter :???:
Erste Zeile kannst du dir wohl sparen ;)
Und wenns vor den Serialisieren nicht ok war, dass ist es nachher sicher auch der Fall.
Ich hoffe mal das mit der Seialisierung ist nur eine Übergangslösung.
http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/table/DefaultTableModel.html

Warning: Serialized objects of this class will not be compatible with future Swing releases. The current serialization support is appropriate for short term storage or RMI between applications running the same version of Swing. As of 1.4, support for long term storage of all JavaBeansTM has been added to the java.beans package. Please see XMLEncoder (http://java.sun.com/j2se/1.5.0/docs/api/java/beans/XMLEncoder.html).


Original geschrieben von Gast
Nur an o.g. Stellen werden Einträge hinzugefügt.

Wenn ich vorher keine Datei geladen habe, ist copmares auch nicht Null
Wie, jetzt auf einmal nicht mehr?

Gast
2004-02-18, 13:40:09
Also wie geht denn das jetzt?
Ich muß doch nur das TableModel ändern. Der Sorter wird doch benachrichtigt, daß sich etwas geändert hat, oder doch nicht?


Das mit dem Speichern ist eh nur provisorisch.

HellHorse
2004-02-18, 18:58:04
Original geschrieben von Gast
Also wie geht denn das jetzt?
Ich muß doch nur das TableModel ändern. Der Sorter wird doch benachrichtigt, daß sich etwas geändert hat, oder doch nicht?

Also so wie's im Tutorial ist, und so wie du den ersten Code gepostet hast schon, so wie du den zweiten gepostet hast nicht. Dies gillt allerdings nur für Modifikation einer Zelle, nicht das Hinzufügen oder entfernen von Zeilen (siehe weiter unten). Sorry, mein Fehler, hatte das übersehen.

Der TableSorter ist ein Proxy für ein TableModel. Er sieht aus wie ein TableModel, verhält sich wie ein TableModel, enthält aber keine wirklichen Daten. Statdessen transformiert er alle Anfragen (ändert die Indizes) und leitet (eigententlich die Superklasse) sie an das eigentliche Model weiter, das die Daten enthält.

Was du zur Verfügung stellen musst, ist ein eigentliches TableModel, das die Daten enthält und an das der TableSorter die Anfragen weiterleiten kann. Hierfür kannst du DefaultTableModel verwenden oder ein eigenes schreiben (vorzugsweise von AbstractTableModel erben).
Diesem Model müssen dann die Daten hinzugefügt werden (vom Controller), worauf dieses den View benachrichtigt. Und es muss auch der Sorter benachritig werden, so dass er die Indices anpasst. Auf einfache Weise geht dies mit einem TableModelListener.

Gast
2004-02-19, 09:31:20
Jetzt klappts. :up: