I have a JTable that is within a JScrollPane.
Rows are added to the table at runtime based on events that happen in my application. I want to have the scoll pan
It's very easy, JTable has scrollRectToVisible method too. If you want, you can try something like this to make scrollpane go to to the bottom if a new record is added :
jTable1.getSelectionModel().setSelectionInterval(i, i);
jTable1.scrollRectToVisible(new Rectangle(jTable1.getCellRect(i, 0, true)));
Where i is last added record.
It seems to me a lot easier to set the viewport position instead of scrolling the table. Following is my code.
public void scrollCellToView(int rowIndex, int vColIndex) {
if (!(this.getParent() instanceof JViewport)) {
return;
}
JViewport viewport = (JViewport) this.getParent();
Rectangle rect = this.getCellRect(rowIndex, vColIndex, true);
Rectangle viewRect = viewport.getViewRect();
int x = viewRect.x;
int y = viewRect.y;
if (rect.x >= viewRect.x && rect.x <= (viewRect.x + viewRect.width - rect.width)){
} else if (rect.x < viewRect.x){
x = rect.x;
} else if (rect.x > (viewRect.x + viewRect.width - rect.width)) {
x = rect.x - viewRect.width + rect.width;
}
if (rect.y >= viewRect.y && rect.y <= (viewRect.y + viewRect.height - rect.height)){
} else if (rect.y < viewRect.y){
y = rect.y;
} else if (rect.y > (viewRect.y + viewRect.height - rect.height)){
y = rect.y - viewRect.height + rect.height;
}
viewport.setViewPosition(new Point(x,y));
}
JList internally use scrollRectToVisible and specify the coordinates to scroll to. I think you will have to recode a similar functionality for JTable.
See this example : http://www.exampledepot.com/egs/javax.swing.table/Vis.html
update: the link is now obsolete, here is the code (from http://smi-protege.stanford.edu/repos/protege/protege-core/trunk/src/edu/stanford/smi/protege/util/ComponentUtilities.java )
public static void scrollToVisible(JTable table, int rowIndex, int vColIndex) {
if (!(table.getParent() instanceof JViewport)) {
return;
}
JViewport viewport = (JViewport)table.getParent();
// This rectangle is relative to the table where the
// northwest corner of cell (0,0) is always (0,0).
Rectangle rect = table.getCellRect(rowIndex, vColIndex, true);
// The location of the viewport relative to the table
Point pt = viewport.getViewPosition();
// Translate the cell location so that it is relative
// to the view, assuming the northwest corner of the
// view is (0,0)
rect.setLocation(rect.x-pt.x, rect.y-pt.y);
table.scrollRectToVisible(rect);
// Scroll the area into view
//viewport.scrollRectToVisible(rect);
}
The first answer works well, but the selected row gets positioned at the bottom of the table. So I created this modified version:
private void scrollToVisible(int rowIndex, int vColIndex ) {
JTable table = getTablePanel().getTable();
if (!(table.getParent() instanceof JViewport)) {
return;
}
if (table.getRowCount()<1){
return;
}
JViewport viewport = (JViewport)table.getParent();
// view dimension
Dimension dim = viewport.getExtentSize();
// cell dimension
Dimension dimOne = new Dimension(0,0);
// This rectangle is relative to the table where the
// northwest corner of cell (0,0) is always (0,0).
Rectangle rect = table.getCellRect(rowIndex, vColIndex, true);
Rectangle rectOne;
if (rowIndex+1<table.getRowCount()) {
if (vColIndex+1<table.getColumnCount())
vColIndex++;
rectOne = table.getCellRect(rowIndex+1, vColIndex, true);
dimOne.width=rectOne.x-rect.x;
dimOne.height=rectOne.y-rect.y;
}
// '+ veiw dimension - cell dimension' to set first selected row on the top
rect.setLocation(rect.x+dim.width-dimOne.width, rect.y+dim.height-dimOne.height);
table.scrollRectToVisible(rect);
}
Now the selected row gets positioned at the top of the table.