0

I have a mainView.fxml which includes 3 separate fxml files. My mainView is designed like that (VBox)

+------------------------+
+ menu (menu.fxml)       +
+------------------------+
+ toolbar (toolbar.fxml) +
+------------------------+
+                        +
+ dashboardHome          +
+ (dashboardHome.fxml)   +
+------------------------+

All they have their own controllers. Now I want to load a different dashboardhome content depending on the toolbar button I clicked.

In the toolbarController I put

public void onButton3Click(ActionEvent actionEvent) throws IOException {
        MainController main = new MainController();
        main.loadContent();

    }

and in the MainController I put

@FXML
private AnchorPane dashboardHome;

public void loadContent() throws IOException {

        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("view/courseView.fxml"));
        AnchorPane newPane = fxmlLoader.load();
        dashboardHome.getChildren().setAll(newPane);

    }

Gives me Caused by: java.lang.IllegalStateException: Location is not set.

How can I change the dashboardHome AnchorPane?

(generally speaking is my approach correct to modularise the design like that or are there better practices recommended? thanks - I am still at the bottom of the learning curve)

Marko
  • 47
  • 5
  • [How do I determine the correct path for FXML files, CSS files, Images, and other resources needed by my JavaFX Application](https://stackoverflow.com/questions/61531317/how-do-i-determine-the-correct-path-for-fxml-files-css-files-images-and-other) – Abra Jul 22 '23 at 10:34
  • Unrelated, but give things proper names, not `button3`, unless that really is the best name that applies, and don't call something `main`, that has specific meanings in Java. – jewelsea Jul 22 '23 at 12:25

1 Answers1

3

The concept (loading a new pane from fxml into a section of the UI), is fine. The implementation is not.

Fixing immediate issues

Your first issue is the location not found issue Abra refers to in comments, which can be resolved by following instructions at:

The next issue is, calling new on a Controller which is not set on a loader and loaded. That won't work. None of the fxml fields in the controller will be injected and initialized, e.g. dashboardHome will be null. Usually, it is better to specify the controller in the fxml. When you load the fxml, the loader will create a new controller instance for you and populate its fxml fields.

However, you don't need to load the main fxml again. You already loaded the fxml once, so you will already have an associated controller instance. You could store a reference to the existing main controller instance and access it, passing the reference from parent to child using:

Alternate approaches

But really, you shouldn't have controllers trying to interact with other controllers (outside of passing initialization data into the controller when it is first loaded). Controllers are designed for UI interaction, coordinating back-end services and interacting with a UI model, and not for other controllers to interact with them.

Alternates are in the answer to:

Where answers are:

  • the MVC navigation model by James (more complex)
  • using scene graph navigation (less complex, but more brittle).

A third way is using a static scene store which is demoed in:

Which provides some example code.

jewelsea
  • 150,031
  • 14
  • 366
  • 406