从弹出菜单捕获鼠标 XY 位置

Capture Mouse XY Location from the Popup Menu

我能够捕获两个鼠标移动的 XY 坐标以及鼠标右键单击以打开弹出菜单的位置。

问题是如何从与 JFrame 相关的弹出菜单顶部获取 XY 坐标。 Popup 起源的 XY 位置与鼠标在弹出窗口上单击的位置不同。

我尝试将鼠标侦听器添加到 JPopupMenu 对象,但它从未输入代码。

MousePopupListener 看起来很有前途,但这也无济于事。

下面的例子实际上是2个例子混在一起。它应该在鼠标移动时显示 XY 坐标,以便在弹出菜单期间可以看到 XY,但图层不是一个强区域,我只能让鼠标 XY 显示或弹出菜单工作,但是不是都。

无论如何,我想做的是捕获调用弹出菜单的 XY 坐标(这已经可以完成),但我还想要相对于选择时按下鼠标的框架的 XY 位置弹出菜单中的项目。

需要添加什么来捕获该信息?

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;

import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.border.BevelBorder;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;

public class MousePopupExample extends JPanel {

  public JPopupMenu popup;

  public MousePopupExample()
  {
    popup = new JPopupMenu();
    ActionListener menuListener = new ActionListener() {
      public void actionPerformed(ActionEvent event) 
      {
        System.out.println("Popup menu item ["
            + event.getActionCommand() + "] was pressed.");
      }
    };
    JMenuItem item;
    popup.add(item = new JMenuItem("Left", new ImageIcon("1.gif")));
    item.setHorizontalTextPosition(JMenuItem.RIGHT);
    item.addActionListener(menuListener);
    popup.add(item = new JMenuItem("Center", new ImageIcon("2.gif")));
    item.setHorizontalTextPosition(JMenuItem.RIGHT);
    item.addActionListener(menuListener);
    popup.add(item = new JMenuItem("Right", new ImageIcon("3.gif")));
    item.setHorizontalTextPosition(JMenuItem.RIGHT);
    item.addActionListener(menuListener);
    popup.add(item = new JMenuItem("Full", new ImageIcon("4.gif")));
    item.setHorizontalTextPosition(JMenuItem.RIGHT);
    item.addActionListener(menuListener);
    popup.addSeparator();
    popup.add(item = new JMenuItem("Settings . . ."));
    item.addActionListener(menuListener);

    popup.setLabel("Justification");
    popup.setBorder(new BevelBorder(BevelBorder.RAISED));
    popup.addPopupMenuListener(new PopupPrintListener());

    addMouseListener(new MousePopupListener());
  }


// An inner class to check whether mouse events are the popup trigger
  class MousePopupListener extends MouseAdapter 
  {
    public void mouseMoves(MouseEvent e) {
      checkPopup(e);
    }

    public void mousePressed(MouseEvent e) {
      checkPopup(e);
    }

    public void mouseClicked(MouseEvent e) {
      checkPopup(e);
    }

    public void mouseReleased(MouseEvent e) {
      checkPopup(e);
    }

    private void checkPopup(MouseEvent e) {
      if (e.isPopupTrigger()) {
        popup.show(MousePopupExample.this, e.getX(), e.getY());
      }
    }
  }

  // An inner class to show when popup events occur
  class PopupPrintListener implements PopupMenuListener {
    public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
      System.out.println("Popup menu will be visible!");
    }

    public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
      System.out.println("Popup menu will be invisible!");
    }

    public void popupMenuCanceled(PopupMenuEvent e) {
      System.out.println("Popup menu is hidden!");
    }
  }

  public static void main(String s[]) {
    JFrame frame = new JFrame("Popup Menu Example");
    XYMouseLabel xyMouseLabel = new XYMouseLabel();

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    MousePopupExample mpe = new MousePopupExample();

    xyMouseLabel.setBounds(0, 0, frame.getWidth(), frame.getHeight());    
    mpe.add(xyMouseLabel);

    frame.setContentPane(mpe);
    frame.setPreferredSize(new Dimension(400, 300));
    frame.pack();

    frame.addMouseMotionListener(new MouseMotionAdapter() {
        public void mouseMoved(MouseEvent me)
        {
            System.out.println("Mouse Move");
          xyMouseLabel.x = me.getX();
          xyMouseLabel.y = me.getY();
          xyMouseLabel.repaint();
        }
      });

    frame.setVisible(true);
  }


}

JPopupMenu 的子组件正在拦截鼠标事件。您需要为菜单及其子项添加一个侦听器。

您可以使用 SwingUtilities.convertMouseEvent:

转换 MouseEvent 的坐标,使其相对于另一个组件(如 JFrame)
MouseMotionListener listener = new MouseMotionAdapter() {
    @Override
    public void mouseMoved(MouseEvent me) {
        me = SwingUtilities.convertMouseEvent(
            me.getComponent(), me, frame);

        System.out.println("Mouse Move");
        xyMouseLabel.x = me.getX();
        xyMouseLabel.y = me.getY();
        xyMouseLabel.repaint();
    }
};

menu.addMouseMotionListener(listener);
for (Component child : menu.getComponents()) {
    child.addMouseMotionListener(listener);
}