如何根据鼠标位置打开JDialog?

How to open JDialog based on Mouse Location?

此示例打开一个带有按钮的 JFrame。单击该按钮时,将打开一个 JDialog。捕获鼠标在按钮上的 XY 位置并用于打开 JDialog。

问题是按钮上捕获的 XY 是正确的,但它是相对于 JFrame 的 XY。 打开 JDialog 时,它是相对于监视器完成的。

是否可以根据鼠标单击的 XY 位置打开 JDialog?

import java.awt.Dialog;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;

public class JDialogInJFrame {
  private static int index;
  MouseEvent mouseXY;
  JFrame f; 

  private void display() {
    f = new JFrame();
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JButton jb = new JButton(new AbstractAction()
    {
        public void actionPerformed(ActionEvent e) 
        {
            System.out.println("actionPerformed");
          JDialog jd = new JDialog(f);
          jd.setTitle("D" + String.valueOf(++index));
          jd.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
          jd.add(new JButton());
          jd.setSize(200, 200);
          jd.setLocation(mouseXY.getX(), mouseXY.getY());
          jd.setVisible(true);
        }
    }
    );

    jb.addMouseListener(new MouseListener ()
    {

        public void mousePressed(MouseEvent e) {
            mouseXY = e;
           saySomething("Mouse pressed; # of clicks: "
                        + e.getClickCount(), e);
        }

        public void mouseReleased(MouseEvent e) {
           saySomething("Mouse released; # of clicks: "
                        + e.getClickCount(), e);
        }

        public void mouseEntered(MouseEvent e) {
           saySomething("Mouse entered", e);
        }

        public void mouseExited(MouseEvent e) {
           saySomething("Mouse exited", e);
        }

        public void mouseClicked(MouseEvent e) {
           saySomething("Mouse clicked (# of clicks: "
                        + e.getClickCount() + ")", e);
        }

        void saySomething(String eventDescription, MouseEvent e) {
            System.out.println(eventDescription + " detected on "
                            + e.getComponent().getClass().getName());
        }
    });

    f.add(jb);
    f.setSize(200, 200);
    f.setLocationRelativeTo(null);
    f.setVisible(true);
  }

  public static void main(String[] args) {

    new JDialogInJFrame().display();

  }
}

有几个SwingUtilities函数可以在组件坐标系和屏幕坐标系之间转换坐标。像这里一样使用。它对这类事情有帮助。

    JButton component = new JButton();
    Point pt = new Point(component.getLocation());
    SwingUtilities.convertPointToScreen(pt, component);