java - Dependency Injection and JavaFX -


since javafx runtime wants instantiate application object , of controller objects, how inject dependencies these objects?

if objects instantiated di framework, spring, framework wire dependencies. if instantiating objects manually, provide dependencies through constructor parameters. do in javafx application?

thanks!

you can specify controller factory fxmlloader. controller factory function maps controller class object (presumably, not necessarily, instance of class) used controller.

so if want spring create controller instances you, can simple as:

applicationcontext context = ... ;  fxmlloader loader = new fxmlloader(getclass().getresource("path/to/fxml")); loader.setcontrollerfactory(context::getbean); parent root = loader.load(); somecontroller controller = loader.getcontroller(); // if need it... // ... 

and fxmlloader create controller instances class<?> c calling context.getbean(c);.

so, e.g., have configuration:

@configuration public class appconfig {      @bean     public myservice service() {         return new myserviceimpl();     }      @bean     @scope("prototype")     public somecontroller somecontroller() {         return new somecontroller();     }      // ... } 

with

public class somecontroller {      // injected fxmlloader:     @fxml     private textfield sometextfield ;      // injected spring:     @inject     private myservice service ;      public void initialize() {         sometextfield.settext(service.getsometext());     }      // event handler:     @fxml     private void performaction(actionevent e) {         service.doaction(...);     } } 

if you're not using di framework, , want injection "by hand", can so, involves using quite lot of reflection. following shows how (and give idea of how ugly work spring doing you!):

fxmlloader loader = new fxmlloader(getclass().getresource("path/to/fxml")); myservice service = new myserviceimpl(); loader.setcontrollerfactory((class<?> type -> {     try {         // constructor taking myservice parameter         (constructor<?> c : type.getconstructors()) {             if (c.getparametercount() == 1) {                 if (c.getparametertypes()[0]==myservice.class) {                     return c.newinstance(service);                 }             }         }         // didn't find appropriate constructor, use default constructor:         return type.newinstance();     } catch (exception exc) {         throw new runtimeexception(exc);     } }); parent root = loader.load(); // ... 

and do

public class somecontroller {      private final myservice service ;      public somecontroller(myservice service) {         this.service = service ;     }      // injected fxmlloader:     @fxml     private textfield sometextfield ;      public void initialize() {         sometextfield.settext(service.getsometext());     }      // event handler:     @fxml     private void performaction(actionevent e) {         service.doaction(...);     } } 

finally, might want check out afterburner.fx, lightweight (in best ways) javafx-specific di framework. (it uses convention-over-configuration approach, match fxml file names controller class names, , optionally css file names, , works.)


Comments

Popular posts from this blog

sql server - Cannot query correctly (MSSQL - PHP - JSON) -

php - trouble displaying mysqli database results in correct order -

C++ Linked List -