Question

I have a JTable that is sortable by the column headers:

enter image description here

I would now like to only display the X first rows in the table. Have understood that the table sorting is not in the tableModel. I thought it would be a good idea to copy the JTable data to the Model and then just retrieve the first X elements. But it seems to fail. Any idea how to solve this task?

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;

public class SortJTable {

    public static void main(String[] args) {
        final String[] columns = getTableColumns();
        final Object[][] tableData = getTableValues();
        TableModel model = new DefaultTableModel(tableData, columns);

        final JTable table = new JTable(model);
        table.setAutoCreateRowSorter(true); // Make it possible to column-sort

        final JComboBox<String> box = new JComboBox<String>();
        box.addActionListener(new ActionListener(){

            @Override
            public void actionPerformed(ActionEvent e) {

                // TRY TO SORT THE MODEL AS THE TABLE
                for(int i=0; i<10; i++)
                    table.convertColumnIndexToModel(i);

                // IF MODEL IS SORTED AS TABLE: TAKE WANTED ELEMENTS
                Object[][] newModel;
                if(box.getSelectedIndex() == 0){
                    System.out.println("SHOW ALL");
                }
                else if(box.getSelectedIndex() == 1){
                    System.out.println("SHOW 5");

                    // CREATE NEW MODEL WITH ONLY 5 FIRST ELEMENTS FROM THE SORTED MODEL
                    newModel = new Object[5][10];
                    for(int col=0; col<tableData[0].length; col++){
                        for(int row=0; row<5; row++){
                            newModel[row][col] = tableData[row][col];

                            TableModel model = new DefaultTableModel(tableData, columns);
                            table.setModel(model);
                        }
                    }
                }
                else{
                    System.out.println("SHOW 10");
                }
            }
        });
        box.addItem("Show all rows");
        box.addItem("Show 5 first rows");
        box.addItem("Show 10 first rows");

        JPanel content = new JPanel();
        content.add(new JScrollPane(table));
        content.add(box);

        JFrame frame = new JFrame();
        frame.add(content);
        frame.pack();
        frame.setVisible(true);
    }

    private static String[] getTableColumns(){
        String[] columns = new String[10];
        for(int i=0; i<10; i++)
            columns[i] = "col"+i;
        return columns;
    }

    private static Object[][] getTableValues(){
        Object[][] tableData = new Object[10][10];
        for(int i=0; i<tableData.length; i++){
            for(int j=0; j<tableData[0].length; j++){
                tableData[i][j] = i+""+j;
            }
        }
        return tableData;
    }
}
Was it helpful?

Solution

This approach overrides the getRowCount() method of the JTable:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;

public class SortJTable {

    public static void main(String[] args) {
        final String[] columns = getTableColumns();
        final Object[][] tableData = getTableValues();
        TableModel model = new DefaultTableModel(tableData, columns);

        final JTable table = new JTable(model)
        {
            @Override
            public int getRowCount()
            {
                int rows = (int)getClientProperty("rows");

                if (rows == -1)
                    return getModel().getRowCount();
                else
                    return rows;
            }
        };
        table.setAutoCreateRowSorter(true); // Make it possible to column-sort

        final JComboBox<String> box = new JComboBox<String>();
        box.addActionListener(new ActionListener(){

            @Override
            public void actionPerformed(ActionEvent e)
            {
                if(box.getSelectedIndex() == 0)
                {
                    System.out.println("SHOW ALL");
                    table.putClientProperty("rows", new Integer(-1));
                }
                else if(box.getSelectedIndex() == 1)
                {
                    System.out.println("SHOW 5");
                    table.putClientProperty("rows", new Integer(5));

                }
                else
                {
                    System.out.println("SHOW 7");
                    table.putClientProperty("rows", new Integer(7));
                }

                table.revalidate();
                table.repaint();
            }
        });
        box.addItem("Show all rows");
        box.addItem("Show 5 first rows");
        box.addItem("Show 7 first rows");

        JFrame frame = new JFrame();
        frame.add(new JScrollPane(table));
        frame.add(box, BorderLayout.SOUTH);
        frame.pack();
        frame.setVisible(true);
    }

    private static String[] getTableColumns(){
        String[] columns = new String[10];
        for(int i=0; i<10; i++)
            columns[i] = "col"+i;
        return columns;
    }

    private static Object[][] getTableValues(){
        Object[][] tableData = new Object[10][10];
        for(int i=0; i<tableData.length; i++){
            for(int j=0; j<tableData[0].length; j++){
                tableData[i][j] = i+""+j;
            }
        }
        return tableData;
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top