0
votes

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

2
For best help, please create and post a valid minimal reproducible example -- a small program, small enough to post in your question completely as code-formatted text, one that we can compile and run without modification, and that demonstrates your problem for us. - Hovercraft Full Of Eels
@HovercraftFullOfEels added MCVE - Ladence

2 Answers

1
votes

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);
            }
        });
    }

}
1
votes
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);