JavaFX从FXML子访问父控制器类
使用JavaFX作为应用程序,我有一个Main.fxml文件,里面有一些fxml子文件。
我想从子控制器访问Main.fxml的MainController类。
我将尝试用一个例子更好地解释:
MainFxml:
MainController:
public class MainController implements Initializable { private String string; public void setString (String string) { this.string = string; }
ChildFxml:
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
分配给
标记, FXMLLoader
尝试将包含的fxml的控制器注入名为
的字段。 您可以在initialize
方法中将MainController
引用传递给子控制器:
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
中提供一个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);
自身的引用传递给Global
类Global.setParentController(this);
。 然后,您可以使用Getter: Global.getParentController();
从子Global.getParentController();
访问它Global.getParentController();
这比父母和孩子共享相同的控制器更有利,因为它有助于保持代码更清晰,更易于阅读。
我自己对Java很新,这可能不是用于这种情况的最复杂的方法,但到目前为止它对我来说非常有效。