Ladence
Ladence

Reputation: 244

Sorting JTable after adding rows

I have to sort JTable (Object[][] data, Object[] headers) after adding new row.

Here is the code (doesn't work)

public class Window extends JFrame {
    Window() {
        super();
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        JTable table = new JTable();
        table.setModel(new DefaultTableModel(null, new String[]{"col1"}));
        TableRowSorter<TableModel> sorter = new TableRowSorter<>(table.getModel());
        sorter.setComparator(0, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);
            }
        });
        sorter.setSortsOnUpdates(true);
        table.setRowSorter(sorter);

        DefaultTableModel model = (DefaultTableModel)table.getModel();
        model.addRow(new String[] {"A"});
        model.addRow(new String[] {"C"});
        model.addRow(new String[] {"B"});

        this.getContentPane().add(table);
        pack();
        setVisible(true);
    }

    public static void main(String[] args) {
        new Window();
    }
}

Output result : table (A, C, B) , expected (A, B, C)

model - DefaultTableModel
deviceTable - Jtable

Upvotes: 0

Views: 3084

Answers (2)

camickr
camickr

Reputation: 324197

model.fireTableDataChanged();

Don't invoke the fireXXX() methods directly.

It is the responsibility of thehe TableModel will invoke the appropriate method (which in this case would be fireTableRowsInserted).

Edit:

Get rid of the code that creates the sorter and the Comparator.

You just let the table create the sorter. But then once you do this you need to tell the sorter which column to sort:

table.setAutoCreateRowSorter(true);
((DefaultRowSorter)table.getRowSorter()).toggleSortOrder(0);

Upvotes: 1

MadProgrammer
MadProgrammer

Reputation: 347334

Based on your example, you need to define a sort key, otherwise the table is effectively unsorted...

List<RowSorter.SortKey> sortKeys = new ArrayList<RowSorter.SortKey>();
sortKeys.add(new RowSorter.SortKey(0, SortOrder.ASCENDING));
sorter.setSortKeys(sortKeys);
table.setRowSorter(sorter);

The following example (based on yours), sorts the first column. When you tap the button, it adds the rows, which are then sorted

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.RowSorter;
import javax.swing.SortOrder;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                JTable table = new JTable();
                table.setModel(new DefaultTableModel(null, new String[]{"col1"}));
                TableRowSorter<TableModel> sorter = new TableRowSorter<>(table.getModel());
                sorter.setComparator(0, new Comparator<String>() {
                    @Override
                    public int compare(String o1, String o2) {
                        return o1.compareTo(o2);
                    }
                });
                sorter.setSortsOnUpdates(true);
                List<RowSorter.SortKey> sortKeys = new ArrayList<RowSorter.SortKey>();
                sortKeys.add(new RowSorter.SortKey(0, SortOrder.ASCENDING));
                sorter.setSortKeys(sortKeys);
                table.setRowSorter(sorter);

                JButton btn = new JButton("...");
                btn.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        DefaultTableModel model = (DefaultTableModel) table.getModel();
                        model.addRow(new String[]{"A"});
                        model.addRow(new String[]{"C"});
                        model.addRow(new String[]{"B"});
                    }
                });

                frame.add(new JScrollPane(table));
                frame.add(btn, BorderLayout.SOUTH);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

}

Upvotes: 1

Related Questions