在Java(SWING)中将JPanel置于其他对象前面

7
我希望在应用程序处理时显示一个加载消息,所以我在JTree上方使用了一个JPanel。但是当用户单击JPanel时,JTree会被选择,而JPanel会到后面。隐藏JPanel后,它再也不会显示。我不知道为什么,但它似乎永远不会在JTree前面。
我需要一种方法将JPanel置于所有元素之前。我该怎么做?
编辑:还必须提到,我不想使用JDialog。我想在任何元素的顶部使用JPanel显示加载消息,直到进程完成。

2
你应该使用JDialog而不是JPanel,因为你可以设置它的模态性。 - mre
1
另外我必须提到,我不想使用JDialog。我想要使用JPanel在任何元素的顶部显示一个加载状态,直到进程完成。什么?JDialog可以免费完成所有这些工作。您能否请说明为什么要使用JPanel而不是JDialog - mre
7个回答

8
这里至少有两种解决方案。要么按照@Geoff和@sthupahsmaht的建议去做。顺便说一下,还可以使用JOptionPane自动为您创建对话框。

另一个选择是从框架中使用GlassPane。

或者,如@jzd所建议的那样,使用JLayeredPane。

编辑: 示例显示如何使用GlassPane捕获用户选择。 请尝试按照以下步骤进行:

1.在开始时单击玻璃窗格。查看输出。

2.右键单击它。这会隐藏玻璃板。

3.单击内容窗格。查看输出。

4.右键单击它。回到第1步。 享受吧。

import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class OverPanel extends JPanel
{   
    private static void createAndShowGUI()
    {
        final JFrame f = new JFrame();
        f.setPreferredSize(new Dimension(400, 300));
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);       
        JPanel glassPanel = new JPanel();
        glassPanel.setBackground(Color.RED);        
        glassPanel.addMouseListener(new MouseAdapter()
        {
            @Override
            public void mousePressed(MouseEvent e)
            {
                super.mousePressed(e);
                System.out.println("f.getGlassPane() mousePressed");
                if(e.getButton() == MouseEvent.BUTTON3)
                    f.getGlassPane().setVisible(false);
            }
        });
        f.setGlassPane(glassPanel);     

        f.getContentPane().setBackground(Color.GREEN);
        f.getContentPane().addMouseListener(new MouseAdapter()
        {
            @Override
            public void mousePressed(MouseEvent e)
            {
                super.mousePressed(e);
                System.out.println("f.getContentPane() mousePressed");
                if(e.getButton() == MouseEvent.BUTTON3)
                    f.getGlassPane().setVisible(true);
            }
        });
        f.getGlassPane().setVisible(true);
        f.pack();
        f.setVisible(true);
    }

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI();
            }
        });
    }
}

编辑2:如果您想要实现对话框的效果,您可以通过适当地将此代码合并到我的示例中来实现。

        JPanel panel = new JPanel(new GridLayout(0, 1));
        panel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
        panel.setBackground(Color.YELLOW);
        panel.add(new JLabel("I am message Label"));
        panel.add(new JButton("CLOSE"));
        JPanel glassPanel = new JPanel(new GridBagLayout());
        glassPanel.setOpaque(false);
        glassPanel.add(panel);

5

+1 @jzd 我忘了这个。但是如果面板比树小,我想它不会完全解决模态问题。因此,我认为在这里使用对话框更合适。 - Boro
@Boro,我同意,对话框似乎是最合适的选择,但问题明确表示“我不想要JDialog”。 - jzd
是的,我同意。现在可以了,但当我回答时还不行 :) - Boro
@Boro,是的,当我第一次回答时也没有说到这一点。 - jzd

2

1

这个确实更适合作为注释。 - mre
谢谢你的建议。下次我会这样做。 - Geoff

0

0
对于那些没有使用JDialog遇到问题的人来说,这是确保它能够显示出来的方法。但请务必注意,如果对话框是模态的,在处理关闭、设置焦点等方面要进行适当的控制。
JDialog dialog = new JDialog();
dialog.setAlwaysOnTop(true);

0
Jpanel main = new JPanel();
Jpanel a = new JPanel();
JPanel b = new Jpanel();

main.add(a);
main.add(b);

此时该对象:

a -> 0 ( index)
b -> 1 (index)

main.getComponentCount() = 2

main.setComponentZorder(b,0);


a -> 1
b -> 0;

b OVER
a DOWN

2
请使用代码格式使文本更易读。 - span

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接