我想用JPopupMenu复制右键单击上下文菜单的一些属性:
我的第一部分很好。但是当我点击其他地方时,可能会发生其他事件。例如,假设我有按钮A,它执行一些操作,B。目前,如果JPopupMenu打开,并且我单击A,则JPopupMenu关闭并执行B.我希望JPopupMenu关闭,B不要执行。这可能吗?
由于
答案 0 :(得分:11)
这很有效,而且简单得多......虽然可以被一些外观所覆盖。
UIManager.put("PopupMenu.consumeEventOnClose", Boolean.TRUE);
值得注意的是,这仅消耗MOUSE_PRESSED事件,不会消耗后续的MOUSE_CLICKED事件。您可以通过在mousePressed()中设置标志并在mouseReleased()中测试它来模拟鼠标单击。如果消耗了初始鼠标,则不会在mouseReleased()
中设置该标志private boolean pressed = false;
@Override
public void mousePressed(MouseEvent e) {
pressed = true;
}
@Override
public void mouseReleased(MouseEvent e) {
if (pressed) {
// do click stuff
}
pressed = false;
}
答案 1 :(得分:3)
考虑到您的问题和评论中的内容,我会通过以下方式之一解决您的问题。
从技术上讲,你有两个选择:
1.只要用户将鼠标移到弹出窗口之外,就会隐藏弹出窗口。这样您就不会遇到用户点击的问题,因为弹出窗口会自动消失。
2.全局捕获此特定鼠标事件,如果弹出窗口可见,则在左键单击时使用该事件。我在下面的例子中展示了这个特殊的解决方案。
import java.awt.AWTEvent;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
public class DisableClickWhenPopupVisibleTest
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
final JPopupMenu popup = new JPopupMenu();
popup.add(new JMenu("aAaa"));
JPanel contentPane = new JPanel();
contentPane.add(popup);
JButton b = new JButton();
b.setAction(new AbstractAction("Button")
{
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e)
{
System.out.println("b actionPerformed");
}
});
contentPane.add(b);
contentPane.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e)
{
showPopup(e);
}
@Override
public void mouseReleased(MouseEvent e)
{
showPopup(e);
}
private void showPopup(MouseEvent e)
{
if(e.isPopupTrigger())
popup.show(e.getComponent(), e.getX(), e.getY());
}
});
//use global mouse event capture to disable left click on anything when popup is visible
Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
@Override
public void eventDispatched(AWTEvent event)
{
MouseEvent me = (MouseEvent)event;
if(me.getID() == MouseEvent.MOUSE_PRESSED)
{
System.out.println("eventDispatched popup.vis="+popup.isVisible());
if( me.getButton() == MouseEvent.BUTTON3)
{
System.out.println("BUTTON3");
}
else if(me.getButton() == MouseEvent.BUTTON1)
{
System.out.println("BUTTON1");
if(popup.isVisible())
me.consume();
}
}
}
}, AWTEvent.MOUSE_EVENT_MASK);
JFrame f = new JFrame();
f.setContentPane(contentPane);
f.setSize(400, 300);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
});
}
}
您可以通过右键单击按钮左侧的稍微测试该示例,然后弹出窗口将显示。然后,如果单击按钮,则不会调用其操作。如果隐藏弹出窗口,则会正常调用该操作。此功能由以下代码行Toolkit.getDefaultToolkit().addAWTEventListener(...)
提供。您可以注释掉该行,然后观察该操作将在您目前遇到的任何情况下发生。