JavaFX-从子控制器到达主控制器

JavaFX-从子控制器到达主控制器,java,javafx,Java,Javafx,On说明了如何在主控制器中插入子控制器: <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

On说明了如何在主控制器中插入子控制器:

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

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

...
...
公共类MainController扩展控制器{
@FXML专用窗口对话框;
@FXML专用对话框控制器;
...
现在,我想知道如何从子控制器(在本例中为
对话框控制器
)中访问
MainController
实例


谢谢您的帮助!

我建议不要这样做。如果您的
对话框控制器
依赖于您的
MainController
,那么它不能独立于
MainController
,这会在两者之间增加不必要的耦合(即,它会破坏封装)

您可能只希望当
对话框控制器
中的某些状态发生更改时,
主控制器
中发生某些事情。因此,您应该在
对话框控制器
中将该状态作为可观察属性公开,并从主控制器观察:

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

    ...
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(...)));
    }
}
如果您确实想从
对话框控制器
访问
MainController
,则可以按照注释中的建议,通过“手动”将
MainController
注入
对话框控制器
。然而,在我看来,这是一种糟糕的设计

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


手动设置:dialogController.setMainController(此);手动设置或将MainController设置为单例。感谢您的想法!但没有类似注入的内置解决方案?可能与否重复,因为我想知道如何从子控制器实例访问主控制器。