Scroll Lock с панелями JTable и JScroll - PullRequest
1 голос
/ 13 сентября 2011

У меня есть JTable, который создан с использованием EventTableModel и находится в JScrollPane.EventTableModel берет живые обновления из eventList и отображает результат в таблице.По мере появления новых результатов в таблице и новой части информации, отображаемой в верхней части таблицы.

Однако я хочу иметь возможность заблокировать таблицу, чтобы показать то, что отображается в данный момент, когда янажмите кнопку под названием «Блокировка таблицы».Эта кнопка должна иметь тот же эффект, что и консоль затмения 'Scroll Lock', поэтому при появлении новых элементов текущие элементы должны оставаться на экране и не отталкиваться при появлении новых элементов.Но новые элементы все равно должны быть добавлены, а не прокручиваться автоматически.

Кто-нибудь знает, как я могу попытаться достичь этой функциональности.Таким образом, по мере поступления обновлений данные, находящиеся в таблице, не выводятся за пределы экрана, поэтому при нажатии флажка фокусировка остается на текущих данных.

Спасибо за любую помощь.Michael

1 Ответ

2 голосов
/ 13 сентября 2011

Основная процедура (для вставки над текущей областью отображения)

  • установка 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;
    }

}
...