JDialog基于鼠标点击定位时相对JFrame坐标失效问题咨询
问题原因与解决方法
核心定位逻辑差异
Swing 中顶级容器(JDialog、JFrame、JWindow 等)的 setLocation(int x, int y) 方法接收的是屏幕绝对坐标,而 MouseEvent 的 getX()/getY() 返回的是相对于触发事件的组件(当前场景下就是你的 JFrame 内容面板)的相对坐标,二者坐标系不统一,所以直接传入会定位错误。
你的代码中 optionDialog.setLocationRelativeTo(parent) 属于冗余操作,后续调用的 setLocation() 会直接覆盖前者的定位结果,可以直接删除。
两种可行的定位方案
方案1:直接使用屏幕坐标(推荐)
就是你目前测试正常的写法,直接传入 evt.getXOnScreen() 和 evt.getYOnScreen(),这是最简便的实现方式,不需要额外坐标转换。
方案2:相对父组件坐标转屏幕坐标
如果你的业务场景只能拿到相对于父组件的坐标,可通过父组件的 getLocationOnScreen() 方法完成坐标换算,修改 showUserMessage 方法的定位逻辑即可:
private static int showUserMessage( Component parent, String title, String text, int type, int options, int relativeX, int relativeY ) { JOptionPane optionPane = new JOptionPane(text, type, options); JDialog optionDialog = optionPane.createDialog(parent, title); // 相对父组件坐标转屏幕绝对坐标 Point parentScreenPos = parent.getLocationOnScreen(); optionDialog.setLocation(parentScreenPos.x + relativeX, parentScreenPos.y + relativeY); optionDialog.setVisible(true); if (optionPane.getValue() == null) { return JOptionPane.CANCEL_OPTION; } return (int) optionPane.getValue(); }
这样你再传入 evt.getX()、evt.getY() 也能正常定位。
补充说明
普通轻量级 Swing 组件(JPanel、JButton 等)的坐标体系是相对于父容器的,和顶级容器的全局屏幕坐标体系完全独立,不要混淆二者的定位逻辑。
内容的提问来源于stack exchange,提问作者William Brandley
相关产品推荐
相关产品推荐

