Why does my JTable sort an integer column incorrectly?
Try this little example.
The better way
As suggested by Kleopatra, defining a column class relevant for each, will be enough to get the data to be sorted correctly.
import javax.swing.*;
import javax.swing.table.*;
import java.util.Comparator;
class TableSorting {
public static void main(String[] args) {
Object[][] data = {
{new Integer(1), "Don't Let Go", new Integer(179)},
{new Integer(2), "Photograph", new Integer(29)},
{new Integer(3), "Hash Pipe", new Integer(186)},
{new Integer(4), "Island In The Sun", new Integer(200)},
{new Integer(5), "Crab", new Integer(154)},
{new Integer(6), "Knock-Down Drag-Out", new Integer(128)},
{new Integer(7), "Smile", new Integer(158)},
{new Integer(8), "Simple Pages", new Integer(176)},
{new Integer(9), "Glorious Day", new Integer(160)},
{new Integer(10), "O Girlfriend", new Integer(230)}
};
Object[] columns = {"Track #", "Title", "Length"};
DefaultTableModel model = new DefaultTableModel(data,columns) {
@Override
public Class getColumnClass(int column) {
switch (column) {
case 0:
return Integer.class;
case 1:
return String.class;
case 2:
return Integer.class;
default:
return String.class;
}
}
};
JTable table = new JTable(model);
JScrollPane scroll = new JScrollPane(table);
table.setAutoCreateRowSorter(true);
JOptionPane.showMessageDialog(null, scroll);
}
}
Original, using a comparator
import javax.swing.*;
import javax.swing.table.*;
import java.util.Comparator;
class TableSorting {
public static void main(String[] args) {
Object[][] data = {
{new Integer(1), "Don't Let Go", new Integer(179)},
{new Integer(2), "Photograph", new Integer(29)},
{new Integer(3), "Hash Pipe", new Integer(186)},
{new Integer(4), "Island In The Sun", new Integer(200)},
{new Integer(5), "Crab", new Integer(154)},
{new Integer(6), "Knock-Down Drag-Out", new Integer(128)},
{new Integer(7), "Smile", new Integer(158)},
{new Integer(8), "Simple Pages", new Integer(176)},
{new Integer(9), "Glorious Day", new Integer(160)},
{new Integer(10), "O Girlfriend", new Integer(230)}
};
Object[] columns = {"Track #", "Title", "Length"};
JTable table = new JTable(data, columns);
JScrollPane scroll = new JScrollPane(table);
DefaultTableModel model = new DefaultTableModel(data,columns);
TableRowSorter trs = new TableRowSorter(model);
class IntComparator implements Comparator {
public int compare(Object o1, Object o2) {
Integer int1 = (Integer)o1;
Integer int2 = (Integer)o2;
return int1.compareTo(int2);
}
public boolean equals(Object o2) {
return this.equals(o2);
}
}
trs.setComparator(0, new IntComparator());
table.setRowSorter(trs);
scroll = new JScrollPane(table);
table.setAutoCreateRowSorter(false);
JOptionPane.showMessageDialog(null, scroll);
}
}
Well, the docs for DefaultTableModel do state:
Warning: 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.
So it sounds like it's just going to be converting values to strings, which would be consistent with what you're seeing.
Have you tried either overriding getColumnClass()
or calling setComparator()
for the appropriate TableRowSorter
?
Here is the answer: Problems with JTable sorting of integer values
The idea is to define classes for columns.
myTable.setModel(new DefaultTableModel(Object[][] tableData, String[] columnsNames){
Class[] types = { Boolean.class, Boolean.class, String.class, String.class };
@Override
public Class getColumnClass(int columnIndex) {
return this.types[columnIndex];
}
});