Layout Manager preferredSize Java
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:
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.
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, 2022Comments
-
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:
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 almost 13 years@mKorbel - Thanks. My approach is always to change as little as possible, but yours is better I think :)
-
David almost 13 yearsThanks for your answer. A little late this time mKorbel :P You're usually always a great help with Swing GUI :)
-
David almost 13 yearsGood idea, I will avoid it when I can. I was experimenting this time.
-
Michael Borgwardt almost 13 yearsNot 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 almost 13 years@David please read little bit crypted suggestion by (@camickr) == don't, never ever set something as setSize(), setBounds() +1
-
camickr almost 13 years@Michael, I stand by my commnent. The poster should NOT be setting the preferred size of the
controlPane
or thebuttonPane
. 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 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 almost 13 yearsSee also How do I create a screenshot to illustrate a post? for some tips on making a great screen shot.
-
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 over 10 yearsWhat operating system are you running for the screen shot above.
-
MByD over 10 years@Doug - this screenshot is from ubuntu ( 11.04 I think ) with gnome.