Reputation: 52478
JTable has a method getVisibleRowCount(), which shows the preferred number of rows to display.
I want to determine the actual number of rows currently visible in a JTable. How can I do this?
My current attempt is:
int rowsVisible = table.getSize().getHeight()/table.getRowHeight();
but the value it gives me is quite higher than what I can see.
For example, when there are 10 or 11 rows visible, this gives me a result of 18.
Upvotes: 2
Views: 8633
Reputation: 11
Exactly none of these attempts is correct. Simply since its don't care about scrolling down... :-/
I wrote the code based on the correct answers which I was able to find, which was tried and was correct (I hope).
But i tried it only for column 0...
public static int getNumberOfVisibleRows(JTable table) {
Rectangle vr = table.getVisibleRect();
int first = table.rowAtPoint(vr.getLocation());
vr.translate(0, vr.height);
return table.rowAtPoint(vr.getLocation()) - first;
}
public static void scrollToVisible(JTable table, int rowIndex, int columnIndex, int numberOfVisibleRows) {
Rectangle visibleRect = table.getVisibleRect();
Rectangle rect1 = table.getCellRect(rowIndex, columnIndex, false);
if (visibleRect.y > rect1.y) {
table.scrollRectToVisible(rect1);
} else {
Rectangle rect2 = table.getCellRect(rowIndex + numberOfVisibleRows, columnIndex, false);
int width = rect2.y - rect1.y;
table.scrollRectToVisible(new Rectangle(rect1.x, rect1.y, rect1.width, rect1.height + width));
}
}
Upvotes: 1
Reputation: 51535
Ask the table, it's doing all the hard work for you:
Rectangle vr = table.getVisibleRect ();
int first = table.rowAtPoint(vr.getLocation());
vr.translate(0, vr.height);
int visibleRows = table.rowAtPoint(vr.getLocation()) - first;
Upvotes: 11
Reputation: 10153
The way Robin offered is not fully correct - it won't work when table have different row heights. Also it doesn't check the rows spacing and some other small nuances.
Here is the example that will work with any L&F and table settings:
public static void main ( String args[] )
{
final JLabel rows = new JLabel ( "Visible rows: ?", JLabel.CENTER );
final JTable table = new JTable ( new DefaultTableModel ( 30, 3 )
{
public String getColumnName ( int column )
{
return "title";
}
public Object getValueAt ( int row, int column )
{
return "cell";
}
} );
JScrollPane scroll = new JScrollPane ( table )
{
public Dimension getPreferredSize ()
{
Dimension ps = super.getPreferredSize ();
ps.height = 150;
return ps;
}
};
scroll.addComponentListener ( new ComponentAdapter ()
{
public void componentResized ( ComponentEvent e )
{
Rectangle vr = table.getVisibleRect ();
int visibleRows = 0;
for ( int i = 0; i < table.getRowCount (); i++ )
{
Rectangle cell = table.getCellRect ( i, 0, false );
if ( cell.y <= vr.y && cell.y + cell.height >= vr.y ||
cell.y <= vr.y + vr.height &&
cell.y + cell.height >= vr.y + vr.height ||
cell.y >= vr.y && cell.y + cell.height <= vr.y + vr.height )
{
visibleRows++;
}
}
rows.setText ( "Visible rows: " + visibleRows );
}
} );
JPanel panel = new JPanel ( new BorderLayout ( 25, 25 ) );
panel.setBorder ( BorderFactory.createEmptyBorder ( 25, 25, 25, 25 ) );
panel.add ( rows, BorderLayout.NORTH );
panel.add ( scroll, BorderLayout.CENTER );
JFrame frame = new JFrame ();
frame.add ( panel );
frame.setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE );
frame.pack ();
frame.setLocationRelativeTo ( null );
frame.setVisible ( true );
}
Just try resizing the table to see the effect.
Also you can modify the "is cell visible" condition to exclude (as an example) rows that have less that 5 pixels (or half of their height) visible.
Upvotes: 0
Reputation: 36621
I haven't tested this, but I would expect when a JTable
is contained in a JScrollPane
, you can ask the scrollpane for its viewport using getViewPort
, and retrieve the size from the viewport.
If you divide that height with the row height of the table, you might get a better estimation
final int pageSize =
(int) (table.getParent().getSize().getHeight() / table.getRowHeight());
is pretty close
Upvotes: 1