【问题标题】:How to make a JPanel display over another JPanel when moved?移动时如何使 JPanel 显示在另一个 JPanel 上?
【发布时间】:2015-10-16 22:04:57
【问题描述】:

我创建了一个纸牌游戏,它允许用户移动纸牌,它们是 JPanel,彼此叠放。但是,我注意到如果我试图将一张卡片移动到另一张卡片的确切位置(即在它上面),那张卡片将不会总是显示在该卡片的顶部。

例如,假设我们有 5 张卡片,它们按顺序构建。

如果将 card1 移动到 card2 的位置,那么 card1 将出现在 card2 的顶部。但是,如果我尝试将 card5 移动到 card3 的位置,那么 card5 将出现在 card3 的下方。

我怎样才能使我移动的最后一张牌成为最上面的一张?

【问题讨论】:

  • 你有一个 z 排序问题,考虑看看 JLayeredPane

标签: java swing user-interface


【解决方案1】:

但是,我注意到,如果我尝试将一张卡片移动到另一张卡片的确切位置(即在其顶部),该卡片将不会始终显示在该卡片的顶部。

这听起来与组件的 Z 顺序有关。基本上 Swing 的默认行为是首先绘制添加到面板的最后一个组件。

所以在面板上添加卡片时需要更改 Z-Order。您可能正在使用如下代码:

 panel.add( card );

简单的解决方案是使用:

panel.add(0, card);

或者,当您点击卡片时处理 mousePressed() 事件时,您将使用:

Component child = event.getComponent();
Component parent = child.getParent();
parent.setComponentZOrder(child, 0);

您可能还想查看Overlap Layout,它更多地解释了 Z-Ordering,并提供了一个布局管理器,可以让您堆叠卡片。

【讨论】:

    【解决方案2】:

    为此目的,卡片布局是您的朋友。

    如何使用卡片布局https://docs.oracle.com/javase/tutorial/uiswing/layout/card.html

    使用示例:

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    public class CardLayoutDemo implements ItemListener {
        JPanel cards; //a panel that uses CardLayout
        final static String BUTTONPANEL = "Card with JButtons";
        final static String TEXTPANEL = "Card with JTextField";
    
        public void addComponentToPane(Container pane) {
            //Put the JComboBox in a JPanel to get a nicer look.
            JPanel comboBoxPane = new JPanel(); //use FlowLayout
            String comboBoxItems[] = { BUTTONPANEL, TEXTPANEL };
            JComboBox cb = new JComboBox(comboBoxItems);
            cb.setEditable(false);
            cb.addItemListener(this);
            comboBoxPane.add(cb);
    
            //Create the "cards".
            JPanel card1 = new JPanel();
            card1.add(new JButton("Button 1"));
            card1.add(new JButton("Button 2"));
            card1.add(new JButton("Button 3"));
    
            JPanel card2 = new JPanel();
            card2.add(new JTextField("TextField", 20));
    
            //Create the panel that contains the "cards".
            cards = new JPanel(new CardLayout());
            cards.add(card1, BUTTONPANEL);
            cards.add(card2, TEXTPANEL);
    
            pane.add(comboBoxPane, BorderLayout.PAGE_START);
            pane.add(cards, BorderLayout.CENTER);
        }
    
        public void itemStateChanged(ItemEvent evt) {
            CardLayout cl = (CardLayout)(cards.getLayout());
            cl.show(cards, (String)evt.getItem());
        }
    
        /**
         * Create the GUI and show it.  For thread safety,
         * this method should be invoked from the
         * event dispatch thread.
         */
        private static void createAndShowGUI() {
            //Create and set up the window.
            JFrame frame = new JFrame("CardLayoutDemo");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            //Create and set up the content pane.
            CardLayoutDemo demo = new CardLayoutDemo();
            demo.addComponentToPane(frame.getContentPane());
    
            //Display the window.
            frame.pack();
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            javax.swing.SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    createAndShowGUI();
                }
            });
        }
    }
    

    您可以轻松修改它以实现您的目标。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-18
      • 1970-01-01
      • 2019-06-08
      • 2014-12-30
      • 2021-01-29
      • 1970-01-01
      相关资源
      最近更新 更多