2

その中に 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);
    }    
}

しかし問題は、ガラスがコンテンツの上に表示されている場合でも、ここに記載されているように、イベントがコンテンツに到達するのをインターセプトしないことです。

4

1 に答える 1

3

テストクラスでは、イベントをインターセプトするように指示していないため、グラスペインはイベントをインターセプトしません (イベントのインターセプトはデフォルトの動作ではありません)。

ドキュメントリンクでは、それは言う

ガラス板

ガラス ペインは、イベントをキャッチしたり、1 つ以上のコンポーネントが既に含まれている領域をペイントしたりできるようにする場合に便利です。たとえば、ガラス ペインでイベントをインターセプトすることにより、マルチコンポーネント領域のマウス イベントを非アクティブ化できます。または、ガラス ペインを使用して、複数のコンポーネント上に画像を表示できます。

この方法でマウス イベントをインターセプトできます。

    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 がフォーカス可能である必要があります。

于 2014-11-04T19:16:23.243 に答える