将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");
}
我尝试this solution found on StackOverflow但我需要获取已经加载的Main.fxml的Controller引用。 是否有任何方法可以从特定的窗格启动Controller? 类似的东西:
// child.getParent().getController();
答案 0 :(得分:8)
如果您为fx:id
标记分配<fx:include>
,则FXMLLoader
会尝试将包含的fxml的控制器注入名为<fx:id>Controller
的字段。您可以使用MainController
方法将initialize
引用传递给子控制器:
<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
独立于父母。这可以通过在StringProperty
中提供ChildController
来设置父级应显示的值来完成。
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));
}
答案 1 :(得分:0)
我使用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
将引用传递给Global.setParentController(this);
类。然后,您可以使用Getter:Global.getParentController();
这比父母和孩子共享相同的控制器更有利,因为它有助于保持代码更清晰,更易于阅读。
我自己对Java很新,这对于这种情况可能不是最复杂的方法,但到目前为止它对我来说非常有效。