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)?
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.