有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

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;

    ...

现在,我想知道,如何从子控制器(在本例中是DialogController)到达MainController实例

谢谢你的帮助


共 (1) 个答案

  1. # 1 楼答案

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

    DialogController中的某些状态发生变化时,您可能只希望在MainController中发生一些事情。因此,您应该在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...
            });
        }
    }
    

    如果您真的想从DialogController访问MainController,那么您可以按照注释中的建议,通过“手动”将MainController注入到DialogController中。然而,这是糟糕的设计,国际海事组织

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