我添加了一个AWTEventListener来处理抓取事件。所以这个监听器只使用sun.awt.SunToolkit.GRAB_EVENT_MASK 标记。 但是这个监听器无法捕获UngrabEvent。棘手的是,当JComboBox弹出其menulist时,它可以捕获此事件。 我使用以下代码进行测试。 启动程序,单击框架的空白区域,单击框架标题。然后应该有一个UngrabEvent。但是听众没有抓住它。 启动程序,单击组合框并使其menulist popuped。点击 框架标题。然后应该有一个UngrabEvent。听众捕捉它。 这很奇怪...... UngrabEvent和JComboBox之间有什么关系吗?
public class ComboboxLearn {
public static void main(String[] args) {
// TODO Auto-generated method stub
Toolkit toolkit = Toolkit.getDefaultToolkit();
toolkit.addAWTEventListener(new AWTEventListener() {
@Override
public void eventDispatched(AWTEvent event) {
System.out.println(event);
}
}, sun.awt.SunToolkit.GRAB_EVENT_MASK);
JComboBox box = new JComboBox(new Object[] { "AAA", "BBB", "CCC" });
box.addPopupMenuListener(new PopupMenuListener() {
@Override
public void popupMenuCanceled(PopupMenuEvent e) {
System.out.println(e);
}
@Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
System.out.println(e);// Set a breakpoint here
}
@Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
System.out.println(e);
}
});
JFrame f = new JFrame();
f.getContentPane().setLayout(new FlowLayout());
f.getContentPane().add(box);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(new Dimension(100, 100));
f.setVisible(true);
}
}
答案 0 :(得分:1)
我感觉到你在试验;但通常,您不应该依赖Sun / Oracle的未记录的API。
我想要一个可以隐藏的弹出窗口 鼠标在弹出窗口外被按下但是 在弹出窗口上按下鼠标时不会隐藏。
当您看到JDialog
时,为什么不调出isPopupTrigger()
并在看到它停用时隐藏它,因为另一个窗口会激活?我们讨论了这个概念here。
答案 1 :(得分:0)
尽管“垃圾桶”的推理是可以理解的,但它不能回答以下问题:您实际上试图做的事情是行不通的,因为即使要抓火,您也需要有一个抓住的窗口:((SunToolkit)Toolkit.getDefaultToolkit()).grab(someWindow);
。
您可以按以下方式更改代码
class ComboboxLearn {
public static void main(String[] args) {
// TODO Auto-generated method stub
Toolkit toolkit = Toolkit.getDefaultToolkit();
toolkit.addAWTEventListener(new AWTEventListener() {
@Override
public void eventDispatched(AWTEvent event) {
System.out.println(event);
}
}, sun.awt.SunToolkit.GRAB_EVENT_MASK);
JComboBox box = new JComboBox(new Object[] { "AAA", "BBB", "CCC" });
JFrame f = new JFrame();
box.addPopupMenuListener(new PopupMenuListener() {
@Override
public void popupMenuCanceled(PopupMenuEvent e) {
System.out.println(e);
}
@Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
System.out.println(e);// Set a breakpoint here
//UNGRABBING WINDOW
((SunToolkit) toolkit).ungrab(f);
}
@Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
System.out.println(e);
//GRABBING WINDOW
((SunToolkit) toolkit).grab(f);
}
});
f.getContentPane().setLayout(new FlowLayout());
f.getContentPane().add(box);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(new Dimension(100, 100));
f.setVisible(true);
}
}
然后,您将获得抓取事件,但是处于您正在处理的级别,不需要它们。
假设您遇到this nasty bug,尽管它已关闭,但我仍然可以重现它,您需要实现自己的弹出机制。您做的一切都很好,只要在外部单击,但缺少某些内容,就可以将AWT侦听器附加到关闭弹出窗口。您随处单击,弹出窗口消失,除了窗口标题和应用程序外!拍你想! JPopupmenu如何做到这一点。在花了一些时间阅读jdk代码并尝试了各种方法之后,您意识到,正是这种未记录的事件才可以解决问题。
我不知道这种grab()
方法的内部知识,而且我没有时间去研究,因此可能会有不太明显的副作用。自行承担风险。