Java - как предотвратить горизонтальную автопрокрутку в JTable при нажатии на вторую ячейку?

У меня есть JTable с 2 столбцами. Во втором столбце есть длинные элементы в некоторых ячейках, поэтому я использую горизонтальную полосу прокрутки, чтобы пользователь мог прокручивать ее вручную, чтобы увидеть, что написано в этих длинных ячейках.

Вот как выглядит JTable до щелчка по любой из его строк:

введите описание изображения здесь

Проблема в том, что когда я щелкаю левой кнопкой мыши по любой ячейке во втором столбце, чтобы выделить эту строку, таблица автоматически прокручивается по горизонтали, как здесь:

введите описание изображения здесь

Есть ли способ предотвратить эту автоматическую прокрутку, но в то же время сохранить ручную прокрутку пользователем (в случае, если пользователь хочет прокрутить по горизонтали, чтобы увидеть, что находится внутри ячеек)?


person Brad    schedule 18.01.2016    source источник
comment
Можете ли вы опубликовать код для приведенной выше таблицы?   -  person user1803551    schedule 18.01.2016


Ответы (5)


Если вы хотите полностью отключить автопрокрутку, вы можете просто использовать

table.setAutoscroll(false)

Но на самом деле это не очень полезно, потому что навигация с клавиатуры не работает. Я предлагаю вам по-прежнему автопрокрутку, если ячейка полностью скрыта от просмотра. Для этого я отключил автопрокрутку и переопределил changeSelection для обработки прокрутки, когда ячейка скрыта.

public static class TestTable extends JTable {
    static final int THRESHOLD = 10;
    static String[] columns = {"name", "description", "other"};
    static String[][] data = {
            {"name1", "some description 1", "other value we don't care about"},
            {"name2", "some description 2", "other value we don't care about"},
            {"name3", "some description 3", "other value we don't care about"}
    };

    public TestTable() {
        super(data, columns);
        setAutoResizeMode(AUTO_RESIZE_OFF);
        setAutoscrolls(false);

        getColumnModel().getColumn(0).setPreferredWidth(300);
        getColumnModel().getColumn(1).setPreferredWidth(300);
        getColumnModel().getColumn(2).setPreferredWidth(300);
    }

    @Override
    public void changeSelection(int rowIndex, int columnIndex, boolean toggle, boolean extend) {
        super.changeSelection(rowIndex, columnIndex, toggle, extend);
        scrollColumnToVisible(rowIndex, columnIndex);
    }

    private void scrollColumnToVisible(int rowIndex, int columnIndex) {
        Rectangle cellRect = getCellRect(rowIndex, columnIndex, false);

        int leftX = cellRect.x;
        int rightX = cellRect.x + cellRect.width;

        //assuming we're in scroll pane
        int width = Math.min(getWidth(), getParent().getWidth());

        int scrolledX = -getX();
        int visibleLeft = scrolledX;
        int visibleRight = visibleLeft + width;

        //bonus, scroll if only a little of a column is visible
        visibleLeft += THRESHOLD;
        visibleRight -= THRESHOLD;

        boolean isCellVisible = leftX < visibleRight // otherwise cell is hidden on the right
                && rightX > visibleLeft // otherwise cell is hidden on the left
                ;
        if (!isCellVisible) {
            scrollRectToVisible(cellRect);
        }
    }
}

В качестве бонуса я добавил THRESHOLD, чтобы ячейка считалась скрытой, когда на самом деле видна только небольшая часть :) Полный код: здесь.

person Dzmitry Paulenka    schedule 18.01.2016
comment
Я заметил, что при прокрутке с помощью стрелок вверх и вниз на клавиатуре он не будет отображать строки, которые мы прокручиваем, если эти строки находятся за пределами текущего видимого прямоугольника в JTable, поэтому я добавил этот код в scrollColumnToVisible (...) чтобы разрешить вертикальную прокрутку с помощью этих клавиш: pastebin.com/JNakxhCX - person Brad; 19.01.2016

Поведение автопрокрутки JTable реализовано в changeSelection (). Самый простой способ предотвратить горизонтальную автопрокрутку - всегда привязать ее к столбцу 0:

table = new JTable(new MyTableModel()) {
    @Override
    public void changeSelection(int rowIndex, int columnIndex, boolean toggle, boolean extend) {
        super.changeSelection(rowIndex, 0, toggle, extend);
    }
};
person perinion    schedule 10.07.2016

Возможно, вы могли бы использовать подход из таблицы с фиксированными столбцами.

Это позволяет вам создать «заголовок строки» для панели прокрутки. Заголовок строки никогда не прокручивается, поэтому всегда будет виден первый столбец. Однако вы все равно можете прокручивать оставшиеся столбцы.

person camickr    schedule 18.01.2016

Вы можете @Override использовать scrollRectToVisible метод таблицы. В качестве первого шага я бы использовал пустую реализацию. Когда вы точно определите, когда вам нужна автоматическая прокрутка, а когда нет, реализуйте метод соответствующим образом.

person user1803551    schedule 18.01.2016

Если вы хотите отключить горизонтальную автопрокрутку, попробуйте это.

public class MyTable extends JTable {
    @Override
    public void scrollRectToVisible(Rectangle aRect) {
        aRect.x = 0;
        super.scrollRectToVisible(aRect);
    }
}
person simis Sim    schedule 27.12.2020