Reputation: 27
I have a very simple JTable that I want to sort in ascending order by column 0. The code is very simple. But it is not able to sort the rows properly. I can not figure out what is wrong. Following is my code:
package test;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.RowSorter;
import javax.swing.SortOrder;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
public class TableSorter {
public static void main(String[] args) {
new TableSorter();
}
public TableSorter() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException |
IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
DefaultTableModel model = new DefaultTableModel(new String[] {"X", "Y", }, 0);
model.addRow(new Object[]{5, 8});
model.addRow(new Object[]{10, 5});
model.addRow(new Object[]{50, 60});
model.addRow(new Object[]{100, 60});
JTable table = new JTable(model);
TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(table.getModel());
table.setRowSorter(sorter);
List<RowSorter.SortKey> sortKeys = new ArrayList<>();
sortKeys.add(new RowSorter.SortKey(0, SortOrder.ASCENDING));
sorter.setSortKeys(sortKeys);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(table));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
Here is the result when I run the program
Results:
X y
10 5
100 60
5 8
50 60
Any help will be appreciated. The result is attached. Thanks in advance.
Upvotes: 0
Views: 1782
Reputation: 14238
From the documentation of DefaultTableModel :
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.
You need to override getColumnClass of your table model like :
DefaultTableModel model = new DefaultTableModel(new String[] {"X", "Y", }, 0)
{
@Override
public Class<?> getColumnClass(int column)
{
Class<?> returnValue;
if ((column >= 0) && (column < getColumnCount()))
{
returnValue = getValueAt(0, column).getClass();
}
else
{
returnValue = Object.class;
}
return returnValue;
};
};
In your case it is comparing Integer.toString()
on integers and hence the wrong order that you see.
By overriding getColumnClass()
to return Integer
type, you will get comparison of integers by their values.
Upvotes: 1