为何点击Swing表格表头会自动排序?内部触发机制解析
Swing表格表头点击的内部机制与排序原理
示例代码
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); } }
问题
运行程序后点击列表头,行会自动排序,想了解:
- 点击列表头时,Swing组件内部会触发哪些方法?
- 仅点击表头并未修改模型内容,为何会自动排序?
回答
一、点击表头时内部触发的核心方法流程
JTableHeader捕获鼠标点击事件,调用自身的mouseClicked(MouseEvent e)方法- 通过
getColumnModel().getColumnIndexAtX(e.getX())计算出点击的列索引 - 调用关联
JTable实例的getRowSorter()方法,获取自动创建的TableRowSorter对象 TableRowSorter执行toggleSortOrder(int column)方法,切换该列的排序状态(升序→降序→取消排序循环)- 根据列对应的数据类型,
TableRowSorter生成或获取对应的Comparator,完成排序逻辑计算 - 最后
TableRowSorter调用fireSortOrderChanged(),通知JTable视图更新行的显示顺序
二、未修改模型却能排序的原因
Swing的JTable采用模型-视图分离的设计模式:
- 底层
TableModel存储的是原始、未排序的数据,这部分数据不会因为表头点击被修改 - 启用
setAutoCreateRowSorter(true)后,自动创建的TableRowSorter会维护一个行索引映射关系——把模型中的原始行索引,映射成视图需要显示的排序后行索引 - JTable渲染表格时,会根据
TableRowSorter提供的映射关系,从TableModel中取出对应位置的数据展示,所以看起来行是排序后的,但原始模型数据完全没动
内容的提问来源于stack exchange,提问作者Kk Lee
相关产品推荐
相关产品推荐

