Search code examples
javaswingjpanelscrollable

JPanel Preferred Size Not Being Set


When is the preferred size of a JPanel set if you don't set it explicitly?

I have the following code:

private static class ScrollableJPanel extends JPanel implements Scrollable {
    @Override
    public Dimension getPreferredScrollableViewportSize() {
                 return getPreferredSize();
    }
            .
            .
            .
}

and this code:

    myPanel = new ScrollableJPanel();
            // Add a bunch of controls to the panel.
    final JScrollPane scroll = new JScrollPane(myPanel);
    scroll.setAutoscrolls(true);
    scroll.setHorizontalScrollBarPolicy(
        ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

However, the preferred size of myPanel at the time getPreferredScrollableViewportSize() is being called seems to be an arbitrary value, (4225, 34), and prefSizeSet = false.

According to the Java documentation, this is a reasonable way to define this method. However, the actual size of myPanel is much higher than 34 pixels, so the view port is way too small.

What am I doing wrong here? Should I set the preferred size of myPanel explicitly? I tried that, but I want to use the actual size determined by the layout manager, not just make a guess that will be overridden later.

Note that my question isn't how to set an exact size for the JPanel. I want the layout manager to do that. Nor do I want to have to explicitly set the preferred size. I thought that was also handled by the layout manager. What I want to know is why the layout manager is not setting a reasonable value for the preferred size itself so that I can return a reasonable PreferredScrollableViewportSize.


Solution

  • The Preferred size of a JPanel is based on the components in the panel. The Layout manager calculates a preferred size of the panel, based on the preferred size of the items in the panel, and if some of those things are panels, then it is a recursive calculation. If there are no sub components in the panel, then the preferred size will have to be set explicitly.