In my Guice Module I want to associate FXML files and their controllers, currently it looks like this:
public class GuiceModule extends AbstractModule
{
@Override
protected void configure()
{
// associate controllers and fxml files
bind(MainController.class).toInstance((MainController)loadController("/main.fxml"));
bind(SubController.class).toInstance((SubController)loadController("/content.fxml"));
}
protected Object loadController(String url)
{
InputStream fxmlStream = null;
try
{
fxmlStream = getClass().getResourceAsStream(url);
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource(url));
loader.setControllerFactory(new Callback<Class<?>, Object>() {
public Object call(Class<?> clazz) { // clazz because class is a reserved word
return injector.getInstance(clazz); // PROBLEM: no access to the injector here
}
});
loader.load(fxmlStream);
return loader.getController();
}
// [..] exception handling
}
}**strong text**
However in the loadController(String url)
method I get problems with that line:
return injector.getInstance(clazz); // PROBLEM: no access to the injector here
How can I access Guice's getInstance
method from within a Guice Module? Is that or something equivalent possible?
I will suggest one of many approaches to associate a Controller to an FXML file, I will suppose that you are using the fx:controller tag in your FXML file.
for the demonstration purpose, I will implement a demo app hosted on github with one button in the middle of the stage.
View.fxml
note that we refer to the interface in the fx:controller in the FXML file, and not to the implementation, so we can reuse the fxml view with other controllers implementing the interface.
IController
an interface that the controller must implement , the
printButton()
to print a message to the screen , andgetRoot()
to get the Panel View.Controller
InjectingFXMLLoader
a class with one static method that get a concrete implementation of a controller and URL of the FXML file and return the controller of the view.
AppModule
in the guice module , we use the InjectingFXMLLoader class to associate a concrete implementation of the controller with the corresponding FXML file. using a @Provides method.
App
the main class that show the view
I am the author of fx-guice, an open-source library that can be used to use Guice in your JavaFX applications. The library is licensed using the Apache License v2 and can be obtained via the central Maven repository.
Even though it might not answer your exact question, I suggest you have a look at my project, which comes bundled with quite a few examples:
Project home: → http://github.com/cathive/fx-guice/
The main idea of my framework is: Instead of extending "javafx.application.Application" you extend "com.cathive.fx.GuiceApplication". You can then simply @Inject instaces of "GuiceFXMLLoader" wherever you want and can use these special FXMLLoader instances to load your UI definitions. Within your FXML-controller classes you can mix @Inject and @FXML annoations as you like.
→ http://bit.ly/139fKQV
My framework also offers a bunch of functionality concerning "Guicified" JavaFX components, which bind together a Java class and a single FXML file (using a special annotation: "@FXMLComponent"). I wrote a short "Calculator" example whose sources can be obtained from the Github pages (see above). The relevant portions of the code can be found here:
CalculatorAppPane.java: → http://bit.ly/10YMVoM
CalculatorAppPane.fxml: → http://bit.ly/13loYv8
Hope that helps. :-)