Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JRootpane-将glasspane设置为visible不会拦截鼠标事件_Java_Swing_Glasspane - Fatal编程技术网

Java JRootpane-将glasspane设置为visible不会拦截鼠标事件

Java JRootpane-将glasspane设置为visible不会拦截鼠标事件,java,swing,glasspane,Java,Swing,Glasspane,我在它里面有一个JFrame和一个JPanel层次结构,我想实现一个内部面板,我可以让它看起来“禁用”(而其他面板不会改变),也就是说,用一个半透明的灰色层覆盖它,截获所有发送到这个面板的鼠标甚至键盘事件。我一直在寻找解决办法,但还没有真正找到一个好办法 我得到的最接近解决方案是当我使用JRootPane时,每当我想禁用它时,我都会让它的玻璃窗格可见。玻璃窗格被设置为不透明,背景为半透明 我尝试的一个简单示例: public class Test extends JFrame { pri

我在它里面有一个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);
    }    
}

但问题是,即使玻璃在内容顶部可见,它也不会像文档中所描述的那样拦截到达内容的事件。

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

在文档中,它说

玻璃材质窗格玻璃

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

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

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

        @Override
        public void mousePressed(MouseEvent e)
        {
            e.consume();
        }
    });
    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();
        }
    });
您可以通过以下方式截获键盘事件:

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

        @Override
        public void mousePressed(MouseEvent e)
        {
            e.consume();
        }
    });
    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必须能够聚焦以拦截键盘事件。

请参阅我在shadowing Post上的评论,我认为对JComponents的操作是错误的,为什么不使用框架的
setGlassPane
?@CatalinaIsland,因为我不想只禁用特定的框架jpanel@Catalina他们在示例中没有这样做:@Ofek Ron java文档示例是关于在玻璃窗格上绘画的。如果你看到“MyGlassPane”类,他们有“CBListener”,它监听鼠标点击并在玻璃窗格上绘制一个“椭圆形”。但根据您的问题:用半透明的灰色层覆盖它,截取所有发送到此面板的鼠标甚至键盘事件。如果需要阻止事件,则需要“消费”它们。