【问题标题】:How many rows is a JTable currently displaying?JTable 当前显示多少行?
【发布时间】:2012-08-09 16:16:53
【问题描述】:

JTable 有一个方法 getVisibleRowCount(),它显示首选要显示的行数。

我想确定 JTable 中当前可见的 实际 行数。我该怎么做?

我目前的尝试是:

int rowsVisible = table.getSize().getHeight()/table.getRowHeight();

但它给我的价值比我看到的要高得多。

例如,当有 10 或 11 行可见时,结果为 18。

【问题讨论】:

    标签: java swing jtable


    【解决方案1】:

    问桌子,它正在为你做所有艰苦的工作:

    Rectangle vr = table.getVisibleRect ();
    int first = table.rowAtPoint(vr.getLocation());
    vr.translate(0, vr.height);
    int visibleRows = table.rowAtPoint(vr.getLocation()) - first;
    

    【讨论】:

    • getVisibleRect ... 我知道JTable 中有一个方法,但我在 view 上的搜索没有得到任何好的结果。对此答案表示赞成,需要检查是否可以删除已接受的答案
    【解决方案2】:

    我尚未对此进行测试,但我希望当 JTable 包含在 JScrollPane 中时,您可以使用 getViewPort 向滚动窗格询问其视口,并从视口中检索大小。

    如果将该高度除以表格的行高,您可能会得到更好的估计

    final int pageSize = 
        (int) (table.getParent().getSize().getHeight() / table.getRowHeight());
    

    非常接近

    【讨论】:

    • 抱歉...但是 a) 不完整(正如@Mikle Garin 已经指出的那样)并且太低级(如您所知,始终使用可用的最高抽象;-)
    • @SteveMcLeod 此线程中有更好的答案。如果您不接受这个答案,我可以删除它,因为它不正确
    【解决方案3】:

    这些尝试中没有一个是正确的。只是因为它不关心向下滚动...:-/

    我根据我能找到的正确答案编写了代码,并且尝试过并且是正确的(我希望如此)。

    但我只尝试了第 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));
        }
    }
    

    【讨论】:

      【解决方案4】:

      Robin 提供的方式并不完全正确 - 当表格具有不同的行高时,它将无法工作。它也不会检查行间距和其他一些细微差别。

      以下是适用于任何 L&F 和表格设置的示例:

      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 );
      }
      

      只需尝试调整表格大小即可查看效果。

      您还可以修改“单元格可见”条件以排除(作为示例)可见少于 5 个像素(或其高度的一半)的行。

      【讨论】:

      • near .. 但仍然太低级(无需循环,只需问表:-)
      • @kleopatra 如果您想排除只有几个可见像素的单元格,或者如果您正在使用一些复杂的表格(如 Jide 包中的表格),您将不得不循环。例如 - 一些行折叠的树表,在这种情况下你的方法将不起作用;)
      • 它必须 - 如果它没有,表实现是错误的 ;-) 看不出有任何理由要排除低于给定高度的行 - 无论您是否想要实际计数。
      • @kleopatra 如果使用树表(或其他类似的类似表的结构),您可以获得可见行之间的隐藏行。这意味着当您获得 lastVisibleRow-firstVisibleRow 值时,它可能大于实际可见行数。那是我的观点。但总的来说 - 是的,你的方法会更快,更省力。
      • 重复我自己:如果 jide 树表计算折叠(又名:隐藏行),那么它的实现是错误的:返回的 rowIndex 必须在视图坐标和那些 必须是连续的。现在运行检查我们的 JXTreeTable 是否表现良好 :-)
      【解决方案5】:

      试试:

      table.getModel().getRowCount();
      

      【讨论】:

      • 返回表中的总行数,而不是当前可见的行数。
      • 对不起我的错。它可能与 JScrollPane 有关。
      • 投票删除此答案,因为它没有回答所提出的问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多