# JTable sortieren



## Stinner (11. Sep 2009)

Hallo,
habe die FAQs gelesen und auch die ganzen Beiträge in diesem Forum zu dem Thema sortieren. Bekomme es trotzdem nicht hin.
Bzw. wenn ich meine JTable erstelle funktioniert das ganze mit einem TableRowSorter:

```
MyTableModel tmodel = new MyTableModel();
sorter = new TableRowSorter<MyTableModel>(tmodel);
List<RowSorter.SortKey> sortKeys = new ArrayList<RowSorter.SortKey>();
sortKeys.add(new RowSorter.SortKey(0, SortOrder.ASCENDING));
sorter.setSortKeys(sortKeys);
datatable = new JTable(tmodel);
datatable.setRowSorter(sorter);
```

Damit sortiere ich die JTable nach der ersten Spalte. Jetzt will ich nach nachdem der Nutzer an der Table rumgespielt hat, die Table wieder nach der ersten Spalte sortieren. mache das so, klappt aber nicht:

```
TableRowSorter sorter = (TableRowSorter) datatable.getRowSorter();
List<RowSorter.SortKey> sortKeys = new ArrayList<RowSorter.SortKey>();
sortKeys.add(new RowSorter.SortKey(1, SortOrder.ASCENDING));
sorter.setSortKeys(sortKeys);
sorter.sort();
```

Die sortKeys setzten mache ich nur, weil ich es im Inet gelesen habe. Nach meinem Verständnis müsste doch reichen

```
TableRowSorter sorter = (TableRowSorter) datatable.getRowSorter();
sorter.sort();
```

Das klappt aber nicht. Könnte natürlich die Daten in meinem MyTableModel sortieren und das ganze anzeigen, aber würde es gerne mit dem TableRowSorter machen. Dann ist auch der Pfeil in dem Spaltenkopf.
GRuß


----------



## hdi (12. Sep 2009)

Wo steht dein Code denn? Also wann und wo rufst du dieses "Neu-Sortieren" (also der zweite von dir gepostete Code-Abschnitt) auf?

PS: Ich glaube der Setter von JTable#setRowSorter() hat den Seiteneffekt, sorter.sort() automatisch aufzurufen, sollte also nicht nötig sein.


----------



## André Uhres (12. Sep 2009)

Dein Code funktioniert bei mir, ausser dass du hier die zweite statt die erste Spalte angibst:

```
sortKeys.add(new RowSorter.SortKey(1, SortOrder.ASCENDING));
```


----------



## hdi (12. Sep 2009)

> ausser dass du hier die zweite statt die erste Spalte angibst



Dazu wollte ich vorher eh noch was sagen: Der Index für den SortKey bezieht sich aufs Model, nicht auf die View. Er sortiert also vielleicht schon nach der ersten Spalte, vielleicht aber auch nach der achten. Je nachdem wie man die Spalten vorher vertauscht hat mit der Maus. Die Frage ist also, woher er die 1 hat, (oder die 0 falls das ein Tippfehler war), und ob es wirklich das ist, was er will. Solange man keine Spalten hinzufügen oder löschen kann, ist es ja noch fehlerfrei, den Index als Magic Number reinzuschreiben (trotzdem nicht wirklich gut)


----------



## André Uhres (12. Sep 2009)

hdi hat gesagt.:


> Der Index für den SortKey bezieht sich aufs Model, nicht auf die View.


Richtig.


hdi hat gesagt.:


> Er sortiert also vielleicht schon nach der ersten Spalte


Der Satz kann einen unerfahrenen Leser verwirren, denn jetzt beziehst du dich trotz der vorigen Aussage auf die View, nicht aufs Model. Aber was du schreibst ist richtig .


----------



## Stinner (14. Sep 2009)

Morgen,
also die Angabe nach mit der ersten Spalte ist schon okay so. Habe ein eigenes TableModel was von AbstractTableModel erbt und die erste Spalte bezieht sich auf das Model.
Es soll default mäßig immer nach dieser Spalte sortiert werden, sie ist auch immer da und kann nicht gelöscht werden. Wenn sie verschoben wird, soll trotzdem nach ihr sortiert werden.

Ich rufe das Sortieren auch im TableModel auf. Die Variable datatable hält eine Referenz auf das angzeigte JTable und ich mache danach auch ein validate() auf das JScrollPane wo die JTable angezeigt wird. Funktioniert aber trotzdem nicht.
Gruß


----------



## hdi (14. Sep 2009)

