簡體   English   中英

JavaFX從FXML子訪問父控制器類

[英]JavaFX access parent Controller class from FXML child

使用JavaFX作為應用程序,我有一個Main.fxml文件,里面有一些fxml子文件。

我想從子控制器訪問Main.fxml的MainController類。

我將嘗試用一個例子更好地解釋:

MainFxml:

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

MainController:

    public class MainController implements Initializable {
            private String string;
            public void setString (String string) {
                    this.string = string;
            }

ChildFxml:

    <HBox fx:id="child" fx:controller="ChildController.java">
        <Button text="hello" onAction="#selectButton"></Button>
    </HBox>

ChildController:

    public class ChildController implements Initializable {
            @FXML HBox child;
            @FXML Button button;
            @FXML
            public void selectButton (ActionEvent event) {
                // here call MainController.setString("hello");
            }

我嘗試在StackOverflow上找到這個解決方案,但我需要獲取已經加載的Main.fxml的Controller引用。 是否有任何方法可以從特定的窗格啟動Controller? 就像是:

    // child.getParent().getController();

如果將fx:id分配給<fx:include>標記, FXMLLoader嘗試將包含的fxml的控制器注入名為<fx:id>Controller的字段。 您可以在initialize方法中將MainController引用傳遞給子控制器:

<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");
}

但是,更好的做法是讓ChildController獨立於父ChildController 這可以通過在ChildController中提供一個StringProperty來完成,該StringProperty設置為父應該顯示的值。

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));
}

我使用Singleton模型在自己的項目中解決了這個問題。 您可以使用單獨的類來保持對父控制器的引用。

例如:

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;
    }
}

在父控制器中,您只需要通過調用Global.setParentController(this);自身的引用傳遞給GlobalGlobal.setParentController(this); 然后,您可以使用Getter: Global.getParentController();從子Global.getParentController();訪問它Global.getParentController();

這比父母和孩子共享相同的控制器更好,因為它有助於保持代碼更清晰,更易於閱讀。

我自己對Java很新,這可能不是用於這種情況的最復雜的方法,但到目前為止它對我來說非常有效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM