1

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.

Paul Reiners
  • 8,576
  • 33
  • 117
  • 202
  • better would be check last post from [http://stackoverflow.com/questions/1385737/scrollable-jpanel] .... – mKorbel Apr 28 '11 at 21:44
  • 2
    whatever the solution (too late for me to really dig :-) never-ever call any of the setXXSize (xx = min/pref/max), doing so will short-circuit any efforts of the component to come up with reasonable hints depending on its own state. – kleopatra Apr 28 '11 at 22:27
  • 4
    -1, Where is your SSCCE? (http://sscce.org) How do we know what your panel looks like or why the preferred size isn't what your think? We don't know what components you added to it or anything – camickr Apr 29 '11 at 00:42

2 Answers2

4

In AWT (and then Swing), Container.getPreferredSize() either:

  • returns the size explicitly set by setPreferredSize(),
  • or the size calculated by the LayoutManager if setPreferredSize() has not been called explicitly

Hence, what getPreferredSize() returns highly depends on which LayoutManager you use for your ScrollableJPanel.

Be aware that most LayoutManagers will use getPreferredSize() on all direct children of the Container upon which getPreferredSize() was called. This is a recursive process (if children have children themselves) and may involve several different LayoutManagers.

jfpoilpret
  • 10,449
  • 2
  • 28
  • 32
  • while technical true (as LayoutManagers are rather free what to return), practically all managers simply return the summed up preferredSizes of all the container's children. You said that as well, but the emphasis is a bit too much on the "highly depends": the actual layout might depend, but mostly not the prefSize. The other way round: the sizing requirements of the children at the leafs of the hierarchy tree deterministically define the overall prefSize of the tree :-) – kleopatra Apr 29 '11 at 08:37
  • OK, this is my habit to use "strong" words like "never", "highly"... I like the word "simply" in your sentence "practically all managers simply return the summed up preferredSizes of all container's children"; I haven't checked all LAyoutManagers, but I can tell for sure that this is not "simple" for DesignGridLayout ;-) – jfpoilpret May 02 '11 at 05:05
  • yeah, definitely was in my strong-word-phase myself ;-) Meant the simply as in first approximation. Don't think (my gut-always-right-phase) that the problem is in any way bound to complex LayoutManagers doing higher magic ... we'll see when/if the OP releases more info :-) – kleopatra May 02 '11 at 07:11
3

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.

MeBigFatGuy
  • 28,272
  • 7
  • 61
  • 66
  • all correct except for the last sentence: nothing automagically sets any preferredSize, empty panel or not, explicitly, except mis-behaving client code ;-) – kleopatra Apr 29 '11 at 08:39
  • What i'm saying is if you derive a class from JPanel, and just override paintComponents to do some Graphics drawing code, that class should call setPreferredSize, or perhaps override getPreferredSize to produce something meaningful. – MeBigFatGuy Apr 29 '11 at 18:14