We help IT Professionals succeed at work.

JPanel inside JPanel layout problem

tslettebo asked
Medium Priority
Last Modified: 2013-11-23

I have a problem with a program I'm working on. No matter how much I've read the Swing tutorial (at Sun's site), and the API, I haven't got it fixed.

The problem is as follows:

I have an Applet with JPanels inside JPanels (to make it easier to group the components), and it appears that only the topmost container (in the containment hierachy, the content pane) respects the widow size, while any container it contains, don't, so some of the components end up outside the window.

Here's a program to demonstrate the problem (I'm using JFrame, rather than JApplet, here. The effect is the same). The following works:

--- Start program ---

JFrame frame=new JFrame("Test frame");


JPanel pane=new JPanel();

pane.add(new JTextField(8)); // Add some components
pane.add(new JTextField(8));
pane.add(new JTextField(8));
pane.add(new JTextField(8));
pane.add(new JTextField(8));
pane.add(new JTextField(8));
pane.add(new JTextField(8));
pane.add(new JTextField(8));

//JPanel paneN=new JPanel();


--- End program ---

This lays out the textfields neatly in two rows of four each, so the layout works.

If you uncomment the two lines above, and changes the line below to "frame.setContentPane(paneN)", it puts all the textfields in a JPanel (as before), and adds that JPanel to a new JPanel, which gets used as the content pane (instead of the first one).

If you run this, it will now lay all the textfields in one line, and they will overflow the window, so some aren't shown.

Is this how it's supposed to be?

Is there some way to get JPanels (or other JComponents) inside others, to all be laid out correctly?

Any help greatly appreciated.


Terje, Norway
Watch Question

>> This lays out the textfields neatly in two rows of four each, so the layout works.

No, it doesn't work. The JPanel's default layout is FlowLayout. If you resize your JFrame, you will realise that the components' positions will change. If you want the buttons to stay in two rows of four each, use a GridLayout.

Perhaps you can tell us how exactly you want the layout to be.

Maybe this is what you wanted:

     JFrame frame=new JFrame("Test frame");


     JPanel pane=new JPanel(new GridLayout(2, 4, 10, 10));

     pane.add(new JTextField(8)); // Add some components
     pane.add(new JTextField(8));
     pane.add(new JTextField(8));
     pane.add(new JTextField(8));
     pane.add(new JTextField(8));
     pane.add(new JTextField(8));
     pane.add(new JTextField(8));
     pane.add(new JTextField(8));

     GridBagLayout gridBagLayout = new GridBagLayout();
     GridBagConstraints constraints = new GridBagConstraints();
     JPanel paneN=new JPanel(gridBagLayout);

     constraints.anchor = GridBagConstraints.CENTER;
     constraints.gridwidth = GridBagConstraints.REMAINDER;
     constraints.fill = GridBagConstraints.NONE;
     gridBagLayout.setConstraints(pane, constraints);



If you resize the JFrame, the text fields will always be in two rows of four each.

It actually has some sense to it, just not much useful sense in your case.

If you consider a panel to give its first child in a flow its desired size, then start a new row if necessary, then you can see that the second panel gets its desired size (a single row of all its children), which means it won't wrap into two rows.

If you set the layout of the first pane to something else which forces its child's size (e.g. BorderLayout, with the next panel in CENTER), then you'll force the second JPanel to redo its layout to fit.
You need to set the preferred size of the inner panel. In your example adding the following line would work:

pane.setPreferredSize(new Dimension(400,400));

Hoppas det svaret racker ;-)

'Henrik, Sverige

It will not work if you change the columns of the text fields:

pane.add(new JTextField(20)); // Bigger text fields

In this case, each row can only accomodate one text field.

You're right yongsing. I was under the impression that he just wanted the JPanel to respect the frame's size.

But if you want a fixed set of rows and fixed size of the components (JTextFields in this example) your solution with GridLayout and GridBagLayout is absolutely the best. It will still overflow the frame if the fields are too big though.

The best solution for this I can think of right now is pretty ugly.

Take yongsing's example but instead of using a GridBagLayout for paneN do this:

JPanel paneN = new JPanel();
paneN.setLayout(new BoxLayout(paneN, BoxLayout.Y_AXIS));
pane.setMaximumSize(new Dimension(frame.getSize  ().width,pane.getPreferredSize().height));

frame.addComponentListener(new ComponentAdapter() {
          public void componentResized(ComponentEvent c) {
               pane.setMaximumSize(new Dimension(frame.getSize().width,pane.getPreferredSize().height));

It's ugly and it's specific for this problem but it might give you a few pointers in the right direction...

This question is LOCKED with a Proposed Answer.  If it helps you, great, accept it and grade it to close.  If not, reject it and comment as to why or what else is needed.

Few additional experts will join this collaboration effort, once a question has been locked.  Just want to confirm this to you.  If more than one expert helps you, you can always split points or award additional help in a new question, within the same topic area.  If you need help from us, post a zero point question here, and include the link:



Community Support Moderator @ Experts Exchange

Explore More ContentExplore courses, solutions, and other research materials related to this topic.