Search code examples
javaswinglayout-managerjlayeredpanenull-layout-manager

JLayeredPane not respecting layers


I have a JLayeredPane. My program works something like this:

JPanel p1 = new JPanel(new BoxLayout(p1, BoxLayout.X_AXIS));
JPanel p2 = new JPanel(new BoxLayout(p2, BoxLayout.Y_AXIS));
JLayeredPane lp = new JLayeredPane();
lp.add(p1, 1);
lp.add(p2, 0);

Both p1 and p2 have components like buttons, etc...

The issue is that when I add both JPanels to the JLayeredPane, NOTHING appears.

I tried changing the layout of the JLayeredPane().

For example, I did:

lp.setLayout(new BoxLayout(lp, BoxLayout.X_AXIS));

Then, the JPanels do show, but they are shown adjacent, not respecting the layers of the JLayeredPane.

Am I forced to use a null layout?

How can I make my JLayeredPane respect the layers and show my two BoxLayout JPanels correctly?

When I give my JLayeredPane a layout, it shows the panels, but it is not respecting the layers at all.


Solution

  • You need a layout manager which understands the Z-Axis. The default layout managers don't understand the Z-Axis of the JLayeredPane.

    If you simply want to overlay stuff on top of each other you can use a LayoutManager like this:

    JLayeredPane layeredFooPane = new JLayeredPane();
    // The magic!
    layeredFooPane.setLayout(new LayeredPaneLayout(layeredPane));
    // Add components:
    layeredFooPane.add(fooComponent, new Integer(JLayeredPane.DEFAULT_LAYER + 10));
    layeredFooPane.add(barComponent, JLayeredPane.DEFAULT_LAYER);
    

    LayoutManager Class:

    public class LayeredPaneLayout implements LayoutManager {
    
        private final Container target;
        private static final Dimension preferredSize = new Dimension(500, 500);
    
        public LayeredPaneLayout(final Container target) {
                this.target = target;
        }
    
        @Override
        public void addLayoutComponent(final String name, final Component comp) {
        }
    
        @Override
        public void layoutContainer(final Container container) {
                for (final Component component : container.getComponents()) {
                        component.setBounds(new Rectangle(0, 0, target.getWidth(), target.getHeight()));
                }
        }
    
        @Override
        public Dimension minimumLayoutSize(final Container parent) {
                return preferredLayoutSize(parent);
        }
    
        @Override
        public Dimension preferredLayoutSize(final Container parent) {
                return preferredSize;
        }
    
        @Override
        public void removeLayoutComponent(final Component comp) {
        }
    }