【问题标题】:Scroll Lock with JTable and JScroll Panes使用 JTable 和 JScroll 窗格进行滚动锁定
【发布时间】:2011-09-12 22:18:15
【问题描述】:

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

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

有谁知道我可以如何尝试实现此功能。这样当更新进入时,表格上的数据不会被强制离开屏幕,因此当按下复选框时,焦点仍停留在当前数据上。

感谢您的帮助。 迈克尔

【问题讨论】:

    标签: java swing locking jtable jscrollpane


    【解决方案1】:

    基本步骤(在当前显示区域上方插入)

    • 在表的模型上安装 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;
        }
    
    }
    

    【讨论】:

    • 这种方法的问题是表格跳转,行不固定。有没有办法只保证上面添加了行,并且当前表格字段保留在屏幕上,但是上面添加了其他表格行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多