views:

18

answers:

2

I have a JTable with a custom TableModel that extends AbstractTableModel. I have also used the built in table sorting by calling:

table.setAutoCreateRowSorter(true);

The model also return the right class of the data for each column from the getColumnClass() call, which from what I read should ensure the fastest sorting being done.

While it works fine and is indeed a very quick way to get sorting in your JTables its exceptionally slow when the number of rows reaches 5000+ entries. My table of almost 10000 rows now take 6-7 seconds to sort on a fairly powerful computer. But if I sort the data myself before adding them to the model using collections sort algorithm it is done in a few milliseconds!

I am suspecting the built in sorter is firing a lot of unecessary events for each "swap" of items going on in the sorter algorithm even though repainting is halted until its finished (the built in sorter is obviously run in the AWT thread and hence locks up the whole GUI/repainting). I have not analyzed this by looking at what is actually going on in the table sorting though.

I am tempted to drop the whole built-in sorter and just detect the column header clicks and just sort the model myself before doing a fireTableDataChanged() which is what the built in sorter should have done.

But before I do that, am I overlooking something that could make the built in sorter quick?

A: 

Have you tried using the GlazedLists library? Their support for JTable sorting works very well in my experience.

Barend
A: 

Works fine for me on a slow computer:

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

public class TableSort extends JFrame
{
    JTable table;
    DefaultTableModel model;

    public TableSort()
    {
        Random random = new Random();
        model = new DefaultTableModel(0, 2)
        {
            public Class getColumnClass(int column)
            {
                return Integer.class;
            }
        };

        for (int i = 0; i < 10000; i++)
        {
            Integer[] row = new Integer[2];
            row[0] = random.nextInt(100000);
            row[1] = random.nextInt(100000);
            model.addRow( row );
        }

        table = new JTable( model );
        table.setAutoCreateRowSorter(true);
        JScrollPane scrollPane = new JScrollPane( table );
        add( scrollPane );
        System.out.println(table.getRowCount());
    }

    public static void main(String[] args)
    {
        TableSort frame = new TableSort();
        frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
        frame.pack();
        frame.setVisible(true);
    }
}

Is the problem your custom model?

camickr
I think I might have found a cause to the problem yes and you were right that its a high chance that it is my custom model. Since the default table model does not have any built in filter I have implemented my own and it seems this mapping from visible row to actual row is exceptionally slow. I think I will have to rebuild the model to maintain two sets of rows so that I dont have to do this mapping.
Johncl