JRootpane - 将玻璃窗格设置为可见不会拦截鼠标事件

时间:2014-11-03 12:16:39

标签: java swing glasspane

我有一个JFrame和一个JPanel层次结构,我想实现一个内部面板,我可以让它看起来"禁用"(而其他面板不会改变),也就是说,覆盖它一个半透明的灰色层,拦截所有鼠标,甚至可能是调度到这个面板的键盘事件。香港专业教育学院一直在寻找一个解决方案,并没有找到一个好的解决方案。

我最接近解决方案的是当我使用JRootPane时,每当我想要它禁用时,我都可以看到它的玻璃板。玻璃板已被设置为不透明且具有半透明背景。

我尝试的一个简单例子:

public class Test extends JFrame {
    private final JPanel jPanel;

    public Test() {
        jPanel = new JPanel();
        final JButton jButton = new JButton("Hidden");
        jButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("hidden is clicked!");
            }
        });
        final JRootPane jRootPane = new JRootPane();
        jPanel.add(jRootPane);
        final JPanel glassPane = new JPanel();
        final JButton jButton2 = new JButton();
        jButton2.addActionListener(new ActionListener() {
            private boolean visible = true;

            @Override
            public void actionPerformed(ActionEvent e) {
                glassPane.setVisible(visible = !visible);
            }
        });
        jPanel.add(jButton2);

        jRootPane.getContentPane().add(new JScrollPane(jButton));
        glassPane.setBackground(new Color(0.5f, 0.5f, 0.5f, 0.2f));
        glassPane.setOpaque(true);
        jRootPane.setGlassPane(glassPane);
        glassPane.setVisible(true);
        getContentPane().add(jPanel);    
    }

    public static void main(String[] strings) {
        final Test test = new Test();
        test.pack();
        test.setVisible(true);
    }    
}

但问题是,即使在内容的顶部可以看到玻璃,它也不会截取事件,因为它应该按照原样here截取内容。

1 个答案:

答案 0 :(得分:3)

在您的测试类中,您的玻璃板不会拦截事件,因为您没有告诉它拦截事件(拦截事件不是默认行为)。

在文档link中,它说

  

玻璃窗格

     

当您希望能够捕获事件或绘制已包含一个或多个组件的区域时,玻璃窗格非常有用。例如,通过让玻璃窗格拦截事件,可以停用多组件区域的鼠标事件。或者,您可以使用玻璃窗格在多个组件上显示图像。

您可以通过以下方式拦截鼠标事件

    glassPane.addMouseListener(new MouseAdapter()
    {
        @Override
        public void mouseClicked(MouseEvent e)
        {
            e.consume();
        }

        @Override
        public void mousePressed(MouseEvent e)
        {
            e.consume();
        }
    });

您可以通过以下方式拦截KeyBoard事件

    glassPane.setFocusable(true);
    glassPane.addKeyListener(new KeyListener()
    {
        @Override
        public void keyTyped(KeyEvent e)
        {
            e.consume();
        }

        @Override
        public void keyReleased(KeyEvent e)
        {
            e.consume();
        }

        @Override
        public void keyPressed(KeyEvent e)
        {
            e.consume();
        }
    });

注意:JPanel必须能够拦截键盘事件。