You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaFX加载第二场景后如何在SecondController调用Stage的getUserData

问题根因

空指针报错是因为initialize()方法执行时机早于FXML元素被挂载到Scene、Scene绑定到Stage的流程。此时statusLabel已经被注入,但还没关联到任何Scene对象,因此statusLabel.getScene()返回null,调用getWindow()自然触发空指针。

解决方案1(更推荐:直接传参,绕过StageUserData)

这是JavaFX跨控制器传参的标准实现,稳定性更高:

  1. 首先修改SecondController.java,新增接收参数的自定义方法:
public class SecondController {
    @FXML
    private Label statusLabel;

    // 外部调用该方法直接传入要接收的字符串
    public void initData(String message) {
        statusLabel.setText(message);
    }

    @FXML
    public void initialize() {
        // 此处不需要再编写获取Stage数据的逻辑
    }
}
  1. 修改FirstController中加载第二场景的逻辑,加载完FXML后先传参再切换场景:
// 原加载逻辑
FXMLLoader loader = new FXMLLoader(getClass().getResource("secondScene.fxml"));
Parent root = loader.load();
// 新增:获取SecondController实例并传入参数
SecondController secondController = loader.getController();
secondController.initData(message);
// 原切换场景逻辑
Stage stage = (Stage) ((Node)event.getSource()).getScene().getWindow();
stage.setScene(new Scene(root));
// 原setUserData代码可直接删除,参数已经完成传递
stage.show();
解决方案2(坚持使用Stage.getUserData的实现)

如果一定要通过Stage的userData传递参数,可以通过属性监听器等待控件完成挂载后再取值:

@FXML
public void initialize() {
    // 监听statusLabel的scene属性变化,等待控件挂载到Scene
    statusLabel.sceneProperty().addListener((observable, oldScene, newScene) -> {
        if (newScene != null) {
            // 监听Scene的window属性变化,等待Scene绑定到Stage
            newScene.windowProperty().addListener((obs, oldWindow, newWindow) -> {
                if (newWindow != null) {
                    Stage window = (Stage) newWindow;
                    statusLabel.setText("" + window.getUserData());
                }
            });
        }
    });
}

内容的提问来源于stack exchange,提问作者noodles888

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 12:24:05