Java 带JTable和JScroll窗格的滚动锁

Java 带JTable和JScroll窗格的滚动锁,java,swing,locking,jtable,jscrollpane,Java,Swing,Locking,Jtable,Jscrollpane,我有一个JTable,它是使用创建的,位于JScrollPane中。EventTableModel从eventList中获取实时更新,并在表中显示结果。当新结果进入表格时,新信息将显示在表格顶部 但是,我想做的是冻结表格,以便在按下名为“锁定表格”的按钮时显示当前显示的内容。此按钮应具有与eclipse控制台“滚动锁定”相同的效果,因此,当新项目出现时,当前项目应保留在屏幕上,而不是在新项目出现时被按下。但新项目仍应添加,只是不能自动滚动到 有人知道我如何尝试实现此功能吗。因此,当更新进入时,表

我有一个JTable,它是使用创建的,位于JScrollPane中。EventTableModel从eventList中获取实时更新,并在表中显示结果。当新结果进入表格时,新信息将显示在表格顶部

但是,我想做的是冻结表格,以便在按下名为“锁定表格”的按钮时显示当前显示的内容。此按钮应具有与eclipse控制台“滚动锁定”相同的效果,因此,当新项目出现时,当前项目应保留在屏幕上,而不是在新项目出现时被按下。但新项目仍应添加,只是不能自动滚动到

有人知道我如何尝试实现此功能吗。因此,当更新进入时,表上的数据不会被强制移出屏幕,因此当按下复选框时,焦点将保持在当前数据上

谢谢你的帮助。 Michael

基本程序(用于在当前显示区域上方插入)

  • 在表的模型上安装TableModelListener
  • 启用锁定:注意当前可见矩形下方的行数
  • 在锁定时接收插入时,滚动以使下面的行数保持不变
一些工作代码(使用JXTable,因为它有方便的滚动方法,对于核心表,只需自己进行计算:-)


这种方法的问题是,表跳转,行不固定。是否仍要确保行添加到上面,当前表字段保留在屏幕上,但其他表行添加到上面。
public static class ScrollLock {
    private JXTable table;
    private boolean blocked;
    private int rowsBelow;

    public ScrollLock(JXTable table) {
        this.table = table;
        table.getModel().addTableModelListener(getTableModelListener());
    }

    private TableModelListener getTableModelListener() {
        TableModelListener l = new TableModelListener() {

            @Override
            public void tableChanged(TableModelEvent e) {
                if (!blocked) return;
                if (e.getType() == TableModelEvent.INSERT) {
                    updateInsert(e.getFirstRow(), e.getLastRow());
                }
            }

        };
        return l;
    }

    protected void updateInsert(int firstRow, int lastRow) {
        // PENDING: assumption is that insert always above
        // need additional logic for other cases
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                Rectangle r = table.getVisibleRect();
                int row =table.rowAtPoint(new Point(0, r.y + r.height));
                int lastVisible = table.getRowCount() - rowsBelow;
                table.scrollRowToVisible(lastVisible);
            }
        });
    }

    public void block() {
        Rectangle viewRect = table.getVisibleRect();
        int lastVisibleRow = table.rowAtPoint(new Point(0, viewRect.y + viewRect.height));
        rowsBelow = table.getRowCount() - lastVisibleRow;
        blocked = true;
    }

    public void unblock() {
        blocked = false;
        rowsBelow = -1;
    }

}