Program-Me-Rev
Program-Me-Rev

Reputation: 6624

Error creating a custom FXML loader in Spring

I've been trying to move my JavaFx application to Spring to make use of dependency injecton. The project has become too big to move items between classes manually.

The code does not show any red error highlights on my netbeans IDE, but when I run I keep getting this error:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'homeController' defined in class wakiliproject.controllerinjection.SampleAppFactory: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public wakiliproject.controllerinjection.controllers.HomeController wakiliproject.controllerinjection.SampleAppFactory.homeController() throws java.io.IOException] threw exception; nested exception is javafx.fxml.LoadException: Base location is undefined.

I have it like this:

public class SampleApp extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    public void start(Stage stage) throws Exception {
        AnnotationConfigApplicationContext context
                = new AnnotationConfigApplicationContext(SampleAppFactory.class);

        Group box = new Group();
        HomeController homeController = context.getBean(HomeController.class);
        box.getChildren().add(homeController.getView());

        Scene scene = new Scene(box, 600, 200);
        stage.setScene(scene);
        stage.setTitle("JFX2.0 Sprung");
        stage.show();
    }
}

--

@Configuration
public class SampleAppFactory {

    @Bean
    public HomeController homeController() throws IOException {
        return (HomeController) loadController("/resources/fxml/Home.fxml");
    }

    protected Object loadController(String url) throws IOException {
        InputStream fxmlStream = null;
        try {
            fxmlStream = getClass().getResourceAsStream(url);
            FXMLLoader loader = new FXMLLoader();
            loader.load(fxmlStream);
            return loader.getController();
        } finally {
            if (fxmlStream != null) {
                fxmlStream.close();
            }
        }
    }
}

--

public class HomeController {

    @FXML
    private AnchorPane view;

    public AnchorPane getView() {
        return view;
    }
}

An extract of the FXML file looks something like this:

<?xml version="1.0" encoding="UTF-8"?>

<AnchorPane fx:id="view" prefHeight="654.0" prefWidth="900.0" styleClass="AnchorPane" visible="true" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="wakiliproject.controllerinjection.controllers.HomeController">
    <children>
        <Pane id="wrapperPane" prefHeight="600.0" prefWidth="700.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
            <children>
                <Pane id="top" layoutX="-1.0" layoutY="3.0" prefWidth="879.0" styleClass="appNav" visible="true">
                    <children>
                        <HBox id="HBox" alignment="CENTER" layoutX="12.0" layoutY="6.0" spacing="0.0">
                            <children>
                                <Label prefHeight="32.0" prefWidth="32.0" styleClass="titleBarHome" />
                                <Label prefHeight="32.0" prefWidth="32.0" styleClass="titleBarPublisher" />
                            </children>
                        </HBox>

Upvotes: 0

Views: 464

Answers (1)

James_D
James_D

Reputation: 209330

It looks like you need to set the location of your FXML file on the FXMLLoader. This can be the case if, for example, your FXML file requires resolving relative locations. Using the FXMLLoader.load(URL) method does not set the location. Try

protected Object loadController(String url) throws IOException {
    FXMLLoader loader = new FXMLLoader(getClass().getResource(url));
    loader.load();
    return loader.getController();
}

instead of the current implementation you have.

Incidentally, have you looked at afterburner.fx as a (much more lightweight) alternative to Spring for dependency injection in JavaFX?

Upvotes: 1

Related Questions