Reputation: 195
I have a JTable with in a JScrollPane, I want to scroll to the bottom of the table programatically. The code I tried is:
int bottomRow = table.getRowCount()-1;
Rectangle rect = table.getCellRect(bottomRow,0,true);
table.scrollRectToVisible(rect);
Also I tried the code:
int bottomRow = table.getRowCount()-1;
Rectangle rect = table.getCellRect(bottomRow,0,true);
jscrollPane1.getViewPort().setViewPosition(rect.getLocation());
Both the code snippets behave the same and both are scrolling the table not to the bottom row but a few rows above the bottom row depending upon the height of the rectangle.
I need help to see the last row of the table in visible rectangle.
Upvotes: 0
Views: 1137
Reputation: 347314
I wrote this simple example to demonstrate a workable solution, seen there has being no further development with the question, I'll post it as a working example in the hope that it might prompt more info from the OP
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;
public class ToLastRow {
public static void main(String[] args) {
new ToLastRow();
}
public ToLastRow() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
DefaultTableModel model = new DefaultTableModel(new Object[]{"Look no hands..."}, 0);
for (int index = 0; index < 1000; index++) {
model.addRow(new Object[]{index});
}
final JTable table = new JTable(model);
JButton last = new JButton("Last");
JButton first = new JButton("First");
last.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int row = table.getRowCount() - 1;
scrollTo(table, row);
}
});
first.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
scrollTo(table, 0);
}
});
JPanel buttons = new JPanel();
buttons.add(last);
buttons.add(first);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new JScrollPane(table));
frame.add(buttons, BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public void scrollTo(JTable table, int row) {
Rectangle bounds = table.getCellRect(row, 0, true);
table.scrollRectToVisible(bounds);
table.addRowSelectionInterval(row, row);
}
}
Upvotes: 0
Reputation: 51525
Wildly guessing (as you didn't provide enough context) that you want to update the scroll value when notified about a change in the tableModel.
In this case the problem is that the table itself is listening to the model to update its internals. As you want to change something based on state of the table itself, you have to ensure that your action happens only after the internals are completely updated, something like:
public void tableChanged(TableModelEvent e) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// scroll to last row
}
});
}
Upvotes: 2