This is my code:
import java.awt.*;
import javax.swing.*;
public class TableTest
{
public static void main(String[] args)
{
EventQueue.invokeLater(() ->
{
var frame = new PlanetTableFrame();
frame.setTitle("TableTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
});
}
}
class PlanetTableFrame extends JFrame
{
private String[] columnNames = { "Planet", "Radius", "Moons", "Gaseous", "Color" };
private Object[][] cells =
{
{ "Mercury", 2440.0, 0, false, Color.YELLOW },
{ "Venus", 6052.0, 0, false, Color.YELLOW },
{ "Earth", 6378.0, 1, false, Color.BLUE },
{ "Mars", 3397.0, 2, false, Color.RED },
{ "Jupiter", 71492.0, 16, true, Color.ORANGE },
{ "Saturn", 60268.0, 18, true, Color.ORANGE },
{ "Uranus", 25559.0, 17, true, Color.BLUE },
{ "Neptune", 24766.0, 8, true, Color.BLUE },
{ "Pluto", 1137.0, 1, false, Color.BLACK }
};
public PlanetTableFrame()
{
var table = new JTable(cells, columnNames);
table.setAutoCreateRowSorter(true);
add(new JScrollPane(table), BorderLayout.CENTER);
}
}
Running the program, when I click on the column header, the rows are automatically sorted.
I want to know why: when I click the column header, what happens inside the Swing component (what method is triggered)? I just clicked the table header and did not change the model content. Why does it automatically sort?
The necessary objects that are involved in table sorting are:
JTable
. No matter which JTable
constructor you call the effective constructor is JTable(TableModel, TableColumnModel, ListSelectionModel)
JTableHeader
. An object of this class is constructed when executing JTable.initializeLocalVars()
which is called from the JTable
constructorBasicTableHeaderUI
is constructed in the JTableHeader
constructor (during the call to JTableHeader.updateUI()
)BasicTableHeaderUI.MouseInputHandler
which handles mouse input for the BasicTableHeaderUI
. An instance of this class is constructed from the calls originating in JTableHeader.updateUI()
and is added as a mouse listener to the JTableHeader
TableRowSorter
- the JTable
creates an instance of this class when you call setAutoCreateRowSorter(true)
The BasicTableHeaderUI.MouseInputHandler.mouseClicked()
is the method that gets called when you click in the table header.
After some checks this method calls RowSorter.toggleSortOrder(int column)
which informs the TableRowSorter
that it should change the sorting.
Note that sorting the table doesn't sort the table model! The TableRowSorter
internally maintains two arrays to convert from (sorted) view row index to model row index and from model row index to (sorted) view row index.
In the unsorted state these arrays map index 0 to index 0, index 1 to index 1 etc.
When sorting these arrays are shuffled.
Final note: this post mentions the class BasicTableHeaderUI
. Depending on the LAF that your application uses it could be a different class (for example the WindowsTableHeaderUI
if your application uses the Windows LAF).