19

I currently have JTables nested in JScrollPanes like so:

enter image description here

My problem is that the number of rows in each table is variable when the table is created. What I want to do is make the JScrollpane smaller if the table is too short, but I want to keep it at a set size if the table is too long.

How can I accomplish this?

Alex Bliskovsky
  • 5,973
  • 7
  • 32
  • 41
  • 6
    +1 for the screenthot. Is way lot easier to answer these kind of question if there is an image present. – OscarRyz Jun 29 '11 at 16:33

5 Answers5

21
Dimension d = table.getPreferredSize();
scrollPane.setPreferredSize(
    new Dimension(d.width,table.getRowHeight()*rows+1));

Where rows represents the number of rows of data, or the limit.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • Seems like this will only give 1 pixel for the header. Is it possible the height calc was intended to be table.getRowHeight() * (rows+1) ? – KathyA. May 08 '17 at 21:43
  • 1
    This does not take into account various aspects of the L&F. It will squish the table columns from their preferred size if scrollbars are visible in the `scrollPane`. It also assumes the header height is equal to the row height, which is not always the case. – AJNeufeld Oct 26 '17 at 20:04
6

The following (currently accepted) code does not take into account various aspects of the Look and Feel:

Dimension d = table.getPreferredSize();
scrollPane.setPreferredSize(
    new Dimension( d.width, table.getRowHeight() * (rows+1) ));
  1. The header line is not necessarily table.getRowHeight() pixels in height. (In the "Metal" L&F, it is taller)
  2. A vertical scrollbar in the scrollPane will squish the table smaller than it's preferred size.
  3. A horizontal scrollbar will take additional space, so not all requested rows rows will be visible.

The following code should be used instead:

table.setPreferredScrollableViewportSize(
    new Dimension(
        table.getPreferredSize().width,
        table.getRowHeight() * visible_rows));

The scrollPane will ask the table for its preferred size, and adds to that any extra space for the header and scrollbars.

Below shows the difference in a JTable with 4 rows, when visible_rows is reduced from 4 to 3. The preferred width of the JScrollPane is automatically padded to include the scrollbar instead of compacting the table columns. Also note room for the header (which is different from the row height) is also automatically provided; it is not included in the visible_rows count.

JTable with and without scrollbar

AJNeufeld
  • 8,526
  • 1
  • 25
  • 44
5

I use setPreferredScrollableViewportSize() in this context, followed by pack() or revalidate() as required.

Addendum:

How do you use it?

It's a feature of the implementation of Scrollable in JTable. Here are several examples. The complementary getPreferredScrollableViewportSize() may also be useful.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
2

Use a GridBagLayout manager and set the maximum size of the JScrollPane to whatever you want to. If the table is larger the JScroll won't grow beyond that size.

Then, add a glue component ( I think it is something like BoxLayout.createVerticalGlue or something like that ) which is an empty component that just takes the remaining space.

So, when the table is smaller, this component will take the remaining space, if the table is larger, it won't take anything since the JScrollPane is using it.

OscarRyz
  • 196,001
  • 113
  • 385
  • 569
0

If you use MigLayout, when add the scrollpane containing the JTable, you can specify the constraint growx instead of grow, to make it stretch only horizontally.

Now the scrollpane is located in the middle of its parent. You can set in the row constraint to make it align to top of the row. Or, in component constraint: aligny top.

WesternGun
  • 11,303
  • 6
  • 88
  • 157