How to sort JTable on two columns so that items with "1" are at the top?

Suppose I have a JTable with lines like this:

(2, 1) (1, 3) (1, 5) (3, 1) (2, 3) (2, 4) 

I want to sort JTable so that rows that have 1 in the first or second column are at the top and the rest of the rows can be in random order:

  (1, 3) (1, 5) (2, 1) (3, 1) (2, 3) (2, 4) 

Is there a way to do this in a table with TableRowSorter ?

UPD : I want to sort the table programmatically, and not through the user interface (by clicking on the column headers)

+4
source share
4 answers

I figured out a way to do this without using TableRowSorter : you can nip data in the TableModel and then fire an event so that the table finds out that the data has changed. Here is the pseudo code:

Set up the table:

 AbstractTableModel model = new MyModel(); JTable table = new JTable(model); 

MyModel :

 public class MyModel implements AbstractTableModel { private ArrayList<Integer> data; ... // implement interface methods ... public void sortToTop(int a) { // float all rows w/ a in the first column to the top Collections.sort(data, new Comparator<Integer>() { public int compare(int o1, int o2) { if (o1 == a) return -1; if (o2 == a) return 1; return o1.compareTo(o2); } }); // find how many rows at the top have a in the first row int startIndex = 0; boolean notFound = true; while (startIndex < data.size() && notFound) { if (data.get(startIndex) == a) startIndex++; else notFound = false; } int endIndex = data.size(); // get a sublist w/o these first rows List<Integer> sublist = data.subList(startIndex, endIndex); // sort sublist on the second column floating a to the top Collections.sort(sublist, new Comparator<Integer>() { public int compare(int o1, int o2) { if (o1 == a) return -1; if (o2 == a) return 1; return o1.compareTo(o2); } }); this.fireTableDataChanged(); } } 
+1
source

You can define a Comparator for the first column using the setComparator method. Then, in the compare method in Comparator return -1 if the first argument is 1, 1 , if the second argument is 1 and 0 otherwise.

+1
source
  • Not that you are simply mistaken, and do not reinvent the wheels by adding one comparator integrated into the API with another comparator, other methods implement RowFilter, an example for RowFilter

enter image description here

enter image description here

enter image description here

enter image description here

from code

 import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.table.*; public class TableBoolean extends JFrame { private final static String LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; private static final long serialVersionUID = 1L; private JTable table; private DefaultTableModel model; public TableBoolean() { Object[][] data = {{"A", new Boolean(false), 2, 1}, {"B", new Boolean(true), 1, 3}, {"A", new Boolean(false), 1, 5}, {"B", new Boolean(true), 3, 1}, {"A", new Boolean(false), 2, 3}, {"B", new Boolean(true), 2, 4}, {"A", new Boolean(false), 5, 2}, {"B", new Boolean(true), 7, 1}}; String[] columnNames = {"String", "Boolean", "Integer", "Integer"}; model = new DefaultTableModel(data, columnNames) { private static final long serialVersionUID = 1L; @Override public Class getColumnClass(int column) { return getValueAt(0, column).getClass(); } @Override public boolean isCellEditable(int row, int column) { return true; } }; table = new JTable(model); TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(table.getModel()); table.setRowSorter(sorter); table.setPreferredScrollableViewportSize(table.getPreferredSize()); JScrollPane scrollPane = new JScrollPane(table); add(scrollPane); /*JButton button = new JButton("Add Row"); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { Object[] newRow = new Object[2]; int row = table.getRowCount() + 1; newRow[0] = LETTERS.substring(row - 1, row); newRow[1] = (row % 2 == 0) ? new Boolean(true) : new Boolean(false); model.addRow(newRow); } }); add(button, BorderLayout.SOUTH);*/ } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { TableBoolean frame = new TableBoolean(); frame.setDefaultCloseOperation(EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); } }); } } 
+1
source

The easiest way to do this, in my opinion, is to first call the sort in the second column, which will lead to something like this:

(3, 1)
(2, 1)
(thirteen)
(2, 3)
(2, 4)
(fifteen)

but it is not completed yet. If we then call the sort in the first column, then we will have:

(thirteen)
(fifteen)
(2, 1)
(2, 3)
(2, 4)
(3, 1)

This is the easiest way to do this.

0
source

Source: https://habr.com/ru/post/1400608/


All Articles