简体   繁体   中英

Java - How to prevent the horizontal auto-scrolling in a JTable when clicking the 2nd cell?

I have a JTable with 2 columns. The 2nd column has long items in some of its cells, so i'm using a horizontal scroll bar so the user can scroll it manually to see what's written in those long cells.

Here is how the JTable looks before clicking on any of its rows:

在此处输入图片说明

The problem is that when i left click on any cell in the second column to highlight that row the table automatically scrolls horizontally like in here:

在此处输入图片说明

Is there a way to prevent this automatic scrolling, but at the same time keep the manual user scrolling(In case the user wants to scroll horizontally to see what's inside the cells)?

Autoscroll behaviour of JTable is implemented in changeSelection(). So simpliest way to prevent horizontal autoscroll is to tie it always to column 0:

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

Maybe you could use the approach from Fixed Column Table .

It allows you to create a "row header" for the scroll pane. The row header is never scrolled, so the first column will always be visible. However, you can still scroll through remaining columns.

You can @Override the table's scrollRectToVisible method. As a first step, I would use an empty implementation. When you figure out exactly when you want auto-scrolling and when not, implement the method accordingly.

If you want to disable autoscroll completely, you can just use

table.setAutoscroll(false)

But really, that's not very usefull, because keyboard navigation is getting off. I suggest you to still autoscroll, if cell is completely hidden from view. To do so, I've disable autoscroll and overriden changeSelection to handle scrolling, when cell is hidden.

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);
        }
    }
}

As a bonus, I've added THRESHOLD to consider cell hidden, when only a little porition is actually visible :) Full code is here.

If you want to disable horizontal auto scroll, try this.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM