package org.peerbox.guice; import java.io.IOException; import javafx.fxml.FXMLLoader; import javafx.util.Callback; import com.google.common.base.Preconditions; import com.google.inject.Inject; import com.google.inject.Injector; /** * This class complements the JavaFX FXMLLoader with Google Guice support. The FXML Loader * responsible for loading .fxml files does only create the controller instance without * further dependencies. * * The GuiceFxmlLoader uses dependency injection for creating the controller instances (and for * providing their annotated dependencies). * The GuiceFxmlLoader instance should be reused as it returns new FXMLLoader instances. * * @author albrecht * */ public class GuiceFxmlLoader implements IFxmlLoaderProvider { /** * The injector to use for creating the controller instances, */ private Injector injector; /** * Creates a new Guice FXML loader. * Note: it may be important which injector instance is passed to this instance, * e.g. due to singletons managed by the container that are then injected into * controller instances. * * @param injector instance to use for creating controllers */ @Inject public GuiceFxmlLoader(Injector injector) { if (injector == null) { throw new IllegalArgumentException("Injector must not be null."); } this.injector = injector; } public GuiceFxmlLoader() { this.injector = null; } /** * Creates a new FXMLLoader instance. The location is set to the provided .fxml file name. * The controller will be created using DI. The FXMLLoader is provided ready to be used, e.g. * FXMLLoader loader = guiceFxmlLoader.create("/views/form.fxml"); * Node content = loader.load(); * FormController controller = (FormController) loader.getController(); * // do something with the UI element and the controller... * * @param fxmlFile the name of the .fxml file * @return an FXMLLoader instance, ready to call load() on it * @throws IOException in case .fxml file cannot be loaded */ @Override public FXMLLoader create(final String fxmlFile) throws IOException { Preconditions.checkNotNull(injector); FXMLLoader loader = create(fxmlFile, injector); return loader; } @Override public FXMLLoader create(final String fxmlFile, Injector injector) throws IOException { FXMLLoader loader = new FXMLLoader(); loader.setLocation(getClass().getResource(fxmlFile)); loader.setControllerFactory(new Callback<Class<?>, Object>() { @Override public Object call(Class<?> type) { return injector.getInstance(type); } }); return loader; } }