javasortingjtabletablerowsorter

Java TableRowSorter not sorting table rows correctly


I am using a TableRowSorter to sort a DefaultTableModel in my JTable. I have used the code

TableRowSorter<DefaultTableModel> sorter = new TableRowSorter<DefaultTableModel>(itemTableModel);

itemsTable.setRowSorter(sorter);

And when I click on the table column headers it does sort it, except not well. Lets say I have the column "Price", and I click on the header to have it sorted, it sorts some of the rows correctly but every now and then adds a row that should not be there. For example:

PRICE: (Ascending)

0.59
1.29
25.9
200.99 (not supposed to be here)
32.99
45
8.95 (also not supposed to fit there)

So basically what is happening here is that it is not sorting out the price properly. Even though it is supposed to sort in ascending order, it is not correct. How would I go about fixing this? If anyone has an answer if they could explain it that would be great.


Solution

  • A column is sorted according to the column’s class, which is defined by the model’s getColumnClass method.

    If you don’t override the getColumnClass method in your model, every column’s type is Object.class, which means its contents are sorted by their string forms.

    You will need to write a TableModel class which overrides the getColumnClass method.

    Typically, this is done by directly extending AbstractTableModel:

    public class ItemModel
    extends AbstractTableModel {
        private static final long serialVersionUID = 1;
    
        private final List<Item> items = new ArrayList<>();
    
        public void add(Item item) {
            items.add(item);
    
            int newRow = items.size() - 1;
            fireTableRowsInserted(newRow, newRow);
        }
    
        @Override
        public int getRowCount() {
            return items.size();
        }
    
        @Override
        public int getColumnCount() {
            return 2;
        }
    
        @Override
        public Object getValueAt(int row,
                                 int column) {
    
            Item item = items.get(row);
    
            switch (column) {
                case 0:
                    return item.getName();
                case 1:
                    return item.getPrice();
                default:
                    throw new IllegalArgumentException(
                        "Invalid column: " + column);
            }
        }
    
        @Override
        public String getColumnName() {
            switch (column) {
                case 0:
                    return "Name";
                case 1:
                    return "Price";
                default:
                    throw new IllegalArgumentException(
                        "Invalid column: " + column);
            }
        }
    
        @Override
        public Class<?> getColumnClass(int column) {
            switch (column) {
                case 0:
                    return String.class;
                case 1:
                    // Returning a class which implements/inherits Comprable
                    // will cause TableRowSorter to sort
                    // by comparing values directly.
                    return Double.class;
                default:
                    throw new IllegalArgumentException(
                        "Invalid column: " + column);
            }
        }
    }