tags:

views:

23

answers:

2

BorderLayout does something strange. If I add two panels to a Container with the same constraint (BorderLayout.CENTER for instance), then the first one goes away, even if the second one is deleted or made invisible

It seems as though it would make sense for it to "stack" each element on top of the previous ones.

Is this correct and by design? If so, is there some documentation on it?

Has anyone else been frustrated by it? Have you a solution, such as a custom LayoutManager?

Sample code:

JFrame frame = new JFrame();
frame.setSize(500, 500);

JPanel panel1 = new JPanel();
panel1.setBackground(Color.blue);
frame.getContentPane().add(panel1);

JPanel panel2 = new JPanel();
panel2.setBackground(Color.red);
frame.getContentPane().add(panel2);

panel2.setVisible(false); // Seems like it should allow us to see panel1.

frame.setVisible(true);

This creates and displays a 500x500 blank box.

+2  A: 

BorderLayout was simply not designed to do what you want. Separation of responsibility. If you want that behavior you should compose: combine the BorderLayout with a CardLayout. Though for the actual stack behavior, you'll have to code something yourself (or find someone who already has.)

Kirk Woll
A: 

Is this correct and by design?

Yes.

You need to understand the basics of how layout managers work. One of the jobs of the layout manager is to set the "location" and "size" of the components added to the panel. In the case of a BorderLayout it only tracks 5 components so only the last component added to the CENTER is known by the layout manager.

Layout management is not done when components are added to the panel. It is done when the frame is packed, or made visible (or the revalidate() method is invoked) . In this case the blue panel is not part of the components managed by the BorderLayout so its size remains (0, 0), which means there is nothing to paint.

Try changing your code to:

JPanel panel1 = new JPanel();
panel1.setSize(200, 200);

and you will see the blue panel painted at the specified size.

Now try commenting out:

//panel2.setVisible(false); 

and you will see both panels. This is because as components are added to the panel they are assigned a ZOrder. Basically the last component added is painted first, which is why the blue panel is painted on top of the red panel. Check out the setComponentZOrder() method of the Container class for more information.

The CardLayout is probably the layout manager you should be using, but you can check out the Overlap Layout as well.

camickr