I had to inject a whole controller into another controller with the guice implementation of gluon ignite. I will show an approach doing so. This is applicable if you have set the controller id in your fxml. Otherwise this snipped requires slightly modifications. I assume you have ignite already running and injecting stuff already but facing the “inject a controller for me” problem.
Create a new provider for your controller you want to inject and register it. If you decide to create this as inner class of your module you have to use a static inner class.
public class GUIConfig extends AbstractModule {
@Override
protected void configure() {
install(new ApplicationConfig());
bind(ControllerError.class).toProvider(ControllerErrorProvider.class);
}
/**
* Provides the {@link ControllerError}.
* This Controller has it's own stage.
*/
@Singleton
static class ControllerErrorProvider implements Provider<ControllerError> {
@Inject
FXMLLoader fxmlLoader;
@Inject
Injector injector;
@Override
public ControllerError get() {
ControllerError controllerError = null;
Parent node = null;
try {
// The fxml can't load the same fxml twice with the same instance but setRoot is a workaround
// http://stackoverflow.com/questions/21424843/exception-has-occuredroot-value-already-specified-in-javafx-when-loading-fxml-p
fxmlLoader.setRoot(null);
fxmlLoader.setController(null);
// The path to your fxml
fxmlLoader.setLocation( getClass().getResource(Resources.getErrorFXML()) );
// Disable the controller factory since the reference to the controller in the fxml would be a circular dependency.
fxmlLoader.setControllerFactory(null);
node = fxmlLoader.load();
controllerError = fxmlLoader.getController();
} catch (IOException e) {
e.printStackTrace();
}
if( null == controllerError) {
throw new IllegalStateException("Failed to create the ControllerError!");
}
if( null == node ) {
throw new IllegalStateException("Failed to load the fxml for the controller! Check the path is valid");
}
// Inject eventual other dependencies (that are not @FXML annotations)
injector.injectMembers(controllerError);
// This is not relevant for this snippet but might be useful anyway
// I create a new stage and set it to the controller so it is ready to use and call show() on it.
Stage stage = new Stage();
stage.setScene(new Scene(node));
controllerError.setStage(stage);
return controllerError;
}
}
}Use it to inject
public class MyController {
@Inject
private ErrorController;
@FXML
Button button1;
@Inject
FXMLLoader fxmlLoader;
}You are done! Use the injected controller as usual.