Numerische Sortierung in JTable


#1

Hallo,

ich schaffe es nicht, in meiner JTable die erste Spalte numerisch sortiert zu bekommen. Die gelieferte Sortierung ist immer 1,10,11,2,3,4,44,45…
obwohl ich die erste Spalte im Model entsprechend als Integer Wert berücksichtigt habe.

			 @Override
			    public boolean isCellEditable(int row, int column) {
			       //all cells false
			       return false;
			    }
			   @Override
	            public Class<?> getColumnClass(int columnIndex) {
				 
	                if (columnIndex == 0) {
	                	
	                    return Integer.class;
	                }
	                // TODO Auto-generated method stub
	                return super.getColumnClass(columnIndex);
	                
	            }
		
		};
		
		
		
		
		TableRowSorter sorter = new TableRowSorter<DefaultTableModel>(model);
		setTable(new JTable(model));		
		getTable().getTableHeader().setReorderingAllowed( true );
		getTable().getTableHeader().setResizingAllowed( true );
		getTable().setAutoCreateRowSorter(false);
		getTable().setRowHeight(20);
		
		getTable().setRowSorter(sorter);```

Weiss jemand Rat?

GGK

#2

was spricht gegen ein vollständiges Testprogramm?
und zumindest in meiner bisherigen Sichtweise ist Tabellen-Sortierung kein richtiges Standard-Feature,
welchen Code, welches Framework verwendest du dafür denn grundsätzlich?

Suchmaschine führt mich zu TableRowSorter? (edit: oh, weiter unten im Code zu sehen :wink: )
ab Java 6, das kenne ich dann freilich nicht so gut :wink:
http://openbook.galileocomputing.de/javainsel9/javainsel_19_019.htm#mja6e89fe02669f01b7bd5b44b5331f5d0

19.19.10 Automatisches Sortieren und Filtern mit RowSorter
[…]
Starten wir das Programm, ist schon eine Sortierung eingebaut, allerdings nur auf String-Ebene, sodass etwa »19« < »2« < »20« ist. Mit einem Klick auf die Kopfzeile der Tabelle zeigt ein kleiner Pfeil die Sortierrichtung an.
[…]
Da der RowSorter standardmäßig die Inhalte als String sortiert, wollen wir im nächsten Beispiel für die erste Spalte einen Comparator deklarieren, der nach der Anzahl der gesetzten Bits geht:
[…]

ist das was für dich? allerdings ist da auch das Model so schlecht, dass es nur Strings liefert…

ein vollständiges Testprogramm könnte genauer zeigen ob alles abgedeckt ist (edit: welche Daten sind in den Rows, das fehlt noch),
ob ich dabei mithelfen es zu testen kann und will falls Java 6, weiß ich noch nicht recht

ist übrigens ein Swing-Thema, ruhig aufpassen mit den Areas im Forum,
es geht nicht nach Kompliziertheit, sondern nach Thema,
verschoben


#3

Mit dem Standard RowSorter getTable().setAutoCreateRowSorter(true); das selbe Problem?

…am Verhalten wird sich vermutlich nichts ändern.
Die getColumnClass des TableModels ist nur für Renderer und Editor relevant. Der RowSorter orientiert sich daran, was das Objekt in der Zelle tatsächlich ist. Vermutlich ist es in Deinem Fall ein String oder zumindest liefert Dein TableModel einen String in der getValueAt() für diese Spalte. --> Damit die Spalte wie Zahlen sortiert wird, muss das TableModel auch Zahlen liefern.


#4

danke…das war der Hinweis…

Ich habe beim Befüllen der Tabelle den String in einen Integer-Datentyp konvertiert.

GGK


#5

Die TableRowSorter Doku ist da recht ausführlich:

TableRowSorter uses Comparators for doing comparisons. The following defines how a Comparator is chosen for a column:

  1. If a Comparator has been specified for the column by the setComparator method, use it.
    2 .If the column class as returned by getColumnClass is String, use the Comparator returned by Collator.getInstance().
  2. If the column class implements Comparable, use a Comparator that invokes the compareTo method.
  3. If a TableStringConverter has been specified, use it to convert the values to Strings and then use the Comparator returned by Collator.getInstance().
  4. Otherwise use the Comparator returned by Collator.getInstance() on the results from calling toString on the objects.

Eine von mehreren Möglichkeiten ist also

		TableRowSorter<TableModel> sorter = 
			new TableRowSorter<TableModel>(table.getModel());
		sorter.setComparator(3, new Comparator<Integer>() {
			@Override
			public int compare(Integer o1, Integer o2) {
				return o1 - o2;
			}
		});
		table.setRowSorter(sorter);

Oder eingebaut in die “SimpleTableDemo” aus http://docs.oracle.com/javase/tutorial/uiswing/components/table.html :

import java.awt.Dimension;
import java.awt.GridLayout;
import java.util.Comparator;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

public class SimpleTableDemo extends JPanel {

	public static void main(String[] args) {
		javax.swing.SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				createAndShowGUI();
			}
		});
	}
	private static void createAndShowGUI() {
		JFrame frame = new JFrame("SimpleTableDemo");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		SimpleTableDemo newContentPane = new SimpleTableDemo();
		newContentPane.setOpaque(true);
		frame.setContentPane(newContentPane);
		frame.pack();
		frame.setVisible(true);
	}

	public SimpleTableDemo() {
		super(new GridLayout(1, 0));

		String[] columnNames = { "First Name", "Last Name", "Sport",
			"# of Years", "Vegetarian" };

		Object[][] data = {
			{ "Kathy", "Smith", "Snowboarding", new Integer(5), new Boolean(false) },
			{ "John", "Doe", "Rowing", new Integer(3), new Boolean(true) },
			{ "Sue", "Black", "Knitting", new Integer(2), new Boolean(false) },
			{ "Jane", "White", "Speed reading", new Integer(20), new Boolean(true) },
			{ "Joe", "Brown", "Pool", new Integer(10), new Boolean(false) } };

		final JTable table = new JTable(data, columnNames);
		table.setPreferredScrollableViewportSize(new Dimension(500, 70));
		table.setFillsViewportHeight(true);

		TableRowSorter<TableModel> sorter = 
			new TableRowSorter<TableModel>(table.getModel());
		sorter.setComparator(3, new Comparator<Integer>() {
			@Override
			public int compare(Integer o1, Integer o2) {
				return o1 - o2;
			}
		});
		table.setRowSorter(sorter);

		JScrollPane scrollPane = new JScrollPane(table);
		add(scrollPane);
	}


}