Java 在视口中保持JTable选择

Java 在视口中保持JTable选择,java,scroll,jtable,glazedlists,Java,Scroll,Jtable,Glazedlists,我使用GlazedList从事件列表自动生成一个EventTableModel,用于JScrollbarPane中的JTable 我将事件列表用作FIFO,在末尾添加一组元素,然后从开头删除一组元素。删除元素后,选择的工作方式与我预期的完全相同:即使选择的索引已更改,也会选择相同的元素(或至少选择仍在表中的元素)。太棒了 显然,如果对象由于在开始时删除项目而更改其索引,则不可能保持视口显示固定范围的对象和固定范围的索引。默认行为似乎是保持视口不变 如果要将选定对象保持在视口中的同一位置,有什么方

我使用GlazedList从事件列表自动生成一个EventTableModel,用于JScrollbarPane中的JTable

我将事件列表用作FIFO,在末尾添加一组元素,然后从开头删除一组元素。删除元素后,选择的工作方式与我预期的完全相同:即使选择的索引已更改,也会选择相同的元素(或至少选择仍在表中的元素)。太棒了

显然,如果对象由于在开始时删除项目而更改其索引,则不可能保持视口显示固定范围的对象和固定范围的索引。默认行为似乎是保持视口不变


如果要将选定对象保持在视口中的同一位置,有什么方法可以做到这一点?(例如,在EventTableModel或JScrollbarPane或其他东西上设置一个事件侦听器,并计算右滚动条设置,以便当我从一开始删除项目时,视口随对象一起移动?

如果我正确调用,JViewport使用JComponent上的一个方法 在Jtable中使用箭头键时,实际的滚动是哪个

public void scrollRectToVisible(Rectangle aRect)
这样,您就不需要调整滚动条,但您可以明确地说明什么rect应该是可见的。可能包括基于单行的行数和像素高度的一些计算。
您还可以在此方法中设置断点,并检查当使用箭头键在Jtable中移动时断点的工作方式。另一种显示Jtable中位于滚动窗格内的第一个选定行的方法是手动设置垂直滚动条显示的内容:

因此,首先,获取表中的第一个选定行。如果选择了多行,这仍然只会获取第一行

int firstSelectedRow = table.getSelectedRow();
然后,获取所选行在表中的位置(y坐标)

Rectangle cellLocation = table.getCellRect(firstSelectedRow, 0, false);
最后,我们可以告诉垂直滚动条在哪里

scrollPane.getVerticalScrollBar().setValue(cellLocation.y);
此外,如果没有选定的行,这将使视口显示表的顶部

Rectangle cellLocation = table.getCellRect(firstSelectedRow, 0, false);

我宁愿使用scrollRectToVisible()方法,但由于某种原因,它对我不起作用,而且似乎每次都能起作用

这是另一个仅取决于表格的解决方案。此解决方案还在新视图中保留选定行的y位置

首先,我们要存储更新前的视图和选择矩形

Rectangle preUpdateViewRect = table.getVisibleRect();
Rectangle preUpdateSelectedCellRect = table.getCellRect( table.getSelectedRow(), 1, true );
更新后,检查我们的选择是否在视图中。此检查确保如果用户选择一行并开始滚动,我们不会将视图捕捉回所选内容。如果所选内容在我们的视图中,请进行一些简单的数学运算,以创建矩形,使所选内容位于视图中的同一位置

if( preUpdateViewRect != null && preUpdateViewRect.contains( preUpdateSelectedCellRect ))
{
    Rectangle postUpadteSelectedCellRect = table.getCellRect( table.getSelectedRow(), 1, true );
    int newViewPortY = postUpdateSelectedCellRect.y - ( preUpdateSelectedCellRect.y - preUpdateViewRect.y );
    Rectangle newViewRect = new Rectangle( preUpdateViewRect.x, newViewPortY , preUpdateViewRect.width, preUpdateViewRect.height );
    table.scrollRectToVisible( newViewRect );
}