2

I have a recursive case of FXML loading needed here.

If I choose to View an Objective, it takes me to another instance of the screen that loads a list of Strategy objects. If I choose to view a Strategy, it takes me to another instance of the screen that loads a list of Tactic objects. If I view a Tactic, it takes me to another instance of the screen that loads a list of Task objects.

A picture of my UI

Naturally, I decided to use a base controller class, ViewChildItemController to handle inheritance. Then I extended from it ViewObjective, ViewStrategy, and ViewTactic. (ViewTask makes no sense because a Task is the very lowest level item with no children).

The problem is, when I use loader.loadController(), the method returns null.

FXMLLoader loader = new FXMLLoader(this.getClass()
        .getResource(ScreenPaths.VIEW_PLAN_ITEM));
Parent root = null;
try {
    root = loader.load();
} catch (IOException e) {
}
ViewObjectiveController ctrl = loader.getController();//Return null? Why?
ObservableList<Strategy> childItems = childItemsTableView.
        getSelectionModel().getSelectedItem().getChildPlanItems();
ctrl.initValues(childItems);
DialogPopup.showNode(root);

Could it be that the base FXML being loaded is hooked to the ViewChildItemController? Do I have to create several copies of the FXML and hook the controllers separately to each ViewObjectiveController, ViewStrategyController, etc? It doesn't make much sense to do.

I could try loader.setController(), but I'm not sure if the @FXML attributes will be mapped again.

Toni_Entranced
  • 969
  • 2
  • 12
  • 29

1 Answers1

2

Turns out all I had to do was treat the controller as "dynamic".

That is, set the controller BEFORE loading the root.

@Override
protected void viewChildItem() {
    FXMLLoader loader = new FXMLLoader(this.getClass()
            .getResource(ScreenPaths.VIEW_PLAN_ITEM));
    ViewTacticController ctrl = new ViewTacticController();
    loader.setController(ctrl);
    Parent root = null;
    try {
        root = loader.load();
    } catch (IOException e) {
    }
    ObservableList<Task> childItems = childItemsTableView.
            getSelectionModel().getSelectedItem().getChildPlanItems();
    ctrl.initValues(childItems);
    DialogPopup.showNode(root);
}
Toni_Entranced
  • 969
  • 2
  • 12
  • 29
  • Just curious, any reasons for not setting your controller directly in the `fxml` ? – ItachiUchiha Aug 27 '14 at 18:45
  • I only have 1 FXML file, and 5+ different controllers for the same FXML. If I set the FXML directly, it will be hooked to one and only one controller. I have to dynamically set a new controller for every level of depth. – Toni_Entranced Aug 27 '14 at 19:05