问题
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...
回答1:
@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.
来源:https://stackoverflow.com/questions/48290589/javafx-spring-boot-npe