Java 如何在被打开的JDialog阻止的窗口上捕获鼠标单击事件

Java 如何在被打开的JDialog阻止的窗口上捕获鼠标单击事件,java,swing,jdialog,modality,Java,Swing,Jdialog,Modality,简单地说,我想要的是在被模态JDialog阻塞的窗口上捕捉鼠标单击 以下是一个例子: public class BlockedFrameTest { public static void main ( final String[] args ) { Toolkit.getDefaultToolkit ().addAWTEventListener ( new AWTEventListener () { @Override

简单地说,我想要的是在被模态JDialog阻塞的窗口上捕捉鼠标单击

以下是一个例子:

public class BlockedFrameTest
{
    public static void main ( final String[] args )
    {
        Toolkit.getDefaultToolkit ().addAWTEventListener ( new AWTEventListener ()
        {
            @Override
            public void eventDispatched ( final AWTEvent event )
            {
                if ( event instanceof MouseEvent )
                {
                    System.out.println ( event );
                }
            }
        }, AWTEvent.MOUSE_EVENT_MASK );

        final JFrame frame = new JFrame ( "Frame" );
        frame.add ( new JLabel ( "Content" )
        {
            {
                setBorder ( BorderFactory.createEmptyBorder ( 100, 100, 100, 100 ) );
            }
        } );
        frame.pack ();
        frame.setLocationRelativeTo ( null );
        frame.setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE );
        frame.setVisible ( true );

        final JDialog dialog = new JDialog ( frame, "Dialog" );
        dialog.setModal ( true );
        dialog.add ( new JLabel ( "Content" )
        {
            {
                setBorder ( BorderFactory.createEmptyBorder ( 50, 50, 50, 50 ) );
            }
        } );
        dialog.pack ();
        dialog.setLocationRelativeTo ( frame );
        dialog.setVisible ( true );
    }
}
通过查看示例输出日志,您将看到当打开JDialog时,JFrame中的事件不会被传递(甚至不会传递到示例中添加的全局AWT事件侦听器中)

所以我想知道-有什么方法可以捕捉到被阻止的JFrame上的点击吗?
或者至少在用户“触摸”被阻止的内容时捕获事件

我之所以需要它,是为了在此类事件发生时使自定义装饰的JDialog blick。

也许这有助于:


这有点困难,因为您要离开Swing领域,进入本机GUI域。

我认为如果您的
JDialog
是模态的,您就不能这样做,但您可以使用
FocusListener的下一个技巧:

import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.BorderFactory;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class Example {
    public static void main(final String[] args) {

        final JFrame frame = new JFrame("Frame");
        final JDialog dialog = new JDialog(frame, "Dialog");
        frame.add(new JLabel("Content") {
            {
                setBorder(BorderFactory.createEmptyBorder(100, 100, 100, 100));
            }
        });
        frame.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent arg0) {
                System.out.println("frame pressed");
                System.out.println("dialog focused " + dialog.isFocused());
                System.out.println("frame focused " + frame.isFocused());
                super.mousePressed(arg0);
            }
        });
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);


        dialog.add(new JLabel("Content") {
            {
                setBorder(BorderFactory.createEmptyBorder(50, 50, 50, 50));
            }
        });
        dialog.addFocusListener(new FocusAdapter() {
            @Override
            public void focusLost(FocusEvent arg0) {
                super.focusLost(arg0);
                dialog.requestFocus();
            }
        });
        dialog.pack();
        dialog.setLocationRelativeTo(frame);
        dialog.setVisible(true);
    }
}
和输出:

frame pressed
dialog focused true
frame focused false

我知道使用本机特性捕获此类事件可能是一个解决方案,但我不会使用它,因为它只会在代码中添加大量混乱,并会使其在某一天无法维护-我宁愿保持纯java.hmm的难度。一旦你在应用程序外单击,从技术上讲,你就不再是Java世界了。不是真的,我只是在单击同一Java应用程序的另一部分-我提到,我只需要在用户单击对话框阻止的同一应用程序的其他部分时捕捉事件,没有在系统中启动另一个随机应用程序。如果用户也在底层框架之外单击,该怎么办?它们会被忽略吗?是的,我真的不在乎应用程序之外的点击,因为它们甚至不必在对话框上产生“闪烁”效果。在我的示例中,当你点击框架时,看看Windows(我指的是操作系统)装饰是如何工作的。这会使与框架内容的交互成为可能,这是一件坏事。而且它不会完全模仿模态,所以我宁愿避免使用这种技巧。我知道,但我宁愿使用模态JDialog,而不是一些变通方法,因为它更方便,可以(肯定)在不同的平台上正常工作,并且不需要任何代码来支持。