在窗口任何地方检测鼠标点击

3
我写了一个JWindow,类似于我的应用程序中的精美菜单,当用户按下按钮时弹出。然而,如果用户在主窗口中的任何地方单击,我希望它消失。当然,我可以向主窗口添加鼠标监听器,但这并不会将其添加到窗口本身上的所有组件中,而且循环遍历所有组件似乎有点蛮力的解决方案(如果窗口上的组件发生更改,则无法保证其有效)。
如何最好地处理这样的事情?

2个回答

5
尝试使用Toolkit.getDefaultToolkit().addAWTEventListener(listener, eventMask)。找到过滤仅限鼠标点击的eventMask。这个AWT监听器是整个应用程序的全局监听器,因此您可以看到发生的所有事件。

1
+1 只是要注意:在安全受限的环境中可能无法正常工作。 - kleopatra
@kleopatra,您是绝对正确的(+1)。权限在“addAWTEventListener()”中进行检查。所以,这是限制。 - AlexR

3
如果用户在主窗口的任何位置单击,我希望它消失。
为子窗口添加WindowListener,然后处理windowDeactivated()事件并在子窗口上调用setVisible(false)。
工作示例:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class DialogDeactivated
{
    public static void main(String[] args)
    {
        final WindowListener wl = new WindowAdapter()
        {
            public void windowDeactivated(WindowEvent e)
            {
                e.getWindow().setVisible(false);
            }
        };

        JButton button = new JButton("Show Popup");
        button.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                JButton button = (JButton)e.getSource();
                JFrame frame = (JFrame) SwingUtilities.windowForComponent(button);

                JDialog dialog = new JDialog(frame, false);
                dialog.setUndecorated(true);
                dialog.add( new JButton("Dummy Button") );
                dialog.pack();
                dialog.setLocationRelativeTo( frame );
                dialog.setVisible( true );
                dialog.addWindowListener( wl );
            }
        });

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(button, BorderLayout.NORTH);
        frame.setSize(400, 400);
        frame.setLocationRelativeTo( null );
        frame.setVisible( true );
     }
}

我最初尝试这个方法是因为它似乎是最简单的方法,但是 windowDeactiveated() 事件似乎从来没有得到注册,这有点奇怪。在使用 JFrame 时它很好用,但是一旦我切换到 JWindow 上,就不能正常工作了。不知道您是否有任何想法可以解决这个问题?我现在已经用另一种方法实现了,但是我很感兴趣 :) - Michael Berry
@berry120,不确定,但您可以尝试使用未装饰的JDialog而不是JWindow。或者,如果您的问题所述的确实是使用了花哨的菜单,那么为什么不直接使用JPopupMenu呢?这样您就可以默认获得此行为了。 - camickr
这不完全像是一个菜单,还有一些方面,比如当你点击一个项目时它会消失,我并不是真的想要这样 - 更像是菜单和对话框之间的交叉!很难解释,但在我使用它的上下文中效果很好。尝试过使用未装饰的JDialog,但也没有起作用。啊,好吧,我想我只能坚持使用awtevent方法了。谢谢你的见解,如果它能够起作用,这将是一个更清洁的解决方案! - Michael Berry
@berry120,对我来说它很好用。你的对话框上实际上有一个可聚焦的组件吗?请参见编辑中的SSCCE。 - camickr
1
我现在感觉很傻。不,那里根本没有可聚焦的组件 - 非常感谢您的示例。现在完全明白了! - Michael Berry

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