JavaFX窗口最大化时弹出Alert切换场景后显示非最大化异常问题
问题根因
这是JavaFX跨平台窗口渲染层的常见同步问题:模态Alert关闭后切换场景根节点时,窗口的内部最大化状态标记和实际系统层面的窗口渲染状态不同步。你连续调用setMaximized(false)和setMaximized(true)时,JavaFX的UI线程会合并相邻的同属性修改操作,导致状态变更没有触发实际的窗口重绘。另外你setPane方法里冗余的stage.show()调用也会额外触发窗口状态重置逻辑,加剧不同步问题。
修复方案
步骤1:删除setPane方法里冗余的stage.show()调用
Stage只要调用过一次show()处于显示状态后,切换根节点不需要重复调用show,修改后的代码:
// in class GUI public void setPane(Pane pane) { stage.getScene().setRoot(pane); // 删掉多余的stage.show() }
步骤2:把最大化状态重置操作放到UI事件队列末尾执行
用Platform.runLater包装最大化设置逻辑,等前面的根节点切换、Alert关闭的残留渲染操作全部执行完成后,再触发窗口状态更新,保证状态同步:
public void onLeave(ActionEvent actionEvent) { if(leaveAlert()) { boolean wasMaximized = GUI.getStage().isMaximized(); GUI.INSTANCE.setPane(MenuPane.PANE); if (wasMaximized) { // 延迟到UI队列空闲时再设置最大化,避免同步问题 Platform.runLater(() -> { GUI.getStage().setMaximized(false); // 再套一层runLater保证false的设置先被渲染,再设置true Platform.runLater(() -> GUI.getStage().setMaximized(true)); }); } } }
备选兼容方案(针对部分Linux/macOS平台失效的情况)
如果上述方案还是失效,可以临时修改窗口的宽高属性触发重绘,强制系统同步窗口状态:
public void onLeave(ActionEvent actionEvent) { if(leaveAlert()) { boolean wasMaximized = GUI.getStage().isMaximized(); double oldWidth = GUI.getStage().getWidth(); double oldHeight = GUI.getStage().getHeight(); GUI.INSTANCE.setPane(MenuPane.PANE); if (wasMaximized) { Platform.runLater(() -> { GUI.getStage().setWidth(oldWidth - 1); GUI.getStage().setHeight(oldHeight - 1); GUI.getStage().setMaximized(true); }); } } }
内容的提问来源于stack exchange,提问作者Griszder
相关产品推荐
相关产品推荐

