Linux下JavaFX调用popupstage.initOwner()致窗口移位的问题求助
Linux下JavaFX调用
popupstage.initOwner()导致窗口移位的规避方案 调用popupstage.initOwner()会导致已有窗口移位,视觉效果异常,该问题仅在Linux系统上出现。当在已有窗口之上创建新窗口时触发,相关代码如下:
public static void newWind(String fxml) throws IOException{ FXMLLoader fxmlLoader = new FXMLLoader(App.class.getResource(fxml + ".fxml")); Parent root1 = (Parent) fxmlLoader.load(); popup_stage = new Stage(); Scene newscene = new Scene(root1, 720,480); newscene.getRoot().setStyle("-fx-font-family: 'Arial'"); popup_stage.setScene(newscene); popup_stage.initModality(Modality.WINDOW_MODAL); popup_stage.initOwner(stage_APP); // 此行触发bug,移除后窗口不再移位 popup_stage.initStyle(StageStyle.UNDECORATED); popup_stage.show(); }
注释掉popup_stage.initOwner(stage_APP);后,窗口移位的bug消失,但无法满足新窗口保持焦点、旧窗口在新窗口关闭前冻结的需求。该问题属于未修复的OpenJDK bug(编号JDK-8255347)。
可行规避方案
手动模拟模态效果(推荐)
不调用initOwner(),通过手动控制主窗口的禁用状态来实现模态效果:public static void newWind(String fxml) throws IOException{ FXMLLoader fxmlLoader = new FXMLLoader(App.class.getResource(fxml + ".fxml")); Parent root1 = (Parent) fxmlLoader.load(); popup_stage = new Stage(); Scene newscene = new Scene(root1, 720,480); newscene.getRoot().setStyle("-fx-font-family: 'Arial'"); popup_stage.setScene(newscene); popup_stage.initStyle(StageStyle.UNDECORATED); // 显示新窗口前禁用主窗口 stage_APP.setDisable(true); // 新窗口关闭时恢复主窗口交互 popup_stage.setOnHidden(event -> stage_APP.setDisable(false)); popup_stage.show(); popup_stage.requestFocus(); // 确保新窗口获取焦点 }调整窗口初始化顺序
先完成新窗口的样式、尺寸设置并显示,再关联所有者和模态属性,部分场景下可缓解移位问题:public static void newWind(String fxml) throws IOException{ FXMLLoader fxmlLoader = new FXMLLoader(App.class.getResource(fxml + ".fxml")); Parent root1 = (Parent) fxmlLoader.load(); popup_stage = new Stage(); Scene newscene = new Scene(root1, 720,480); newscene.getRoot().setStyle("-fx-font-family: 'Arial'"); popup_stage.setScene(newscene); popup_stage.initStyle(StageStyle.UNDECORATED); // 先显示窗口,再设置所有者和模态 popup_stage.show(); popup_stage.initOwner(stage_APP); popup_stage.initModality(Modality.WINDOW_MODAL); popup_stage.requestFocus(); }替换为Dialog组件
JavaFX原生Dialog组件默认支持模态和所有者关联,部分版本下可避开该窗口移位bug:public static void newWind(String fxml) throws IOException{ FXMLLoader fxmlLoader = new FXMLLoader(App.class.getResource(fxml + ".fxml")); Parent root1 = (Parent) fxmlLoader.load(); Dialog<Void> dialog = new Dialog<>(); dialog.getDialogPane().setContent(root1); dialog.initOwner(stage_APP); dialog.initModality(Modality.WINDOW_MODAL); dialog.initStyle(StageStyle.UNDECORATED); dialog.getDialogPane().setPrefSize(720, 480); dialog.getDialogPane().getScene().getRoot().setStyle("-fx-font-family: 'Arial'"); dialog.showAndWait(); }
内容的提问来源于stack exchange,提问作者Allexj
相关产品推荐
相关产品推荐

