如何滚动到 JTable 中的最后一行 [英] How to scroll to last row in a JTable

查看:44
本文介绍了如何滚动到 JTable 中的最后一行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试以将新数据记录添加到末尾的方式使用 JTable.奇怪的是滚动条没有走到表格的末尾;相反,它总是显示倒数第二个.有什么方法可以告诉滚动条总是走到表格的末尾?

I am trying to use JTable in the way where new data record are added to the end. The strange thing is the scroll bar does not go to the end of the table; instead, it always shows the second from the last. Any way to tell the scroll bar to always go to the end of the table?

这是我的代码的一部分:

Here is part of my code:

table.scrollRectToVisible(table.getCellRect(table.getRowCount()-1, 0, true));

推荐答案

我刚遇到这个问题——那行代码实际上没有任何问题;问题在于你何时执行它.

I just ran into this problem - there is actually nothing wrong with that line of code; the problem lies in when you execute it.

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

If you're, like me, trying to execute it immediately after manipulating the TableModel (even via invokeLater) or by using a TableModelListener, you'll get the problem you're describing. The problem is that while the model has been updated with the new data (table.getRowCount() is simply a pass-through to the getRowCount() method on your TableModel), the JTable component visually has not.

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

When you execute that line of code in the previously described places, you're actually trying to tell the JScrollPane (JTable.scrollRectToVisible defers any action to a parent that can provide scrolling behaviour, e.g. JScrollPane) to scroll beyond the end of the enclosed JTable component. It refuses to do that, and instead scrolls to the current end of the JTable component instead.

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

At some point later, the JTable component updates itself visually, and adds the newly added row underneath the row scrolled to earlier. You can verify that that line of code works by adding a button that executes it independently of the code that adds new rows, e.g.

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);

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

The solution to this problem is a little indirect, but does work reliably in my testing. Because the issue lies in the visual side of things, I decided to hook into the ComponentListener instead, which provides, among other things, a componentResized method. Whenever a row is added or removed, the JTable resizes, even if it cannot be seen visually due to the JScrollPane's viewport. Therefore just run that line of code in that listener method, and things will work as expected.

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

这篇关于如何滚动到 JTable 中的最后一行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