Steve McLeod
Steve McLeod

Reputation: 52478

How many rows is a JTable currently displaying?

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

Answers (5)

user3042500
user3042500

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

kleopatra
kleopatra

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

Mikle Garin
Mikle Garin

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

Robin
Robin

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

jadrijan
jadrijan

Reputation: 1446

Try:

table.getModel().getRowCount();

Upvotes: -4

Related Questions