Sunday, 1 July 2012

Creating JavaFX Controllers Using Guice

I really like Guice Dependency Injection so was pleased to hear that some work has been done to make this interact with JavaFX. The solution presented though, was less than ideal. It had some duplication of configuration where the class name of the controller needed to specified in the FXML as you would expect but also when loading it. After a brief fumble through FXMLLoader's methods I found #setControllerFactory. By passing this wafer thin adapter below as a parameter to #setControllerFactory, any controllers will be instantiated via Guice.

/**
* A JavaFX controller factory for constructing controllers via Guice DI. To
* install this in the {@link FXMLLoader}, pass it as a parameter to
* {@link FXMLLoader#setControllerFactory(Callback)}.
* <p>
* Once set, make sure you do <b>not</b> use the static methods on
* {@link FXMLLoader} when creating your JavaFX node.
*/
class GuiceControllerFactory implements Callback<Class<?>, Object> {
private final Injector injector;
public GuiceControllerFactory(Injector anInjector) {
injector = anInjector;
}
@Override
public Object call(Class<?> aClass) {
return injector.getInstance(aClass);
}
}