JavaFX access parent Controller class from FXML child

扶醉桌前 提交于 2019-12-04 06:39:39
fabian

If you assign a fx:id to the <fx:include> tag, FXMLLoader tries to inject the the controller of the included fxml to a field named <fx:id>Controller. You can pass the MainController reference to the child controllers in the initialize method:

<HBox fx:controller="MainController.java">
    <fx:include fx:id="child" source="child.fxml"/>
</HBox>

MainController

@FXML
private ChildController childController;

@Override
public void initialize(URL url, ResourceBundle rb) {
    childController.setParentController(this);
}

ChildController

private MainController parentController;

public void setParentController(MainController parentController) {
    this.parentController = parentController;
}

@FXML
private void selectButton (ActionEvent event) {
    this.parentController.setString("hello");
}

It would however be better practice to keep the ChildController independent from the parent. This could be done by providing a StringProperty in the ChildController that gets set to the value the parent should display.

ChildController

private final StringProperty value = new SimpleStringProperty();

public StringProperty valueProperty() {
    return value;
}

@FXML
private void selectButton (ActionEvent event) {
    value.set("hello");
}

ParentController

@Override
public void initialize(URL url, ResourceBundle rb) {
    childController.valueProperty().addListener((observable, oldValue, newValue) -> setString(newValue));
}

I solved this issue in my own projects with the use of the Singleton model. You can use a separate class to keep references to parent controllers.

For example:

Global.java:

public class Global {

    public static ParentControllerClass parentController;

    private Global() {
    }

    public static ParentControllerClass getParentController() {
        return mainApp;
    }

    public static void setParentController(ParentControllerClass parentController) {
        Global.parentController = parentController;
    }
}

Within your parent controller, you would just need to pass a reference to itself to the Global class by calling Global.setParentController(this);. You can then access it from the child by using the Getter: Global.getParentController();

This is preferable to having the parent and child share the same controller as it helps to keep your code cleaner and easier to read.

I am fairly new to Java myself and this may not be the most sophisticated method to use for this scenario, but it has worked perfectly for me thus far.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!