加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 使用BorderLayout在JPanel上方浮动JPanel

发布时间:2020-12-15 04:11:32 所属栏目:Java 来源:网络整理
导读:我有一个名为pnlMain的JPanel,其布局设置为BorderLayout.在面板内部有三个JPanel添加到PAGE_START,CENTER和PAGE_END.现在,我的要求是如果单击“设置”按钮,它将在pnlMain上方显示透明的JPanel.然后,这个透明面板将包含一个不透明,较小的居中面板,它将包含设
我有一个名为pnlMain的JPanel,其布局设置为BorderLayout.在面板内部有三个JPanel添加到PAGE_START,CENTER和PAGE_END.现在,我的要求是如果单击“设置”按钮,它将在pnlMain上方显示透明的JPanel.然后,这个透明面板将包含一个不透明,较小的居中面板,它将包含设置内容.

我知道我可以使用JLayeredPane来做到这一点,但是看看tutorial它说你只能使用绝对定位放置不同深度的组件,我知道这是非常气馁的.

如果不使用绝对定位,还有其他方法吗?

解决方法

您可以使用父框架的玻璃窗格,这将允许您向其添加看似覆盖在主要内容上的组件.

基本上,我会创建一个JPanel并将其设置为透明(setOpaque(false)).我会将它的布局管理器设置为GridBagLayout(因为它将使用子组件的首选大小并将其自动居中在其父容器中).

在这个面板上,我将添加“设置”面板.

最后,我将父框架的玻璃窗格设置为第一个(支持)窗格并使其可见.

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

看看How to use Root Panes

更新

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

此示例基本上使用由GridBagLayout支持的JLayeredPane

如果将MouseListener和KeyListener添加到背景窗格,则可以使用转发到子组件的事件.

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,192));
            g.fillRect(0,getWidth(),getHeight());
        }

    }

    public class SettingsPane extends JPanel {

        public SettingsPane() {

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

        }
    }
}

另一个解决方案可能是通过拍摄当前面板的快照并使用CardLayout伪装整个玻璃窗格,翻转到设置窗格,使用快照拍摄作为设置窗格的背景图像(然后可以将效果应用于喜欢灰色缩放和模糊)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读