2

I'm attempting to overlap JPanel instances. Put a panel directly on another, in the exact same position and exact size. Every time I do this it moves the other panel to the other side or underneath, the previous panel is inside another much larger one and has buttons in it.

How would I do this? Keep in mind it's using the Window Builder tool.

mKorbel
  • 109,525
  • 20
  • 134
  • 319
Hydra
  • 61
  • 2
  • 11
  • 3
    *"Keep in mind it's using the Window Builder tool."* It is important to understand the underlying layouts and components before any window builder can be used effectively. See particularly [Laying Out Components Within a Container](http://docs.oracle.com/javase/tutorial/uiswing/layout/) & [Using Swing Components](http://docs.oracle.com/javase/tutorial/uiswing/components/index.html). – Andrew Thompson Nov 18 '12 at 02:17

3 Answers3

9

You might also want to look at OverlayLayout, seen here. It's not included in the conventional gallery, but it may be of interest.

Overlay Sample

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.OverlayLayout;

/** @see http://stackoverflow.com/a/13437388/230513 */
public class OverlaySample {

    public static void main(String args[]) {
        JFrame frame = new JFrame("Overlay Sample");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel panel = new JPanel();
        panel.setLayout(new OverlayLayout(panel));
        panel.add(create(1, "One", Color.gray.brighter()));
        panel.add(create(2, "Two", Color.gray));
        panel.add(create(3, "Three", Color.gray.darker()));
        frame.add(panel, BorderLayout.CENTER);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private static JLabel create(final int index, String name, Color color) {
        JLabel label = new JLabel(name) {
            private static final int N = 64;

            @Override
            public boolean isOpaque() {
                return true;
            }

            @Override
            public Dimension getPreferredSize() {
                return new Dimension(index * N, index * N);
            }

            @Override
            public Dimension getMaximumSize() {
                return new Dimension(index * N, index * N);
            }
        };
        label.setHorizontalAlignment(JLabel.RIGHT);
        label.setVerticalAlignment(JLabel.BOTTOM);
        label.setBackground(color);
        label.setAlignmentX(0.0f);
        label.setAlignmentY(0.0f);
        return label;
    }
}
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
5

I'm attempting to overlap JPanels

Use a JLayeredPane (image below from the linked tutorial).

JLayeredPane

Put a JPanel directly on another,

..or a CardLayout as shown here..

..depending on which of those two you mean, since I understand them as quite different effects.

Community
  • 1
  • 1
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • Thanks guys, I did it... however I have one problem, the panel_2 is successfully on panel_1 exactly but, the sub-panels that are located inside panel_1 are showing up when I click the button to go onto panel_2... basically its a menu I clicked on Button 1 and Panel_1 comes up with sub-panels inside it, then click button 2 and Panel_2 shows up but, every time I go over panel_2 once the programs running the other sub-panels from panel_1 pop up out of no where while hovering over panel_2.... any suggestions? – Hydra Nov 18 '12 at 03:56
  • @AkeebKhan: You can [answer your own question](http://meta.stackexchange.com/q/17463/163188). – trashgod Nov 18 '12 at 04:12
  • *"any suggestions?"* For better help sooner, post an [SSCCE](http://sscce.org/). – Andrew Thompson Nov 18 '12 at 04:36
  • Did what? The only SSCCE I see is the one [posted by @trashgod](http://stackoverflow.com/a/13437388/418556). Where is *your* SSCCE? – Andrew Thompson Nov 18 '12 at 05:19
4

Use a JDesktopPane (or its superclass JLayeredPane) as its content, adding to the pane.

See How to Use Internal Frames for examples.

InternalFrameDemo


Here you can see a nice way of letting components overlay, and pop up when the cursor rests on it:

import javax.swing.*;

import java.awt.*;
import java.awt.event.*;

public class ShiftedStackPanel extends JPanel implements MouseListener,
                                                            ActionListener {

    private static final long serialVersionUID = 1988454751139668485L;

    private int layer;
    private JDesktopPane desktopPane;
    private Timer timer;
    private Component currentComponent;
    private int layerOfCurrent;
    private int shiftDivision;

    public ShiftedStackPanel() {
        this(4);
    }

    public ShiftedStackPanel(int shift) {
        shiftDivision = shift;

        setLayout(new BorderLayout(0, 0));

        desktopPane = new JDesktopPane();
        desktopPane.setBackground(SystemColor.window);
        super.add(desktopPane);
        timer = new Timer(1000, this);
        timer.setRepeats(false);

    }

    public Component add(Component c) {
        Dimension dim = c.getPreferredSize();
        c.setBounds(
                (desktopPane.getComponentCount() * (dim.width / shiftDivision)),
                0, dim.width, dim.height);
        desktopPane.add(c, new Integer(++layer));
        c.addMouseListener(this);
        return c;
    }

    public void remove(Component c) {
        throw new IllegalArgumentException(
                "Removal of component, not yet supported.");
        // FIXME: allow removal, and shift all latter comps, to left
    }

    public void removeAll() {
        desktopPane.removeAll();
    }

    public static void main(String[] args) {
        JFrame f = new JFrame("JFrame Wrapper");
        ShiftedStackPanel p;
        f.setContentPane(p = new ShiftedStackPanel(4));
        p.add(new JTextField("ABCDEFGHI"));
        p.add(new JTextField("DEFGHIJKL"));
        p.add(new JTextField("GHIJKLMNO"));
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);
        f.setMinimumSize(new Dimension(400, 200));
        f.setLocationRelativeTo(null);
    }

    @Override
    public void mouseClicked(MouseEvent evt) {
        if (currentComponent != null) {
            Component c = (Component) evt.getSource();
            currentComponent = c;
            layerOfCurrent = desktopPane.getLayer(c);
            desktopPane.remove(c);
            desktopPane.add(c, new Integer(100));
        }
    }

    @Override
    public void mouseEntered(MouseEvent evt) {
        timer.start();
        Component c = (Component) evt.getSource();
        currentComponent = c;
        layerOfCurrent = desktopPane.getLayer(c);
    }

    @Override
    public void mouseExited(MouseEvent evt) {
        if ((currentComponent != null) && currentComponent == evt.getSource()) {
            desktopPane.remove(currentComponent);
            desktopPane.add(currentComponent, new Integer(layerOfCurrent));
            currentComponent = null;
            timer.stop();
        }
    }

    @Override
    public void mousePressed(MouseEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseReleased(MouseEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void actionPerformed(ActionEvent arg0) {

        desktopPane.remove(currentComponent);
        desktopPane.add(currentComponent, new Integer(100));
    }
}

Still has some problems, when using components that require focus, but should work well with JLabel, and JPanel.

Mordechai
  • 15,437
  • 2
  • 41
  • 82