# Tabellenspalten als IntegerWert sortieren



## Guest (23. Aug 2007)

Hallo,

.setAutoCreateRowSorter(true)
sortiert die Tabellenspalten leider als String, und nicht als Integer.
1. Wie kann ich eine Tabellenspalte am einfachsten nach ihren Integerwerten sortieren? Ein Codebeispiel wär am besten.

2.Und wie funktioniert das konkret: "override getColumnClass" ?

DefaultTableModel returns a column class of Object. When DefaultTableModel is used with a TableRowSorter this will result in extensive use of toString, which for non-String data types is expensive. If you use DefaultTableModel with a TableRowSorter you are strongly encouraged to override getColumnClass to return the appropriate type.


----------



## martram (23. Aug 2007)

zu 2.)


```
public class ExampleModel extends DefaultTableModel{
	
	private static String columnNames[] = new String[]
	   {"IntegerColumn", "StringColumn", "BooleanColumn"};
	private Class[] columnClasses = new Class[]{Integer.class, String.class, 
			Boolean.class;
	
	public ExampleModel (int rowCount){
		super (columnNames,rowCount);		
	}
	public ExampleModel (){
		this(0);
	}
	
	@Override
	public Class getColumnClass(int columnIndex) {			
		return columnClasses[columnIndex];
	}
}
```

Dadurch kannst du z.B. auch die folgende Methode der JTable sinnvoll benutzen:
JTable#setDefaultRenderer(Class columnClass,TableCellRenderer renderer)
also in Abhängigkeit der Klasse in der column einen TableCellRender setzen. Ob du die ColumnClass nun zur Laufzeit bestimmen möchtest, oder wie oben im Beispiel fest vorgeben, bleibt dir überlassen.

Da ich #setAutoCreateRowSorter(true) nie benutzt habe, basiert das folgende auf Vermutungen: Wenn die Tabelle weiß, was in ihren Zellen ist (durch das überschreiben von #getColumnClass), wird sie wohl gleich den richtigen RowSorter benutzen. Ansonsten wird für jedes Objekt in der Tabelle die toString()-Methode aufgerufen und erst danach sortiert. (nach String-"Sortierung")


----------



## Guest (23. Aug 2007)

Danke erstmal.
Leider krieg ich aber compilerfehlermeldungen, kann mir jemand helfen?


```
private static String columnNames[] = new String[] {"IntegerColumn", "StringColumn", "BooleanColumn"};
```
the filed columnNames cannot be declared static;
static fields can only be declared in static or top level types

Wenn ich dass Wörtchen static aus der obigen Zeile entferne mekert er bezüglich columnNames wie folgt:

```
super (columnNames,rowCount);
```
cannot refer to an instance field columnNames while explicitly invoking a constructor


----------



## Guest (24. Aug 2007)

Und wie setze ich deine ExampeModel Klasse ein?
So: myTable.setModel(new ExampleModel()); ? So hab ichs jetzt jedenfalls gemacht.
Leider sortiert es irgendwie nicht meine Spalte mit den Integers? 

Hier mein Code:

```
@Override 
public Class getColumnClass(int columnIndex) {  
    if (columnIndex==3) { //meine 4te Spalte die Integerwerte enthält
        return Integer.class;
    } else return String.class;
}
```


Die Frage meines vorherigen Beitrags hat sich erledigt, ich kriege keine Compilerfehler wenn ich diese Zeile

```
private static String columnNames[] = new String[] {"IntegerColumn", "StringColumn", "BooleanColumn"};
```
über die public class ExampleModel Zeile schiebe


----------



## martram (24. Aug 2007)

Jau, ich hätte das Model als eigene Klasse (in einer eigenen Datei) benutzt. Selbstverständlich kannst du die Methode auch anderweitig überschreiben. (z.B. anonym)

Wenn du immer das selbe Model benutzt, kannst du es ja auch direkt dem Konstruktor der JTable übergeben.


```
TableModel t = new ExampleModel ();
//t.add(irgendwas)
JTable table = new JTable(t);

table.setAutoCreateRowSorter(true);
```

Hast du denn auch in der Tabelle in der GUI auf die richtige Spalte geklickt, damit sortiert wird? 



> This actions defines a row sorter that is an instance of javax.swing.table.TableRowSorter. This provides a table that does a simple locale-specific sort when the user clicks on a column header. This is demonstrated in TableSortDemo.java, as seen in this screen shot:


Quelle: http://java.sun.com/docs/books/tutorial/uiswing/components/table.html#sorting



> To determine which Comparator to use for a column, TableRowSorter attempts to apply each of the following rules in turn. Rules are followed in the order listed below; the first rule that provides the sorter with a Comparator is used, and the remainining rules ignored.
> 
> If a comparator has been specified by invoking setComparator, use that comparator.
> If the table model reports that the column data consists of strings (TableModel.getColumnClass returns String.class for that column), use a comparator that sorts the strings based on the current locale.
> If the column class returned by TableModel.getColumnClass implements Comparable, use a comparator that sorts the strings based on the values returned by Comparable.compareTo.



ansonsten: was machst du anders. Nen kleines Testprogramm, was die (Nicht-)Funktionalität zeigt, könnte bei der Fehlersuche helfen. Ich bin mir sicher, dass du ihn dann wahrscheinlich sogar selbst findest.


