5

我想用 JPopupMenu 复制右键单击上下文菜单的一些属性:

  1. 当菜单打开并单击其他位置时,菜单将关闭。
  2. 当菜单打开并且您单击其他地方时,不会发生任何其他事情。

我已经把第一部分写得很好。但是当我单击其他地方时,可能会发生其他事件。例如,假设我有按钮 A,它执行一些操作 B。目前,如果 JPopupMenu 打开,并且我单击 A,则 JPopupMenu 关闭并执行 B。我宁愿关闭 JPopupMenu 并且不执行 B。这可能吗?

谢谢

4

2 回答 2

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;
}
于 2011-09-28T14:34:28.827 回答
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(...)。您可以注释掉该行并观察该操作在任何情况下都会在您当前体验到的情况下发生。

于 2011-06-07T19:45:08.333 回答