2

I am trying to use JavaFX and Spring together. I am using Spring Boot, in particular. My issue is that I have both Spring autowired fields and JavaFX "autowired" fields in the FXML controller. I put a breakpoint in the constructor controller and it is actually being invoked twice: one by Spring, which autowires @Autowired fields only, one by JavaFX, which initialize @FXML fields only.

Here's my main code:

@SpringBootApplication
public class MySpringAndJavaFXApp extends AbstractJavaFXAndSpringApplication {

    @Override
    public void start(Stage window) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("/fxml/home.fxml"));
        window.setTitle("My Title");
        window.setScene(new Scene(root, 500, 300));
        window.show();
    }


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

Here's the class I am extending:

public abstract class JavaFXAndSpringApplication extends Application {

    protected static void launchApp(Class<? extends JavaFXAndSpringApplication> classePrincipaleJavaFX, String[] args) {
        launch(classePrincipaleJavaFX,args);
    }

    private ConfigurableApplicationContext applicationContext;

    @Override
    public void init() throws Exception {
        applicationContext = SpringApplication.run(getClass());
        applicationContext.getAutowireCapableBeanFactory().autowireBean(this);
    }

    @Override
    public void stop() throws Exception {
        super.stop();
        applicationContext.close();
    }
}

An example of a class being Spring-managed and JavaFX-managed:

@Component
public class MixedController {

    @FXML
    private TextField aTextField;

    @Autowired
    private MyService myService; // MyService is a @Component


    public MixedController() {
        System.out.println("I am here"); // debugger goes twice here
    }
}

How I can easily fix my issue? I attempted using a custom FXML loader (e.g. JavaFX and Spring - beans doesn't Autowire). However, if I load the home.fxml file with such loader, I get an error on the data provider (i.e. Spring is not getting my database configuration correctly) and I would prefer another approach.

Community
  • 1
  • 1
Manu
  • 4,019
  • 8
  • 50
  • 94
  • 1
    Check [the answer](http://stackoverflow.com/a/32426672/2747533) to the question you've linked to. Use an instance of `FXMLLoader`, don't load with static method. – MirMasej Oct 01 '16 at 11:46
  • Yes, that's what I tried (see my OP last lines) and couldn't get it to work. – Manu Oct 01 '16 at 11:47
  • In `MySpringAndJavaFXApp` at first line of the `start` method a static `load` method is being called. Either your sample code is wrong or you are calling a static method. Initialize `FXMLoader` and pass `ControllerFactory` to it as described in discussed answer. – MirMasej Oct 01 '16 at 12:23
  • The code I posted does not refer to the attempt of using the custom FXMLLoader. I haven't reported that attempt. I would prefer not using a custom FXMLLoader, if there is another approach (it causes me several issues). Does it exist? – Manu Oct 01 '16 at 12:29
  • @Manu You don't have to use a *custom* `FXMLLoader`. Just create a `FXMLLoader` instance and set the controller factory on it. As stated above, don't use the static method. – James_D Oct 01 '16 at 15:29
  • 1
    The bottom line here is that if you want Spring to create the controllers that are used by the `FXMLLoader` you *must* set a controller factory on the `FXMLLoader` (and of course to do that, you must have an `FXMLLoader` instance). If you don't set a controller factory, the `FXMLLoader` will create a new instance of the controller class. The issue with the database configuration sounds like another issue entirely. – James_D Oct 01 '16 at 15:42
  • Ok, I got the point. Is there a way to go the other way round and automatically register a fxcontroller as a spring bean? – Manu Oct 01 '16 at 15:45
  • Checkout the github projects: `jacpfx` or `easyfxml`. They both facilitate interop between javafx and spring. EasyFXML is probably all you need tbh – smac89 Aug 20 '19 at 20:28

0 Answers0