如何滚动到JTable中的最后一行

gd7*_*gd7 11 java swing scroll jtable

我试图以JTable新数据记录添加到最后的方式使用.奇怪的是滚动条没有到达表的末尾; 相反,它总是显示从最后一秒开始的第二个.有什么办法告诉滚动条总是到表的末尾?

这是我的代码的一部分:

table.scrollRectToVisible(table.getCellRect(table.getRowCount()-1, 0, true));
Run Code Online (Sandbox Code Playgroud)

Sam*_*Sam 17

我刚遇到这个问题 - 这行代码实际上并没有错; 问题在于你执行它.

如果你像我一样,在操作TableModel之后立即执行它(甚至通过invokeLater)或者使用TableModelListener,你将会遇到你正在描述的问题.问题是虽然模型已经使用新数据更新(table.getRowCount()只是对TableModel上的getRowCount()方法的传递),但JTable组件在视觉上没有.

当您在前面描述的位置执行该行代码时,您实际上是在尝试告诉JScrollPane(JTable.scrollRectToVisible将任何操作推迟到可以提供滚动行为的父级,例如JScrollPane)以滚动到封闭的JTable的末尾之外零件.它拒绝这样做,而是滚动到JTable组件的当前端.

稍后,JTable组件会以可视方式更新自身,并将新添加的行添加到之前滚动到的行的下方.您可以通过添加一个独立于添加新行的代码执行它的按钮来验证该行代码是否有效,例如

private JTable _table = new JTable();
...
JButton b = new JButton("Force scroll to bottom");
b.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) { 
        _table.scrollRectToVisible(_table.getCellRect(_table.getRowCount()-1, 0, true));
    }
});
this.add(b);
Run Code Online (Sandbox Code Playgroud)

这个问题的解决方案有点间接,但在我的测试中确实可靠.因为问题在于事物的视觉方面,所以我决定挂钩到ComponentListener,它提供了一个componentResized方法.无论何时添加或删除行,JTable都会调整大小,即使由于JScrollPane的视口而无法直观地看到它.因此,只需在该侦听器方法中运行该行代码,事情就会按预期工作.

private JTable _table = new JTable();
...
_table.addComponentListener(new ComponentAdapter() {
    public void componentResized(ComponentEvent e) {
        _table.scrollRectToVisible(_table.getCellRect(_table.getRowCount()-1, 0, true));
    }
});
Run Code Online (Sandbox Code Playgroud)