[英]JAVAFX - FXML - Access Loaded FXML Controls from Parent Controller
[英]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>
@FXML
private ChildController childController;
@Override
public void initialize(URL url, ResourceBundle rb) {
childController.setParentController(this);
}
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
設置為父應該顯示的值。
private final StringProperty value = new SimpleStringProperty();
public StringProperty valueProperty() {
return value;
}
@FXML
private void selectButton (ActionEvent event) {
value.set("hello");
}
@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);
自身的引用傳遞給Global
類Global.setParentController(this);
。 然后,您可以使用Getter: Global.getParentController();
從子Global.getParentController();
訪問它Global.getParentController();
這比父母和孩子共享相同的控制器更好,因為它有助於保持代碼更清晰,更易於閱讀。
我自己對Java很新,這可能不是用於這種情況的最復雜的方法,但到目前為止它對我來說非常有效。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.