本文介绍了Java Swing:结合CardLayout和JLayeredPane的效果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图将一个JPanel放在另一个之上,完全重叠.我使用JLayeredPane将它们设置为不同的深度",因此可以更改深度和不透明度,以查看某个面​​板在另一个"下方.这是我所做的一个小测试,可以正常运行:

I am trying to place some JPanels one on top of the other, completely overlapping.I use JLayeredPane to have them in different "depth" so I can change the depth and opacity to see a certain panel "under" another.Here is a small test I did which is working properly:

    public class LayeredCardPanel extends JPanel  {

        private static final String BLUE_PANEL     =  "blue   ";
        private static final String RED_PANEL      =  "red     ";
        private static final String GREEN_PANEL    =  "green";

        private String[] panelNames = { BLUE_PANEL, RED_PANEL, GREEN_PANEL };
        private Color[] panelColors = { Color.BLUE, Color.RED,  Color.GREEN };

        private List<JPanel> panels = new ArrayList<>();

        private final int TOP_POSITION = 30;
        private static final int PANELS_FIRST_POS = 10;

        private JLayeredPane layeredPane;


        public LayeredCardPanel()    {

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

            add(createControlPanel());

            layeredPane = new JLayeredPane();

            ////////////////////////////////////////////////////////////////
            //setting layout here results in all grey, non functioning panel.
            //layeredPane.setLayout(new CardLayout(0, 0));
            //////////////////////////////////////////////////////////////

            add(layeredPane);

            //adding 3 panel
            for (int i = 0; i < panelNames.length; i++) {

                JPanel panel = new JPanel();
                panel.setBackground(panelColors[i]);

                layeredPane.add(panel);
                layeredPane.setLayer(panel, PANELS_FIRST_POS + i);

                panels.add(panel);
            }

            ////////////////////////////////////////////////////////////
            //setting the card here, after adding panels, works fine
            layeredPane.setLayout(new CardLayout(0, 0));
            //////////////////////////////////////////////////////////
        }

测试结果如下:

The test result looks like this:

正如您在//////注释行之间看到的那样,仅当我在添加JPanel s后将CardLayout设置为JLayeredPane 后,此测试才能正常工作做到这一点.在我看来,JPanel是使用默认布局管理器添加到JLayeredPane的.布局(设置和更改边界以填充JLayeredPane)由稍后应用的CardLayout完成.

As you can see in between the ////// commented line, this test works fine only if I set CardLayout to the JLayeredPane after I add the JPanels to it.It seems to me that the JPanels are added to the JLayeredPane using the default layout manager. The layout (setting and changing bounds to fill the JLayeredPane) is done by the later-applied CardLayout.

我的问题是:尽管这可以按我的需要工作,但解决方案(使用一个布局管理器添加,然后替换它以实现所需的布局)看起来不是一个很好的解决方案.我正在寻找更好的方法来做到这一点.

My question is: although this is working as I need, the solution (using one layout manager to add, and then replacing it to achieve the layout I want) does not look an elegant solution. I am looking for better ways to do it.

这是整个SSCE:

    public class LayeredCardPanel extends JPanel  {

        private static final String BLUE_PANEL     =  "blue   ";
        private static final String RED_PANEL      =  "red     ";
        private static final String GREEN_PANEL    =  "green";

        private String[] panelNames = { BLUE_PANEL, RED_PANEL, GREEN_PANEL };
        private Color[] panelColors = { Color.BLUE, Color.RED,  Color.GREEN };

        private List<JPanel> panels = new ArrayList<>();

        private final int TOP_POSITION = 30;
        private static final int PANELS_FIRST_POS = 10;

        private JLayeredPane layeredPane;

        public LayeredCardPanel()    {

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

            add(createControlPanel());

            layeredPane = new JLayeredPane();

            add(layeredPane);

            //add 3 panel
            for (int i = 0; i < panelNames.length; i++) {

                JPanel panel = new JPanel();
                panel.setBackground(panelColors[i]);

                layeredPane.add(panel);
                layeredPane.setLayer(panel, PANELS_FIRST_POS + i);

                panels.add(panel);
            }

            layeredPane.setLayout(new CardLayout());
        }

        private JPanel createControlPanel() {

            ActionListener aListener = new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {

                    if(e.getSource() instanceof JButton ) {

                        moveToTop(((JButton) e.getSource()).getActionCommand() );
                    }
                }
            };

            JPanel controls = new JPanel();
            controls.setLayout(new BoxLayout(controls, BoxLayout.Y_AXIS));

            JButton blueViewBtn = new JButton(BLUE_PANEL);
            blueViewBtn.setActionCommand(BLUE_PANEL);
            blueViewBtn.addActionListener(aListener);
            controls.add(blueViewBtn);

            JButton redViewBtn = new JButton(RED_PANEL);
            redViewBtn.setActionCommand(RED_PANEL);
            redViewBtn.addActionListener(aListener);
            controls.add(redViewBtn);

            JButton greenViewBtn = new JButton(GREEN_PANEL);
            greenViewBtn.setActionCommand(GREEN_PANEL);
            greenViewBtn.addActionListener(aListener);
            controls.add(greenViewBtn);

            return controls;
        }

        private void moveToTop(String panelName) {

            for(int i = 0; i < panelNames.length; i++) {

                if(panelNames[i].equals(panelName)) {
                    layeredPane.setLayer(panels.get(i),TOP_POSITION);
                } else {
                    layeredPane.setLayer(panels.get(i), PANELS_FIRST_POS + i);
                }
            }
        }

        public static void main(String[] args) {

            javax.swing.SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {

                    JFrame frame = new JFrame("Layered Card Panel Simulation");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                    JComponent newContentPane = new LayeredCardPanel();
                    newContentPane.setPreferredSize(new Dimension(300,100));
                    frame.setContentPane(newContentPane);

                    frame.pack();
                    frame.setVisible(true);
                }
            });
        }
     }

推荐答案

我应用的解决方案如下:我更改了承包商,因此layeredPane使用自定义布局管理器Layout():

The solution I applied is the following: I changed the contractor so layeredPane uses custom layout manager Layout() :

        public LayeredCardPanel()    {

            setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
            add(createControlPanel());

            layeredPane = new JLayeredPane();
            layeredPane.setLayout(new Layout());
            add(layeredPane);

            //add 3 panel
            for (int i = 0; i < panelNames.length; i++) {

                JPanel panel = new JPanel();
                panel.setBackground(panelColors[i]);

                layeredPane.add(panel);
                layeredPane.setLayer(panel, PANELS_FIRST_POS + i);

                panels.add(panel);
            }
        }

Layout()扩展了CardLayout覆盖了addLayoutComponent却什么也不做:

Layout() extends CardLayout overriding addLayoutComponent to do nothing:

    class Layout extends CardLayout{

        @Override
        public void addLayoutComponent(String name, Component comp) {
            // override to do nothing
        }
    }

这篇关于Java Swing:结合CardLayout和JLayeredPane的效果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 13:21