Layout Manager preferredSize Java

16,215

Solution 1

That's the result of using GridLayout as layout manager. Change it to BorderLayout:

frame.getContentPane().setLayout(new BorderLayout());

For example, this code (I changed a little as possible from the original):

import java.awt.*;
import javax.swing.*;

public class LayoutMgrTest
{
    public static void main(String[] args)
    {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        //frame.setVisible(true);   
        //frame.getContentPane().setLayout(new BorderLayout());

        JPanel controlPane = new JPanel();
        JPanel buttonPane = new JPanel();

        controlPane.setLayout(new BoxLayout(controlPane, BoxLayout.PAGE_AXIS));
        controlPane.setPreferredSize(new Dimension(200, 200));
        controlPane.add(new JScrollPane(new JTextArea()));

        buttonPane.setLayout(new FlowLayout(FlowLayout.LEFT));
        buttonPane.setPreferredSize(new Dimension(100,40));
        buttonPane.add(new JButton("Button1"));
        buttonPane.add(new JButton("Button2"));

        frame.add(controlPane, BorderLayout.NORTH);
        frame.add(buttonPane, BorderLayout.SOUTH);
        //frame.setSize(new Dimension(500,500));
        frame.pack();
        frame.setVisible(true);
    }
}

Generates this frame:

enter image description here

Solution 2

I set the preferredSize of each panel accordingly,

That is another problem. You should NOT set the preferred size. That is the job of the layout manager. Just add your components to the panels and let the layout manager do its job.

Most compnents have a default preferred size. For some you need to give it a little tip. For example when using a text area you would give a "suggested" preferred size by using:

JTextArea textArea = new JTextArea(rows, columns);

Solution 3

If you use LayoutManager, you should not set a size on a component except the frame.

the size for the components is calculated from the different layout managers.

you find more infos at http://download.oracle.com/javase/tutorial/uiswing/layout/howLayoutWorks.html

in your code, you can add the panel with the textarea to BorderLayout.CENTER. this should solve your problem. the component in BorderLayout.CENTER takes the whole space, except the space needed for the components in NORTH, EAST, SOUTH and WEST.

Share:
16,215
David
Author by

David

Hey! I'm David, co-founder at a design & dev startup called All Front. I love to build single page apps with the amazing design & dev team! I'm enthusiastic about Angular, React and progressive web apps.

Updated on June 08, 2022

Comments

  • David
    David about 2 years

    I'm still trying to learn how layout managers work. I made a Frame with two JPanels. The first one contains a textArea with a boxLayout. The second one contains a flow layout with a button.

    I set the preferredSize of each panel accordingly, packed them, but got unexpected results.

    import java.awt.*;
    import javax.swing.*;
    
    public class LayoutMgrTest
    {
        public static void main(String[] args)
        {
            TableBasic frame = new TableBasic();
            frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
            frame.setVisible(true);
    
    
            frame.getContentPane().setLayout(new GridLayout(2,1));
    
            JPanel controlPane = new JPanel();
            JPanel buttonPane = new JPanel();
    
            controlPane.setLayout(new BoxLayout(controlPane, BoxLayout.PAGE_AXIS));
            controlPane.setPreferredSize(new Dimension(200, 200));
            controlPane.add(new JScrollPane(new JTextArea()));
    
            buttonPane.setLayout(new FlowLayout(FlowLayout.LEFT));
            buttonPane.setPreferredSize(new Dimension(100,20));
            buttonPane.add(new JButton("Button1"));
            buttonPane.add(new JButton("Button2"));
    
            frame.getContentPane().add(controlPane, BorderLayout.NORTH);
            frame.getContentPane().add(buttonPane, BorderLayout.SOUTH);
            frame.setSize(new Dimension(500,500));
            frame.pack();
        }
    }
    

    Whatever I do, if I use a grid Layout, it seems to always allocate half of the available space to each control. I have been told that:

    The height of each row is dependent on the height of each component added in each row.

    The buttonpane's height is 20. It's allocating much more than that to it:

    Wasted space

    What's wrong with this code?
    I would like to leave the two JPanels intact please. It's easy to simply add the textbox and the buttons directly to the frame, but I need to do it with JPanels (because I will be adding borders and other things).

  • MByD
    MByD almost 13 years
    @mKorbel - Thanks. My approach is always to change as little as possible, but yours is better I think :)
  • David
    David almost 13 years
    Thanks for your answer. A little late this time mKorbel :P You're usually always a great help with Swing GUI :)
  • David
    David almost 13 years
    Good idea, I will avoid it when I can. I was experimenting this time.
  • Michael Borgwardt
    Michael Borgwardt almost 13 years
    Not true; the preferredSize is one of the values layout managers base their calculations on (not all of them, though). The result of their calculations is the size property, not preferredSize.
  • mKorbel
    mKorbel almost 13 years
    @David please read little bit crypted suggestion by (@camickr) == don't, never ever set something as setSize(), setBounds() +1
  • camickr
    camickr almost 13 years
    @Michael, I stand by my commnent. The poster should NOT be setting the preferred size of the controlPane or the buttonPane. The layout manager will determine the preferred size of these panels based on the components added to them. This information will then be used to pack() the frame based on the preferred size of all the panels added to the frame. And yes, then the layout manager will set the size/location of each panel.
  • Michael Borgwardt
    Michael Borgwardt almost 13 years
    @camickr: Hm, you're right in context: setting the preferred size of containers that have layout managers is not useful; My statement would be correct for regular components.
  • Andrew Thompson
    Andrew Thompson almost 13 years
    See also How do I create a screenshot to illustrate a post? for some tips on making a great screen shot.
  • jfpoilpret
    jfpoilpret almost 13 years
    @Michael you shouldn't set size (min, max, pref or actual) even for stand-alone components, because most Swing components know how to compute their own min,pref,max sizes based on their content; then it's the LayoutMnager's job to calculate set their actual size (and location).
  • Doug Hauf
    Doug Hauf over 10 years
    What operating system are you running for the screen shot above.
  • MByD
    MByD over 10 years
    @Doug - this screenshot is from ubuntu ( 11.04 I think ) with gnome.