Java 返回相对于JFrame的单击位置,JFrame不是直接父对象

Java 返回相对于JFrame的单击位置,JFrame不是直接父对象,java,swing,jframe,jbutton,mouselistener,Java,Swing,Jframe,Jbutton,Mouselistener,我正在开发一个使用Swing库的简单Java图形游戏。我有一个JFrame,它包含一个JPanel。面板包含按钮。按钮具有鼠标侦听器。我试图从我的点击按钮获得坐标,但是我需要坐标是相对于帧的。当我使用e.get(x)或get(y)时,坐标是相对于我单击的每个按钮的。我也不能使用getLocationOnScreen 我需要返回相对于框架的位置的东西,框架是容器 import java.awt.MouseInfo; MouseInfo.getPointerInfo().getLocation().

我正在开发一个使用Swing库的简单Java图形游戏。我有一个
JFrame
,它包含一个
JPanel
。面板包含按钮。按钮具有鼠标侦听器。我试图从我的点击按钮获得坐标,但是我需要坐标是相对于帧的。当我使用
e.get(x)
get(y)
时,坐标是相对于我单击的每个按钮的。我也不能使用
getLocationOnScreen

我需要返回相对于框架的位置的东西,框架是容器

import java.awt.MouseInfo;
MouseInfo.getPointerInfo().getLocation().getX() - frame.getX() // X
MouseInfo.getPointerInfo().getLocation().getY() - frame.getY() // Y
这些表达式将返回光标相对于
JFrame
对象的X和Y坐标。

您可能需要使用SwingUtilities类中的方法

在下面的示例中,我打印鼠标事件相对于按钮、父帧和父帧的内容窗格的位置。 然而,框架的内容窗格似乎是您最好的尝试,因为框架装饰和边框会使位置不太准确(在我的Win10上,我有大约9“额外像素”)

另外,请遵循@AndrewThompson的建议,并告诉我们为什么您希望应用程序具有这种行为,因为可能有更好的解决方案

示例代码:

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
public class JFrameCoordinates
{
    public static void main (String [] a) {
        SwingUtilities.invokeLater (new Runnable () {
            @Override public void run () {
                createAndShowGUI ();
            }
        });
    }
    private static void createAndShowGUI () {
        JFrame frame = new JFrame ("Point test");
        frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
        frame.setContentPane (new MainPanel ());
        frame.pack ();
        frame.setLocationRelativeTo (null);
        frame.setVisible (true);
    }
}
class MainPanel extends JPanel
{
    public MainPanel () {
        super (new BorderLayout (0, 50));
        MouseAdapter listener = new MouseAdapter () {
            @Override public void mouseReleased (MouseEvent e) {
                JButton button = (JButton) e.getSource ();
                JFrame frame = (JFrame) SwingUtilities.getWindowAncestor (button);
                System.out.println ();
                System.out.println ("Relative to button: " + e.getPoint ());
                System.out.println ("Relative to frame: " + SwingUtilities.convertPoint (button, e.getPoint (), frame));
                System.out.println ("Relative to frame's content pane: " + SwingUtilities.convertPoint (button, e.getPoint (), frame.getContentPane ()));
            }
        };
        add (createButton ("Print Me", listener), BorderLayout.NORTH);
        JPanel panel = new JPanel (new FlowLayout (FlowLayout.CENTER, 20, 20));
        panel.add (createButton ("Print Me", listener), BorderLayout.NORTH);
        add (panel, BorderLayout.CENTER);
        setBorder (new EmptyBorder (20, 100, 20, 100));
    }
    private JButton createButton (String text, MouseAdapter listener) {
        JButton button = new JButton (text);
        button.addMouseListener (listener);
        return button;
    }
}
“我需要返回相对于框架的位置的东西,框架是外祖父容器。”…为什么?看见