在this page from oracle上解释了如何在主控制器中注入子控制器:
<VBox fx:controller="com.foo.MainController">
...
<fx:include fx:id="dialog" source="dialog.fxml"/>
...
</VBox>
public class MainController extends Controller {
@FXML private Window dialog;
@FXML private DialogController dialogController;
...
现在,我想知道如何从子控制器中取出MainController
实例(在本例中为DialogController
)。
感谢您的帮助!
答案 0 :(得分:2)
我建议不要这样做。如果您的DialogController
依赖于MainController
,那么它就无法独立于MainController
使用,这会在两者之间增加不必要的耦合(即它会破坏封装)。
当MainController
中的某个状态发生变化时,您可能只希望在DialogController
中发生某些事情。因此,您应该将该状态公开为DialogController
中的可观察属性,并从主控制器中观察它:
public class DialogController {
private final ReadOnlyObjectWrapper<Person> selectedPerson = new ReadOnlyObjectWrapper<>();
public ReadOnlyObjectProperty<Person> selectedPersonProperty() {
return selectedPerson.getReadOnlyProperty();
}
public final Person getSelectedPerson() {
return selectedPersonProperty().get();
}
@FXML
private Button okButton ;
public void initialize() {
okButton.setOnAction(selectedPerson.set(new Person(...)));
}
}
然后
public class MainController extends Controller {
@FXML private Window dialog;
@FXML private DialogController dialogController;
public void initialize() {
dialogController.selectedPersonProperty().addListener((obs, oldPerson, newPerson) -> {
// ... whatever you need to do here with new data when OK is pressed in dialog...
});
}
}
如果您确实想要访问MainController
中的DialogController
,那么您可以按照评论中的建议,通过&#34;手动&#34;将MainController
注入DialogController
。然而,这是糟糕的设计,imo。
public class DialogController {
// Ugh. DialogController cannot be used outside the context where
// MainController exists.
private MainController mainController ;
@FXML
private Button okButton ;
public void setMainController(MainController mainController) {
this.mainController = mainController ;
}
public void initialize() {
okButton.setOnAction(e -> {
if (mainController != null) {
mainController.doSomething();
}
});
}
}
并且
public class MainController {
@FXML
private DialogController dialogController ;
public void initialize() {
dialogController.setMainController(this);
}
public void doSomething() {
// ...
}
}