JavaFX & Spring Boot - NPE

发布于 2025-01-13 15:32:35 字数 2413 浏览 2 评论 0原文

我仍在与我的问题作斗争。我想使用 Spring Framework 来注入依赖项,并且必须使用 Spring boot 来集成两者。 不幸的是,在第一个视图中,自动装配运行正确,但如果我进入下一阶段,我仍然只得到空指针异常

这就是主类:

@SpringBootApplication(scanBasePackages = "boxingchallenge")
public class BoxingChallengeApplication extends Application {

    public ConfigurableApplicationContext springContext;
    private Parent root;
    public static Stage stage;

    @Override
    public void init() throws Exception {
        springContext = SpringApplication.run(BoxingChallengeApplication.class);
        springContext.getAutowireCapableBeanFactory().autowireBean(this);
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/FXML/start.fxml"));
        fxmlLoader.setControllerFactory(springContext::getBean);
        root = fxmlLoader.load();
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        stage = primaryStage;
        primaryStage.setTitle("Boxing challenge");
        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    @Override
    public void stop() {
        springContext.stop();
    }

    public static void main(String[] args) {
        launch(BoxingChallengeApplication.class, args);
    }
}

在第一个控制器类中,自动装配运行得很酷:

@Component
public class Start {

    @FXML
    public Button loadGame;
    @FXML
    public Button create;

    @Autowired
    private Boxer boxer;

    public void load(ActionEvent event) {
        System.out.println(boxer.getName());
    }

    //next stage
    public void createNew(ActionEvent event) throws IOException {
        Parent root = FXMLLoader.load(getClass().getResource("/FXML/creator.fxml"));
        BoxingChallengeApplication.stage.setScene(new Scene(root));
    }
}

在第二阶段,自动装配不起作用:

@Component
public class Creator {

    @FXML
    public Button ready;
    public TextField nation;
    public TextField name;
    public Boxer boxer;

    /*@Autowired
    private ApplicationContext context;*/

    @Autowired
    public void setBoxer(Boxer boxer) {
        this.boxer = boxer;
    }

    public void createdAndPlay(ActionEvent event) {
        if (boxer == null)
            System.out.println("boxer is null");
        else
            System.out.println("Injected correctly");
    }
}

谢谢,我希望它能完成......

I'm still fighting with my issue. I want to use Spring Framework in order to incject dependencies and I have to use Spring boot to integrate both.
Unfortunately, in first view autowiring is run correctly, but if I go next Stage, I got still only Null Pointer Exception.

Thats main class:

@SpringBootApplication(scanBasePackages = "boxingchallenge")
public class BoxingChallengeApplication extends Application {

    public ConfigurableApplicationContext springContext;
    private Parent root;
    public static Stage stage;

    @Override
    public void init() throws Exception {
        springContext = SpringApplication.run(BoxingChallengeApplication.class);
        springContext.getAutowireCapableBeanFactory().autowireBean(this);
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/FXML/start.fxml"));
        fxmlLoader.setControllerFactory(springContext::getBean);
        root = fxmlLoader.load();
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        stage = primaryStage;
        primaryStage.setTitle("Boxing challenge");
        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    @Override
    public void stop() {
        springContext.stop();
    }

    public static void main(String[] args) {
        launch(BoxingChallengeApplication.class, args);
    }
}

Here in first controller class autowiring run cool:

@Component
public class Start {

    @FXML
    public Button loadGame;
    @FXML
    public Button create;

    @Autowired
    private Boxer boxer;

    public void load(ActionEvent event) {
        System.out.println(boxer.getName());
    }

    //next stage
    public void createNew(ActionEvent event) throws IOException {
        Parent root = FXMLLoader.load(getClass().getResource("/FXML/creator.fxml"));
        BoxingChallengeApplication.stage.setScene(new Scene(root));
    }
}

Here in second stage, autowiring not working:

@Component
public class Creator {

    @FXML
    public Button ready;
    public TextField nation;
    public TextField name;
    public Boxer boxer;

    /*@Autowired
    private ApplicationContext context;*/

    @Autowired
    public void setBoxer(Boxer boxer) {
        this.boxer = boxer;
    }

    public void createdAndPlay(ActionEvent event) {
        if (boxer == null)
            System.out.println("boxer is null");
        else
            System.out.println("Injected correctly");
    }
}

Thanks, i hope it's going to finished...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

蓝戈者 2025-01-20 15:32:35

@Jewelsea 的评论是正确的:加载 时必须设置控制器工厂创建者.fxml。如果您不这样做,FXMLLoader 将仅通过调用其无参数构造函数来创建控制器,因此 Spring 将对此一无所知,并且没有机会注入任何依赖项。

为此,您只需访问 Start 中的 ApplicationContext,并且可以注入“众所周知的对象”,其中 ApplicationContext > 是 Spring 管理的 bean 中的一个示例:

@Component
public class Start {

    @FXML
    public Button loadGame;
    @FXML
    public Button create;

    @Autowired
    private Boxer boxer;

    @Autowired
    private ApplicationContext context ;

    public void load(ActionEvent event) {
        System.out.println(boxer.getName());
    }

    //next stage
    public void createNew(ActionEvent event) throws IOException {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("/FXML/creator.fxml"));
        load.setControllerFactory(context::getBean);
        Parent root = loader.load();
        BoxingChallengeApplication.stage.setScene(new Scene(root));
    }
}

顺便说一句,在加载 FXML 文件时,您几乎肯定需要任何控制器的新实例,因此您应该将所有控制器设置为 prototype 范围。

@Jewelsea's comment is correct: you must set the controller factory when you load creator.fxml. If you don't do this, the FXMLLoader will create the controller simply by calling its no-arg constructor, so Spring will know nothing about it and will have no opportunity to inject any dependencies.

To do this, all you need is access to the ApplicationContext in Start, and you can inject "well-known objects", of which the ApplicationContext is an example, into your Spring-managed beans:

@Component
public class Start {

    @FXML
    public Button loadGame;
    @FXML
    public Button create;

    @Autowired
    private Boxer boxer;

    @Autowired
    private ApplicationContext context ;

    public void load(ActionEvent event) {
        System.out.println(boxer.getName());
    }

    //next stage
    public void createNew(ActionEvent event) throws IOException {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("/FXML/creator.fxml"));
        load.setControllerFactory(context::getBean);
        Parent root = loader.load();
        BoxingChallengeApplication.stage.setScene(new Scene(root));
    }
}

As an aside, you almost certainly want a new instance of any controller when you load an FXML file, so you should probably make any controllers prototype scope.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文