Eclipse WindowBuilder, overlapping JPanels

百般思念 提交于 2019-11-26 12:33:17

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

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;
    }
}
Andrew Thompson

I'm attempting to overlap JPanels

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

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.

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

See How to Use Internal Frames for examples.


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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!