Also nochmal, was willst du genau? Du willst, das beim Programmstart nach einer bestimmten Spalte sortiert ist, richtig? Und nach dieser Spalte soll immer sortiert werden, egal wie man die Spalten verschiebt? Und nach anderen Spalten soll man *nicht* sortieren können? Sprich ein Klick auf eine Spalte im Header soll nur auf der Spalte funktionieren, auf der sortiert wird (und dort eben die Sortier-Richtung ändern), aber auf allen anderen Spalten nix tun?
Hab ich das jetzt richtig verstanden?



> Jetzt will ich nach nachdem der Nutzer an der Table rumgespielt hat, die Table wieder nach der ersten Spalte sortieren.


Was meinst du mit "rumgespielt"? Das hatte ich ja vorher schon gefragt: Wann genau führst du den Code für diese Neu-Sortierung aus?


----------



## Stinner (15. Sep 2009)

Hi,
das mit dem Programmstart klappt schon. Da sortiere ich nach der ersten Spalte.

Jetzt ist es so:
Ich habe ein Filter für die Tabelle. Kann ausgewählt werden über RadioButtons. Allerdings läuft mein Filter so, dass ich die Daten im TableModel verändere - Sprich ich leses sie aus einer Datenbank aus.

Es ist halt so, nachdem ich einen Filter auswähle. dann ist die JTable unsortiert. Das heißt ich will die Sortierung aufrufen, nachdem ich meinen "Object" - Vector im TableModel verändert habe.
Das klappt leider nicht.
Es soll trotzdem noch für den Benutzer möglich sein, nach den anderen Spalten zu sortieren (Durch Doppelklick auf den Header), aber nach jeder Auswahl eines Filter soll zunächst mal nach der ersten Spalte sortiert werden.


Nochwas zu den Daten und was ich mit dem Filter meine. Habe verschiedene Artikelgruppen in der JTable dargestellt. Zu den Gruppen gehören mehrere Artikel.
Der Filter läuft über die Artikelgruppen. Je nachdem welche Gruppe dargestellt wird, werden unterschiedliche Attribute in der JTable angezeigt. Eine Seriennummer haben jedoch alle. Deshalb will ich immer die Daten zunächst nach ihr sortiert anzeigen.

Gruß , Felix


----------



## Michael... (15. Sep 2009)

Stinner hat gesagt.:


> Allerdings läuft mein Filter so, dass ich die Daten im TableModel verändere - Sprich ich leses sie aus einer Datenbank aus.
> 
> Es ist halt so, nachdem ich einen Filter auswähle. dann ist die JTable unsortiert. Das heißt ich will die Sortierung aufrufen, nachdem ich meinen "Object" - Vector im TableModel verändert habe


Wenn ich das richtig verstehe, liest Du die Daten bei jedem Filtern neu aus der Datenbank?!? Dann kannst Du die Daten ja gleich mit der gewünschten Sortieriung aus der Datenbank auslesen.


----------



## Stinner (15. Sep 2009)

hi,
könnte ich machen - würde allerdings lieber in der tabelle sortieren. dann sieht der nutzer auch (durch den pfeil) nch was sortiert ist


----------



## hdi (15. Sep 2009)

> Je nachdem welche Gruppe dargestellt wird, werden unterschiedliche Attribute in der JTable angezeigt. Eine Seriennummer haben jedoch alle. Deshalb will ich immer die Daten zunächst nach ihr sortiert anzeigen.


Heisst das also, dass du in deinem Table Spalten addest & removest? Wenn ja, möchte ich nochmal erwähnen, was ich ich ein paar Posts vorher schon gesagt hab, und was mir nach wie vor etwas strange vorkommt:

Du sortierst anfangs nach Index 0 im SortKey, und danach nach Index 1. Weisst du denn sicher, welcher Index für welche Spalte steht??

...wenn dem so ist, dann gibt es irgendwo in deiner Code-Logik ein Problem, denn dein Code:


```
TableRowSorter sorter = (TableRowSorter) datatable.getRowSorter();
List<RowSorter.SortKey> sortKeys = new ArrayList<RowSorter.SortKey>();
sortKeys.add(new RowSorter.SortKey(1, SortOrder.ASCENDING));
sorter.setSortKeys(sortKeys);
// sorter.sort(); nicht nötig
```

müsste funktionieren. _Exceptions bekommst du auch keine?_
Ansonsten zeig mal bitte Code-Ausschnitte, und präzisiere ab wann das Verhalten nicht mehr stimmt.

Ich vermute ja grad dass danach nochmal ein Event gefuert wird was deine sortKeys wieder über den Haufen wirft, oder du arbeitest hier auf 2 verschiedenen Tables/Models oder sowas in der Art. 
Und noch ne (ja, dumme, aber man will ja nix ausschließen xD) Frage am Rande: Was sind deine Seriennummern? Strings oder Zahlen?


----------



## Stinner (15. Sep 2009)

