JDK1.8+ControlsFX8.20.8下PopOver无法绑定父节点问题咨询
解决ControlsFX PopOver脱离主应用的问题
看起来你遇到的问题是PopOver没有正确和主窗口绑定,虽然你指定了Circle作为父节点,但因为节点嵌套在Group和Pane中,ControlsFX可能没正确处理坐标转换和窗口关联。我来帮你修复这个问题:
问题根源
当你直接调用popOver.show(marker)时,PopOver可能无法正确识别Circle所在的主Stage,导致它变成一个独立的顶层窗口——这就是为什么它在应用后台还能显示、窗口移动时位置错乱的原因。ControlsFX的PopOver需要明确关联到主窗口的Stage,才能保持和应用的绑定关系。
修复方案
我们需要做两件事:
- 显式将PopOver关联到主窗口的Stage
- 计算Circle在屏幕上的正确位置,让PopOver显示在它附近
修改后的代码如下:
Circle marker = new Circle(panePosition.getX(), panePosition.getY(), 10, Color.GREEN); PopOver popOver = new PopOver(technicalUnit); // 关键修改:禁用PopOver的可分离特性,强制绑定主窗口 popOver.setDetachable(false); marker.setOnMouseClicked(mouseEvent -> { if (popOver.isShowing()) { popOver.hide(); } else { // 获取Circle所在的主Stage Stage stage = (Stage) marker.getScene().getWindow(); // 明确设置PopOver的所属窗口 popOver.setOwner(stage); // 将Circle的本地坐标转换为屏幕坐标,避免布局容器的坐标偏移影响 Point2D screenCenter = marker.localToScreen(marker.getCenterX(), marker.getCenterY()); // 在Circle中心位置显示PopOver(可自行调整偏移量避免重叠) popOver.show(stage, screenCenter.getX(), screenCenter.getY()); } }); group.getChildren().add(marker);
额外说明
setDetachable(false):这个属性会禁止用户将PopOver拖离主窗口,确保它始终和应用绑定在一起localToScreen:这个方法会把Circle的本地坐标转换为屏幕坐标,避免因为Group/Pane的布局变换导致PopOver位置错误- 显式设置
setOwner(stage):让PopOver明确属于主窗口,这样应用最小化时它会跟着隐藏,恢复时回到正确位置,应用切换到后台时也会同步隐藏
这样修改后,PopOver就会完全和主窗口绑定,点击Circle时弹出的详情会始终保持和Circle的相对位置,窗口移动、最小化/恢复时也会正常跟随。
内容的提问来源于stack exchange,提问作者Samarek
相关产品推荐
相关产品推荐

