JavaFX &弹簧靴 - NPE [英] JavaFX & Spring Boot - NPE

查看:22
本文介绍了JavaFX &弹簧靴 - NPE的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我仍在与我的问题作斗争.我想使用 Spring Framework 来注入依赖项,我必须使用 Spring boot 来集成两者.不幸的是,在第一个视图中自动装配运行正确,但如果我进入下一个阶段,我仍然只有 Null Pointer Exception.

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.

这是主类:

@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));
    }
}

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

@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...

推荐答案

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

@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.

为此,您只需要访问Start中的ApplicationContext,并且可以注入众所周知的对象",其中ApplicationContext 是一个例子,进入你的 Spring 管理的 bean:

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));
    }
}

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

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.

这篇关于JavaFX &弹簧靴 - NPE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