FxmlNodeLoader.java
/**
* Copyright (c) 2017 European Organisation for Nuclear Research (CERN), All Rights Reserved.
*/
package org.minifx.fxmlloading;
import static java.util.Objects.requireNonNull;
import static org.minifx.fxmlloading.util.FxmlControllers.useOnceOrThrow;
import java.io.IOException;
import java.net.URL;
import org.minifx.fxmlloading.configuration.FxmlLoadingConfiguration;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.layout.StackPane;
import javafx.util.Callback;
public class FxmlNodeLoader {
private final Callback<Class<?>, Object> controllerFactory;
private final FxmlLoadingConfiguration configuration;
private FxmlNodeLoader(FxmlLoadingConfiguration convention, Callback<Class<?>, Object> controllerFactory) {
this.configuration = requireNonNull(convention, "controller convention must not be null");
this.controllerFactory = requireNonNull(controllerFactory, "controllerFactory must not be null");
}
public static final Parent loadNodeFrom(FxmlLoadingConfiguration convention,
Callback<Class<?>, Object> childControllerFactory) {
return new FxmlNodeLoader(convention, childControllerFactory).create();
}
private Parent create() {
return loadFxml();
}
private Parent loadFxml() {
URL fxmlUrl = configuration.fxmlResource();
try {
FXMLLoader loader = new FXMLLoader(fxmlUrl, configuration.resourceBundle());
loader.setLocation(fxmlUrl);
loader.setControllerFactory(c -> useOnceOrThrow(provideController(c)));
return loader.load();
} catch (IOException e) {
throw new RuntimeException("Unable to load fx node from '" + fxmlUrl + "'", e);
}
}
private static final Parent stackPaneOf(Parent root) {
StackPane stackPane = new StackPane();
stackPane.getChildren().add(root);
return stackPane;
}
private Object provideController(Class<?> clazz) {
Object controller = controllerFactory.call(clazz);
if (controller == null || !clazz.isAssignableFrom(controller.getClass())) {
throw new IllegalStateException("ControllerFactory [" + controllerFactory.getClass().getName()
+ "] returned a controller [" + controller + "] that is not compatible with the requested type ["
+ clazz.getName() + "]");
}
return controller;
}
}