当前位置: 首页 > 知识库问答 >
问题:

在带有BorderLayout的JPanel上方浮动JPanel

孙阳旭
2023-03-14

我有一个JPanel,名为PNLMain,布局设置为BorderLayout。在面板内部有三个jpanel,分别添加到page_startcenterpage_end。现在,我的要求是,如果单击Settings按钮,它将在PNLMain上方显示一个透明的JPanel。这个透明的面板将包含一个不透明的,更小的,居中的面板,其中将包含设置的东西。

我知道我可以使用jlayeredpane来实现这一点,但是查看教程,它说您只能使用绝对定位来放置不同深度的组件,我知道这是非常不鼓励的。

是否有其他方法可以做到这一点,而不使用绝对定位?

共有1个答案

濮阳功
2023-03-14

您可以使用父框架的玻璃窗格,这将允许您向其添加组件,这些组件将显示为覆盖在主内容上。

基本上,我会创建JPanel并将其设置为透明(Setopaque(false))。我会将它的布局管理器设置为类似gridbaglayout的内容(因为它将使用子组件的首选大小,并自动将其放在父容器中)。

然后在此面板上添加设置面板。

frame.getRootPane().setGlassPane(backingPane); // Or similar

看一下如何使用根窗格

更新

如果你自己不能使用顶层框架的玻璃窗格,那么你需要伪造它。

如果将mouselistenerkeylistener添加到背景窗格,则可以使用传递到子组件的事件。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;

public class FloatingPane {

    public static void main(String[] args) {
        new FloatingPane();
    }

    public FloatingPane() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                final WorkPane workPane = new WorkPane();
                JButton settings = new JButton("Settings");
                settings.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        workPane.toggleSettings();
                    }
                });

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(workPane);
                frame.add(settings, BorderLayout.SOUTH);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class WorkPane extends JLayeredPane {
        private final BackingPane backingPane;

        public WorkPane() {

            setLayout(new GridBagLayout());

            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 1;
            gbc.gridy = 0;
            gbc.weightx = 1;
            gbc.weighty = 1;
            gbc.fill = GridBagConstraints.BOTH;
            add(createLabel("Center", Color.BLUE), gbc);

            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.weightx = 0;
            gbc.weighty = 0;
            gbc.fill = GridBagConstraints.VERTICAL;
            add(createLabel("Left", Color.RED), gbc);
            gbc.gridx = 2;
            add(createLabel("Right", Color.GREEN), gbc);

            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.weightx = 1;
            gbc.weighty = 1;
            gbc.gridheight = GridBagConstraints.REMAINDER;
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.fill = GridBagConstraints.BOTH;

            backingPane = new BackingPane();
            backingPane.add(new SettingsPane());
            backingPane.setVisible(false);
            add(backingPane, gbc);

            setLayer(backingPane, DEFAULT_LAYER + 1);

        }

        public void toggleSettings() {

            backingPane.setVisible(!backingPane.isVisible());

        }

        protected JLabel createLabel(String text, Color bg) {

            JLabel label = new JLabel(text);
            label.setHorizontalAlignment(JLabel.CENTER);
            label.setOpaque(true);
            label.setBackground(bg);

            return label;

        }
    }

    public class BackingPane extends JPanel {

        public BackingPane() {
            setLayout(new GridBagLayout());
            setOpaque(false);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(new Color(128, 128, 128, 192));
            g.fillRect(0, 0, getWidth(), getHeight());
        }

    }

    public class SettingsPane extends JPanel {

        public SettingsPane() {

            setBorder(new EmptyBorder(10, 10, 10, 10));
            add(new JLabel("Settings"));

        }
    }
}

另一个解决方案可能是通过对当前面板进行快照并使用cardlayout,翻转到设置窗格,将快照作为设置窗格的背景图像(然后可以将效果应用到灰度缩放和模糊),从而伪造整个玻璃窗格

 类似资料:
  • 我的问题是:我在JPanel中显示了一个JLabel的数组列表和一个JPanel的按钮,当我按下按钮时,我想在JLabel的上方显示我的JPanel。但是当我按下按钮时,我的JPanel在标签下面。 请不要告诉我使用JLayerPane,因为如果我可以不用它,那将是最好的。感谢您的解决方案。 这是我的代码的一个例子:要运行这个,请在这里找到图像100x100: http://www.html5ga

  • 你好,我实际上正在尝试从jPanel切换到我的JFrame中的另一个jPanel。我已经更改了我的代码,下面是我遵循以下内容的样子:

  • 基本上,我想做的是添加2张图片,并排在JGroup的中心和JBoard右侧的JLabel,所以我被告知将JGroup的布局设置为BorderLayout并添加带有BorderLayout的图片。CENTER和带有BorderLayout的JLabel。东方。 事实上,结果是图片在JPanel的左侧,JLabel在JPanel的右侧。 非常感谢您的帮助!

  • 我的愿望是当屏幕尺寸减小时,上会出现溢出滚动条。 它在Firefox上是这样做的,然而,背景并没有覆盖滚动条右侧的内容。 此外,IE和Chrome都向下推,甚至不显示滚动条。 编辑下面的图片显示了我想要的外观。请注意,有一个滚动条。 https://output.jsbin.com/huwagajome

  • 问题内容: 有去除任何方式加入的一个,而不必引用本身? 问题答案: 像这样吗

  • 问题内容: 我实现了一个弹出框,可动态显示搜索选项。我希望该框“浮动”在所有网站内容之上。当前,当显示该框时,它将替换其下方的所有内容,并且看起来很糟。 我相信我已经尝试将box的div的z-index设置为高于其余页面内容的z-index,但是仍然没有运气。 问题答案: 您要使用绝对定位。 绝对位置元素相对于具有非静态位置的第一个父元素放置。如果找不到此类元素,则包含的块为html 例如 : 要