2

Solution

jtable.getHeight does not include header element

jtable.getRowHeight include margin

and the example has 15px actual height, not 14px

More clear example

RO 16
R1 16
R2 16
HEIGHT 48
INTERCELL java.awt.Dimension[width=1,height=1]
MARGIN 1

I have JTable with 3 rows. Each row is 16px. And each row margin 1px. So I suspect that table height should be 16 + 1 + 16 + 1 + 16 = 50px

BUT getHeight returns 48px

Also I did streenshot. Each row has 14px height actually.

How how is it possible????

Source code

Visual representation

    //headers for the table
    String[] columns = new String[] {
        "Id", "Name", "Hourly Rate", "Part Time"
    };

    //actual data for the table in a 2d array
    Object[][] data = new Object[][] {
        {1, "John", 40.0, false },
        {2, "Rambo", 70.0, false },
        {3, "Zorro", 60.0, true },
    };

    //create table with data
    JTable table = new JTable(data, columns);

    //add the table to the frame
    this.add(table);

    this.setTitle("Table Example");
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);       
    this.pack();
    this.setVisible(true);
    System.out.println("RO " + table.getRowHeight(0));
    System.out.println("R1 " + table.getRowHeight(1));
    System.out.println("R2 " + table.getRowHeight(2));
    System.out.println("HEIGHT " + table.getHeight());
    System.out.println("INTERCELL " + table.getIntercellSpacing());
    System.out.println("MARGIN " + table.getRowMargin());
}

Original question

I have simple test frame with jtable in the scroll pane.

The table minimum height is less than actual height. header + rows < actual size

It is nonsense.

  val jtable = view.tableControl
  val headerHeight = jtable.getTableHeader.getHeight
  val rowsHeight = (0 until jtable.getRowCount()).foldLeft(0) { (heightAccumulator, counter) ⇒
    println("Row " + counter + " height " + jtable.getRowHeight(counter))
    jtable.getRowHeight(counter) + heightAccumulator
  }
  val rowsMargin = jtable.getRowMargin() * (jtable.getRowCount() - 1)
  println("Actual height " + jtable.getHeight())
  println("Header height " + headerHeight)
  println("Margin height " + jtable.getRowMargin())
  println("PreferredScrollableViewportSize" + jtable.getPreferredScrollableViewportSize())
  println("Rows height " + rowsHeight)
  println("Should be at least: " + (rowsHeight + headerHeight + rowsMargin))

and I got

Row 0 height 16
Row 1 height 16
Row 2 height 16
Row 3 height 16
Row 4 height 16
Actual height 80
Header height 19
Margin height 1
PreferredScrollableViewportSizejava.awt.Dimension[width=450,height=400]
Rows height 80
Should be at least: 103

The JTable lays inside the frame without any scroll bars. It is fully visible and there is a lot of space bellow.

How? How jtable.getHeight() of fully visible table may returns height less then (rows * rowHeight + header)?

Ezhik
  • 876
  • 6
  • 23
  • If you don't get a satisfactory answer, please edit your question to include a [mcve] that shows your current approach. – trashgod Dec 07 '15 at 14:48
  • I have not interest to show or hide a scroll bar. I have no interest to change table height. I just want to find the actual table height. At this time I think that `getHeight()` isn't include header height and `getRowMargin()` information. – Ezhik Dec 07 '15 at 15:03
  • This is one of unit tests from the huge project. I am sure that I am unable to create a Minimal, Complete, and Verifiable example with acceptable efforts. – Ezhik Dec 07 '15 at 15:11
  • Please edit your question to reflect the test case rationale. – trashgod Dec 07 '15 at 16:37

2 Answers2

3

How? How jtable.getHeight() of fully visible table may returns height less then (rows * rowHeight + header)?

A JTable has a default preferred size that is hardcoded when the table is created because a table is typically added to the viewport of a JScrollPane. As you can see the preferred viewport size is much larger that you need for a small table which would account for the extra space.

If you have a small table and you want it to be fully displayed at it minimum size then you can use code like:

JTable table = new JTable(...);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scrollPane = new JScrollPane( table );
camickr
  • 321,443
  • 19
  • 166
  • 288
2

You can substitute your own implementation of Scrollable to get a variety of effects. In particular, override getPreferredScrollableViewportSize() and return a suitable multiple of the row height. Let N be the number of rows after which you want the scrollbar to appear.

JTable table = new JTable(tableModel) {

    @Override
    public Dimension getPreferredScrollableViewportSize() {
        return new Dimension(SOME_WIDTH, N * table.getRowHeight());
    }
};

Add the table to a scroll pane:

JScrollPane sp = new JScrollPane(table);

Add the pane to a panel having a layout that respects preferred size:

JPanel p = new JPanel(new GridLayout());
p.add(sp);

A table having more than N rows will display scroll bars, as shown here.

I just want to find the actual table height [in the context of] unit tests from the huge project.

I don't know exactly how your total height calculation fails, but the result will inevitably change based on the user's platform, the chosen look & feel, and the component validation state; an erroneous approach is suggested here. Instead, attempt to meet the test requirement by ensuring that a paricular number of rows is visible using the approach outlined above.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • (1+) for complete control over the tables initial size. Although I believe you also need to add in the height of the row header. – camickr Dec 07 '15 at 15:53
  • @camickr: Good point, but it looks like `headerHeight` is included; I think the test should be for visible _rows_, rather than visible _pixels_, but I'm spoiled by being allowed to propose derived requirements. – trashgod Dec 07 '15 at 16:55