19

I was searching for Sorting in JTable and I referred many articles, but couldn't get the easiest way to sort the table. I also know that TableRowSorter could be somehow helpful but don't know how. Being new to JTable, I am creating a new question here.

My table structure is something like this

| People  | Place |   Organisation    | Event    | Mentions |
_____________________________________________________________
| Ramanuj | India | Tata Consultancy  | Party'14 |  500000  |
| Prankster | USA | Microsoft Pvt Ltd | Party'14 |  900000  |

What I want here is to sort my table Descending based on 4th column ("Mentions"). If counts (Mentions) are same, it should sort Ascending by 1st column ("People")

CSVReader reader = new CSVReader(new FileReader(file)); 

List<String[]> myEntries = reader.readAll();
String[][] rowData = myEntries.toArray(new String[0][]);

String[] columnNames = { "People", "Place", "Organisation", "Event", "Mentions" };

DefaultTableModel tableModel = new DefaultTableModel(rowData, columnNames);
mKorbel
  • 109,525
  • 20
  • 134
  • 319
Pratik
  • 367
  • 2
  • 4
  • 11

2 Answers2

40

As per How to Use Tables: Sorting and Filtering

JTable table = new JTable(tableModel);
TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(table.getModel());
table.setRowSorter(sorter);

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

Updated

Are you sure it will sort?

...Yes

Table

import java.awt.EventQueue;
import java.util.ArrayList;
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 Test {

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

    public Test() {
        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[]{"People", "Place", "Organisation", "Event", "Mentions"}, 0);
                model.addRow(new Object[]{"Prankster", "USA", "Microsoft Pvt Ltd", "Party'14", 900000});
                model.addRow(new Object[]{"Ramanuj", "India", "Tata Consultancy", "Party'14", 500000});
                model.addRow(new Object[]{"Banana", "India", "Tata Consultancy", "Party'14", 500000});

                JTable table = new JTable(model);
                TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(table.getModel());
                table.setRowSorter(sorter);

                List<RowSorter.SortKey> sortKeys = new ArrayList<>(25);
                sortKeys.add(new RowSorter.SortKey(4, SortOrder.ASCENDING));
                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);
            }
        });
    }

}

Updated

You can extract the data from the view directly...

 for (int row = 0; row < table.getRowCount(); row++) {
     String people = table.getValueAt(row, 0).toString();
     String place = table.getValueAt(row, 1).toString();
     String organisation = table.getValueAt(row, 2).toString();
     String event = table.getValueAt(row, 3).toString();
     int mentions = (int)table.getValueAt(row, 4);
     //...
 }

This will give you the data in the "view" (or sorted) order...

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Are you sure it will sort? Cause I tried just for my column 4, keeping DESCENDING, and checked TableModel. Its still same. Do I need to refresh or something? – Pratik Mar 03 '15 at 04:42
  • Yes. But beware, sorting a `String` (that represents a number) and sorting an actual number will give different results... – MadProgrammer Mar 03 '15 at 04:53
  • I am checking hovering on model variable. Its same there. Won't it reflect there? If not where can I see updated one? – Pratik Mar 03 '15 at 04:57
  • 1
    No, sorting is done at the view level ONLY, it does not affect the model at all, this is the point and a very important one – MadProgrammer Mar 03 '15 at 04:58
  • But I want to export updated Table in new csv. So how? – Pratik Mar 03 '15 at 04:59
  • Create a Plain Old Java Object (POJO) which is a representation of a single row of your data. Parse the CSV file, creating a POJO for each row, place them into a `List` of some kind and use `Collections.sort` to sort them, using a custom `Comparator`. See [Collections Trail](http://docs.oracle.com/javase/tutorial/collections/) for more details – MadProgrammer Mar 03 '15 at 05:01
  • Also, with respect, understand that your question is about how to sort a `JTable`, it didn't mention all these other requirements... – MadProgrammer Mar 03 '15 at 05:02
  • Arr... That's why I say, I don't find an easiest way :( Can you update your answer so that it can change sorting in model itself ? – Pratik Mar 03 '15 at 05:03
  • Not until you change the question so it asks the appropriate, detailing what it is you are trying to achieve and what it is you have tried... – MadProgrammer Mar 03 '15 at 05:11
  • With respect, I asked to sort the table, Didn't ask to make it sorted in just view part. If you can't please don't. – Pratik Mar 03 '15 at 05:20
  • 1
    And the table is sorted...The meaning of communication is defined by the receiver, with respect, if you can't ask a clear question, then don't expect a clear answer... – MadProgrammer Mar 03 '15 at 05:22
  • I was about to be thankful to you, but I feel people like you cant respect stackoverflow portal. Thanks for all your help. If you are here just to gain votes, here I can give to you. Bye. tc – Pratik Mar 03 '15 at 05:25
  • 5
    With all due respect, I can only answer the question that you ask. You made no mention that you wanted the data sorted or that you wanted to save the data after the fact until AFTER I had provided a answer. I would love to help you, but you need to understand that the answers MUST reflect the question, otherwise other people who might be looking for helping sorting a `JTable` may get the WRONG answer, because you've failed to provide appropriate context to the question. Before you start blaming other people, who are voluntarily trying to help, accept portion of the blame in the correct ratio – MadProgrammer Mar 03 '15 at 05:30
  • ps- I asked you to update THIS question to reflect your needs, not ask another one ;) – MadProgrammer Mar 03 '15 at 05:31
  • Thanks bro, but I just copied model data to new csv by looping. But thanks a lot for your help. You don't know how much time you saved of mine. Thanks again. :) – Pratik Mar 03 '15 at 06:41
  • If you can update the question a little, stating your want to sort the data/save it for later, I can add another way to sort the data... – MadProgrammer Mar 03 '15 at 06:46
  • Thanks bro for adding extra details :) – Pratik Mar 03 '15 at 07:40
  • I hope it all helps in some small way ;) – MadProgrammer Mar 03 '15 at 07:45
2

Try to use this

table.setAutoCreateRowSorter(true);
32cupo
  • 850
  • 5
  • 18
  • 36
  • 3
    Can you expand your answer a little bit, please? Maybe add some introductory text, a link to the JavaDoc and cite the relevant passage. Also formatting the example code would be nice (just add at least 4 spaces before each line of code). – DJDaveMark May 14 '20 at 14:02
  • 1
    (1-) This only allows the user to click on a column header to sort by the column. It does not automatically sort on the 4th column as per the requirement of this question. – camickr May 24 '21 at 14:38