----------



## Guest (24. Aug 2007)

> Hast du denn auch in der Tabelle in der GUI auf die richtige Spalte geklickt, damit sortiert wird?


Ja.

So sortiert er bei mir meine Spalte mit integers:
103
107
15
865
85

Die Zahl sieht er also wohl immer noch als String an, schätz ich. Da er die Zahl nicht als ganzes nimmt, sondern hauptsächlich nach der ersten Zahlenstelle sortiert.




> To determine which Comparator to use for a column, TableRowSorter attempts to apply each of the following rules in turn. Rules are followed in the order listed below; the first rule that provides the sorter with a Comparator is used, and the remainining rules ignored.
> 
> If a comparator has been specified by invoking setComparator, use that comparator.
> If the table model reports that the column data consists of strings (TableModel.getColumnClass returns String.class for that column), use a comparator that sorts the strings based on the current locale.
> If the column class returned by TableModel.getColumnClass implements Comparable, use a comparator that sorts the strings based on the values returned by Comparable.compareTo.



Ja wie, dein Code hat also nicht gereicht, man muss noch einen Comparator oder sowas dazucoden?


----------



## martram (28. Aug 2007)

Nein, musst  du nicht, da die Klasse Integer bereits Comparable implementiert.

Wie bereits erwähnt, bis jetzt habe ich noch nie mit dieser Funktionalität der JTable gearbeitet - aus 2 Gründen:

1. Version 6 ist für mich noch nicht relevant, nutze 1.4 oder 5.
2. Setze ich meistens auf die JXTable.  :wink:
Hab' jetzt trotzdem mal 6 auf dem Laptop installiert, da ich mir nicht vorstellen kann, dass es nicht funktionieren soll. Deshalb kann ich jetzt feststellen: Du machst anscheinend etwas falsch. :wink:  In der schnell programmierten Demo funktioniert alles so, wie man es erwartet.


```
package de.toolforge.demo;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

/**
 * Simple demo UI class, which shows the use of the default RowSorter. (JDK 6)
 * @author mart (toolforge.de)
 */
public class TableRowsorterUIDemo extends JFrame{
	private DefaultTableModel model;
	
	public TableRowsorterUIDemo(){
		super("JTable Rowsorter demo");
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setLayout(new BorderLayout());
		
		JLabel topLabel = new JLabel("Demo UI - RowSorter");		
		add(topLabel, BorderLayout.NORTH);
		
		model = (DefaultTableModel) getTableModel();
		
		JTable table = new JTable(model);
		table.setAutoCreateRowSorter(true); 
		//This actions defines a row sorter that is an instance of 
		//javax.swing.table.TableRowSorter. This provides a table that does a simple 
		//locale-specific sort when the user clicks on a column header. 
		
		add(new JScrollPane(table));
		
		JButton addRowBt = new JButton ("add another row");
		addRowBt.setToolTipText("adds a new row to the table, " +
				"with a random integer and boolean value");
		addRowBt.addActionListener(new ActionListener(){

			public void actionPerformed(ActionEvent arg0) {
				Random r = new Random(); 
				// [url]http://java.sun.com/javase/6/docs/api/java/util/Random.html[/url]
				int randomInt = r.nextInt(); //random integer
				boolean randomBool = r.nextBoolean(); //random boolean
				
				model.addRow(new Object[]{randomInt, "Default add row", randomBool});
			}			
		});
		
		add(addRowBt, BorderLayout.SOUTH);	
	}
	
	private DefaultTableModel getTableModel() {
		ExampleModel model = new ExampleModel();
		model.addRow(new Object[]{new Integer(3), "String",new Boolean(true) });
		//zur Verdeutlichung mit new Integer und new Boolean.
		//for clarification, usage of new Integer and new Boolean
		
		//other test data
		model.addRow(new Object[]{103, "anderer String",false });
		model.addRow(new Object[]{15, "noch ein String",false });
		model.addRow(new Object[]{107, "...",true });
		model.addRow(new Object[]{85, "...",false });
		
		return model;
	}

	public static void main(String[] args) {
		JFrame m = new TableRowsorterUIDemo();
		m.pack();
		m.setVisible(true);
	}

}
```

Das bereits bekannte Model:

```
package de.toolforge.demo;

import javax.swing.table.DefaultTableModel;

public class ExampleModel extends DefaultTableModel{ 
    
	   private static String columnNames[] = new String[] 
	      {"IntegerColumn", "StringColumn", "BooleanColumn"}; 
	   private Class[] columnClasses = new Class[]{Integer.class, String.class, 
	         Boolean.class}; 
	    
	   public ExampleModel (int rowCount){ 
	      super (columnNames,rowCount);       
	   } 
	   public ExampleModel (){ 
	      this(0); 
	   } 
	   @Override
	   public Class getColumnClass(int columnIndex) {          
	      return columnClasses[columnIndex]; 
	   } 
	}
```

Wie zu erwarten, sortiert die Tabelle richtig, wenn man auf einen Spaltenheader klickt.


----------



## martram (28. Aug 2007)

edit: Doppelpost...


----------