Die Seriennummern sind Strings. 
Aber das sollte ja keinen Unterschied machen, da es am Anfang ja immer klappt.

Ja, ich weiß immer wo die Seriennummer steht. Man kann zwar die Reihenfolge der Spalten ändern in der Applikation, aber die Seriennummer steht immer vorne.
Das oben stimmt nicht, beim zweiten mal ist der SortKey auch die Spalte 0.

Klappt trotzdem nicht, wüsste nicht, was ich noch posten soll. Was muss ich nach dem sortieren alles validieren? auch das JFrame?

Achso, keine Exceptions.


----------



## hdi (15. Sep 2009)

Naja irgendwo im Code muss nun mal etwas nicht stimmen, denn sonst würde es funktionieren. Das kannst du zB sehen an meinem Bsp eines Table mit mutliper Sortierung
(http://www.java-forum.org/entwuerfe/88240-jtable-mit-multipler-sortierung.html)

Da mache ich ja auch nix anderes als du, und es geht. Zeig mal deine Methode die aufgerufen wird wenn man auf so einen Radio-Button klickt um die Daten neu aus der Datenbank geholt werden.


----------



## KrokoDiehl (15. Sep 2009)

Kann es sein, dass du einfach am Ende deiner Sortierung ein 
	
	
	
	





```
fireTableDataChanged()
```
 (oder wie auch immer es genau heißt) aufrufen musst, damit deine JTable mitbekommt, dass sich ihr Datenmodell geändert hat?


----------



## hdi (15. Sep 2009)

fireTableDataChanged() muss er natürlich schon machen, aber das hat nichts mit der Sortierung zu tun. Und das muss auch nicht erst nach der Sortierung passieren. Er beschwert sich ja nicht darüber dass seine "Filterung" nicht funktioniert, von daher denke ich mal dass er das Model immer schön updaten wird.


----------



## Stinner (17. Sep 2009)

Hi,
konnte gestern nicht an dem Problem weiter arbeiten, aber bin heute wieder dran und es klappt immer noch nicht. Hoffe ihr gebt mir nochmal eure Hilfe
Poste mal meine ganze Methode:

```
public void filter(String filter) throws SQLException,
			EntryNotExistsException {

		if (filter.equalsIgnoreCase("All"))
			writeAll();
		else
			loadClassView(filter);

		JTable datatable;
		if (EntryWindow.getMainWindow().getContentPane() instanceof InitialPane) {
			datatable = ((InitialPane) EntryWindow.getMainWindow()
					.getContentPane()).getDatatable();
			TableRowSorter sorter = (TableRowSorter) datatable.getRowSorter();
			List<RowSorter.SortKey> sortKeys = new ArrayList<RowSorter.SortKey>();
			sortKeys.add(new RowSorter.SortKey(1, SortOrder.ASCENDING));
			sorter.setSortKeys(sortKeys);
			sorter.sort();
		}
		fireTableStructureChanged();
		fireTableDataChanged();
	}
```


Also, ein JPanel, in dem die JTable angezeigt wird. Daneben sind Radiobuttons an denen ein Listener hängt. Je nachdem welcher Radiobutton ausgewählt wird, wird die filter() Methode des TableModels aufgerufen mit dem entsprechenden Parameter.
In den Funktionen writeAll() und loadClassView(String Filter) werden die entsprechenden Daten aus der DB gelesen und der Data - Vector sowie der Colum-Vector überschrieben.
Danach soll gefilter werden. Klappt so aber nicht.
Habe Warnings, da ich den TableRowSorter nicht parametrisiert habe. Daran sollte es aber nicht liegen, dass der Code - Snippet nicht klappt?
Gruß


----------



## hdi (17. Sep 2009)

versuch mal die setSortKeys() Methode _nach_ den fire-Methoden des Models aufzurufen. Vllt wirft ja tableStructureChanged() die SortKeys über'n Haufen..

Ansonsten bau dir mal n paar sysouts in den code oder schmeiß den Debugger an. Liefert deine Methode mit der du "datatable" initialisierst auch wirklich deinen Table zurück? Und nicht vllt einen neuen oder sowas?
...und wird der if-Block überhaupt betreten?

das mit dem getContentPane() instanceof InitialPane find ich etwas strange. Hast du das ContentPane denn per Setter gesetzt? Normalerweise sollte man die Komponenten ja einfach darauf adden, und nicht das komplette Pane austauschen.


----------



## Stinner (17. Sep 2009)

hdi hat gesagt.:


> versuch mal die setSortKeys() Methode _nach_ den fire-Methoden des Models aufzurufen. Vllt wirft ja tableStructureChanged() die SortKeys über'n Haufen..



So klappt es endlich :toll:. Danke für deine Hilfe. 
Gruß


----------

