# JTable nach mehreren Spalten sortieren



## Enton (10. Nov 2009)

Hallo,
ich habe eine JTable und möchte sie nach mehreren Spalten sortieren. Die Sortierung funktioniert auch, wenn ich es per Hand mit Klick auf die Spaltenköpfe durchführe. Der folgende Aufruf sortiert mir leider nur nach der ersten Spalte (Index 0).


```
List <RowSorter.SortKey> sortKeys 
	    = new ArrayList<RowSorter.SortKey>();
		sortKeys.add(new RowSorter.SortKey(0, SortOrder.ASCENDING));
		sortKeys.add(new RowSorter.SortKey(3, SortOrder.ASCENDING));
		rowSorter.setSortKeys(sortKeys);
```

wie sortiere ich mit zweiter Priorität nach der Spalte 4 (Index 3)?


----------



## Michael... (10. Nov 2009)

Enton hat gesagt.:


> Hallo,
> ich habe eine JTable und möchte sie nach mehreren Spalten sortieren. Die Sortierung funktioniert auch, wenn ich es per Hand mit Klick auf die Spaltenköpfe durchführe. Der folgende Aufruf sortiert mir leider nur nach der ersten Spalte (Index 0).
> 
> 
> ...


Keine Ahnung wie die SortKeys intern abgearbeitet werden, aber ändere doch mach die Reihenfolge. Ich nehme mal an, dass das Model beim Sortieren die Liste von vorne nach hinten durch arbeitet.

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


----------



## Enton (10. Nov 2009)

Hallo,
die Sortierreihenfolge ist so schon richtig, wenn ich es tausche sortiert er nach der vierten Spalte aber anschließend wieder nicht nach der ersten. 
Das Problem ist also erstmal nur, nach mehreren Spalten zu sortieren, die richtige Reihenfolge bekomme ich dann schon hin.


----------



## Michael... (10. Nov 2009)

Enton hat gesagt.:


> die Sortierreihenfolge ist so schon richtig, wenn ich es tausche sortiert er nach der vierten Spalte aber anschließend wieder nicht nach der ersten.


?? Also sortiert er doch noch mehreren Spalten ?? Sortieren geht immer nur sequenziell. Ich nehme mal an, dass die Sortierung der vierten Spalte beim Sortieren der ersten Spalte beibehalten wird, sofern diese nicht der letztern widerspricht!? Muss allerdings zugeben noch nie mit dem RowSorter gearbeitet zu haben, da ich das bisher immer selbst implementiert habe.


----------



## Enton (10. Nov 2009)

Ich möchte, dass er nach mehreren Spalten sortiert. Also dass die Sortierung der vierten Spalte beibehalten bleibt, wenn ich anschließend nach der ersten sortiere. Zur Zeit scheint die zweite Sortierung nicht ausgeführt zu werden. Wenn ich es per Hand in der Tabelle mache funktioniert es problemlos.


----------



## Michael... (10. Nov 2009)

Ab jetzt muss ich passen:bahnhof: Habe hier leider kein 1.6 sonst hätte ich es mal schnell ausprobiert.


----------



## Enton (10. Nov 2009)

Schade, trotzdem Danke!


----------



## Enton (17. Nov 2009)

Hallo nochmal,
hat inzwischen vielleicht jemand eine Idee? Verzweifle gerade ein bisschen an dem Problem. Gibt es ansonsten noch andere Möglichkeiten um eine Tabelle nach mehreren Spalten zu sortieren? Geht das z.B. mit Collections.sort() ? Wie?
Danke


----------



## Marco13 (17. Nov 2009)

Wenn man die TableSortDemo von Sun so macht

```
public TableSortDemo() {
        super(new GridLayout(1,0));

        TableModel model = new MyTableModel();
        JTable table = new JTable(model);
        table.setPreferredScrollableViewportSize(new Dimension(500, 70));
        table.setFillsViewportHeight(true);

        List <RowSorter.SortKey> sortKeys
            = new ArrayList<RowSorter.SortKey>();
        sortKeys.add(new RowSorter.SortKey(2, SortOrder.ASCENDING));
        sortKeys.add(new RowSorter.SortKey(3, SortOrder.DESCENDING));
        TableRowSorter sorter = new TableRowSorter(model);

        sorter.setSortKeys(sortKeys);
        table.setRowSorter(sorter);

        //Create the scroll pane and add the table to it.
        JScrollPane scrollPane = new JScrollPane(table);

        //Add the scroll pane to this panel.
        add(scrollPane);
    }
```

und mehrfach z.B. "Snowboarding" einsetzt, scheint's zu gehen. Poste ein KSKB wo das Problem auftritt.


----------



## Enton (17. Nov 2009)

Hi,
ich habe ein KSKB geschrieben. Das Problem scheint wohl bei den Comparatoren zu liegen. Wenn ich nur Integer-Werte eingeben, funktioniert das sortieren nach beiden Spalten. Das Problem ist dann aber, dass (1, 2, 12) als (1, 12, 2) sortiert würden (also nach der ersten Ziffer).
Hier das Beispielprogramm:


```
import java.awt.BorderLayout;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.RowSorter;
import javax.swing.SortOrder;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableRowSorter;

public class PlaeneFenster extends JFrame {
	private DefaultTableModel gruppenPlanData;
	private JTable gruppenPlan;
	/**
	 * Konstruktor
	 */
	public PlaeneFenster(){
		draw();
	}
	public void draw(){
		//Layout des Fensters setzen
		getContentPane().setLayout(new BorderLayout());
		//TabbedPane zum verwalten der Reiter
		JTabbedPane alleReiter = new JTabbedPane();
				
		//GruppenPlanPanel
		JPanel gruppenPlanPanel = new JPanel();
		gruppenPlanPanel.setLayout(null);

		gruppenPlanData = new DefaultTableModel();
		gruppenPlanData.addColumn("Kleingruppe(Nr, Klassenname)");
		gruppenPlanData.addColumn("Startzeitpunkt");
		gruppenPlan = new JTable(gruppenPlanData);
		gruppenPlanPanel.add(gruppenPlan);
		
		TableRowSorter<DefaultTableModel> rowSorter = new TableRowSorter<DefaultTableModel>( gruppenPlanData );
		gruppenPlan.setRowSorter(rowSorter);
		//sortiert den Gruppenplan nach Gruppennummern und Startzeiten
		List <RowSorter.SortKey> sortKeys 
	    = new ArrayList<RowSorter.SortKey>();
		rowSorter.setComparator(0, new MyComparator());
		rowSorter.setComparator(1, new MyComparator2());
		sortKeys.add(new RowSorter.SortKey(0, SortOrder.ASCENDING));
		sortKeys.add(new RowSorter.SortKey(1, SortOrder.ASCENDING));
		rowSorter.setSortKeys(sortKeys);
		
		JScrollPane scrollpaneE = new JScrollPane(gruppenPlan);
		gruppenPlanPanel.add(scrollpaneE);
		scrollpaneE.setBounds(20, 40, 960, 500);
		
		//alle Reiter integrieren
		alleReiter.addTab("Kleingruppenpläne", gruppenPlanPanel);
		getContentPane().add(alleReiter,BorderLayout.CENTER);
		setSize(1000, 700);
		setVisible(true);	
	}
	
	/**
	 * Fülle Tabelle mit aussagekräftigen Werten
	 */
	public void fensterFuellen(){				
					Object data [] ={"1 (2a)",40};
					gruppenPlanData.addRow(data);
					Object datab [] ={"2 (3c)",16};
					gruppenPlanData.addRow(datab);
					Object datac [] ={"1 (2a)",46};
					gruppenPlanData.addRow(datac);
					Object datad [] ={"1 (2a)",16};
					gruppenPlanData.addRow(datad);
	}
	
	//Eigener Comparator für die erste Spalte
	private class MyComparator implements Comparator<String> {
		public int compare( String i, String j ) {
	        if(Integer.parseInt(i.split(" ")[0]) <= Integer.parseInt(j.split(" ")[0]) )
	            return -1;
	        else if( Integer.parseInt(i.split(" ")[0]) > Integer.parseInt(j.split(" ")[0]) )
	            return 1;
	        else
	            return 0;
	    }
    }
	//eigener Comparator für die 2 Spalte
	private class MyComparator2 implements Comparator<Integer> {
		 public int compare( Integer i, Integer j ) {
		        if( i <= j )
		            return -1;
		        else if(i > j)
		            return 1;
		        else
		            return 0;
		    }
    }
public static void main(String[] args) {	
		PlaeneFenster plan = new PlaeneFenster();
		plan.fensterFuellen();
	}
}
```

Ich würde mich sehr über ein wenig Hilfe freuen.
Danke im voraus.


----------



## Michael... (17. Nov 2009)

Vom Comparator her sollte es eigentlich passen.
Allerdings würde ich bei sowas empfehlen eine eigenes Objekt zu schreiben das z.B. die Zahl und den Text in jeweils einer Variablen speichert. --> geht einfacher zu vergleichen


----------



## Enton (17. Nov 2009)

Ich habe es mit und ohne eigenen Comparator getestet. Ohne eigenen Comparator funktioniert die Sortierung (die Reihenfolge ist nur leider nicht die Gewünschte). Sobald ich einen eigenen Comparator habe (den brauche ich in jedem Fall, da auch Integer nicht richtig sortiert werden) funktioniert es dann leider nicht mehr. 
Ich habe gerade auch nochmal ausprobiert immer den gleichen (eigenen Comparator) zu nehmen, dann funktioniert es ebenfalls. Das Problem scheint also zu sein, zwei unterschiedliche Comparatoren zu haben. Kann man die irgendwie zusammenfassen, obwohl die Einträge nicht vom gleichen Typ sind?
Ich wäre dankbar über einen hilfreichen Ratschlag.
Danke!


----------



## Marco13 (18. Nov 2009)

Mein Ratschlag: Schau mal, ob in der Zeile

```
if(Integer.parseInt(i.split(" ")[0]) <= Integer.parseInt(j.split(" ")[0]) )
```
nicht ein Fehler sein könnte ... ... ...


----------



## Enton (18. Nov 2009)

Hallo,
der Comperator funktioniert meiner Ansicht nach richtig. Ich hab nochmal die Werte die verglichen werden ausgegeben und die sind richtig. Was meinst du denn, das anders müsste? 
Ich habe die Tabelle nun so umstrukturiert, dass die Spalten, die sortiert werden nur Integer-Werte enthalten. Somit brauche ich nur noch einen Comperator und es funktioniert. 
Das ist jetzt zwar keine elegante Lösung aber immerhin funktioniert es. 
Falls jemand noch eine bessere Lösung findet, wäre ich daran nach wie vor sehr interessiert.
Vielen Dank für eure Hilfe und bis zum nächsten Mal...


----------



## Marco13 (18. Nov 2009)

Statt
[c]if(Integer.parseInt(i.split(" ")[0]) <= Integer.parseInt(j.split(" ")[0]) )[/c] müßte es
[c]if(Integer.parseInt(i.split(" ")[0]) <  Integer.parseInt(j.split(" ")[0]) )[/c] lauten...


----------

