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

查看:82
本文介绍了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将仅通过调用其no-arg构造函数来创建控制器,因此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,并且可以向Spring管理的bean中注入知名对象"(其中以ApplicationContext为例):

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天全站免登陆