如何获得对另一个控制器的引用-JavaFX [英] How to get reference to another controller - JavaFX

查看:45
本文介绍了如何获得对另一个控制器的引用-JavaFX的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有3个视图和3个控制器:
LogInControllerLogInView
MainMenuControllerMainMenuView
ListOfPatientsInternalMedicineControllerListOfPatientsInternalMedicineView.

Let's say I've got 3 views and 3 controllers:
LogInController, LogInView
MainMenuController, MainMenuView
ListOfPatientsInternalMedicineController, ListOfPatientsInternalMedicineView.

一个internalMedicineButtonClicked方法将我的场景更改为另一个场景(具有其他一些内容),但是在这个新场景中,我想要一个按钮,使我可以返回MainMenu(goBacktoMainMenuButtonClicked()方法).这就是我的问题.如何获得对MainMenuController的引用(与在LogInController中创建的fxml文件相对应的那个)来填充setController()方法.

An internalMedicineButtonClicked method change my scene to another (with some other content) but in this new scene, I want to have a button which allows me to go back to MainMenu (goBacktoMainMenuButtonClicked() method). And here occures my problem. How am I able to get reference to MainMenuController (the one which is corresponding with fxml file, created in LogInController) to fill setController() method.

public class LogInController {

MainMenuController mainMenuController =  new MainMenuController();
@FXML
private JFXTextField logInTextField;
@FXML
private JFXButton logInButton;
@FXML
private JFXPasswordField passwordTextField;

@FXML
void logInButtonClicked(ActionEvent event) throws IOException {
    LogInDAO logInDAO = new LogInDAO();
    if(logInDAO.checkIfLoginAndPasswordIsCorrect(logInTextField.getText(),passwordTextField.getText()))
    {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/MainMenu.fxml"));
        Window window = logInButton.getScene().getWindow();
        Stage stage = (Stage) window;
        loader.setController(mainMenuController); // here i'm passing original controller corresponding with fmxl
        stage.setScene(new Scene(loader.load()));
    }
    else
    {
             (...)
    }
}

}

MainMenuCotroller类:

MainMenuCotroller class:

public class MainMenuController {
ContentOfPatientTableView patientTableViewModel = new ContentOfPatientTableView();
(..)
  @FXML
    void internalMedicineButtonClicked(ActionEvent event) throws IOException {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/ListOfPatientsInternalMedicineView.fxml"));
        Button button = (Button) event.getSource();
        Scene scene = button.getScene();
        Stage stage = (Stage) scene.getWindow();
        loader.setController(new ListOfPatientsInternalMedicineController(patientTableViewModel));
        stage.setScene(new Scene(loader.load()));

    }

和ListOfPatientsInternalMedicineController类;

And ListOfPatientsInternalMedicineController class;

public class ListOfPatientsInternalMedicineController {
    IPatientDAO patientDAO = new PatientDAO();
    ContentOfPatientTableView patientTableViewModel;

    public ListOfPatientsInternalMedicineController(ContentOfPatientTableView content) {
        patientTableViewModel=content;
    }
    @FXML
    public void goBacktoMainMenuButtonClicked(ActionEvent event)
    {
        FXMLLoader loader = new FXMLLoader(MainMenuController.class.getResource("/fxml/MainMenuView.fxml");
        loader.setController(?????????); // Here if I will pass new MainController() i will create new instance, not this which is corresponding with fxml file. How am I able to refer to instance MainController created in LogInController ?
    }
}

推荐答案

考虑使用其他模型来表示当前视图.您可以按照以下几行来实现:

Consider using another model to represent the current view. You could implement this along the following lines:

public class ViewState {

    private final ContentOfPatientTableView patientTableViewModel ;

    private final ReadOnlyObjectWrapper<Parent> currentView = new ReadOnlyObjectWrapper<>();

    private Parent logInView ;
    private Parent mainMenuView ;
    private Parent listOfPatientsMainMedicineView ;

    public ViewState(ContentOfPatientTableView patientTableViewModel) {
        this.patientTableViewModel = patientTableViewModel ;
    }

    public ReadOnlyObjectProperty<Parent> currentViewProperty() {
        return currentView.getReadOnlyProperty();
    }

    public void showLogIn() {
        if (logInView == null) {
            try {
                FXMLLoader loader = new FXMLLoader("/fxml/LogIn.fxml");
                loader.setController(new LogInController(this));
                logInView = loader.load();
            } catch (IOException exc) {
                // fatal...
                throw new UncheckedIOException(exc);
            }
        }
        currentView.set(logInView);
    }

    public void showMainMenu() {
        // similarly...
    }

    public void showListOfPatientsMainMedicineView() {
        // ...
    }
}

现在您的LogInController可以执行以下操作:

Now your LogInController can do:

public class LogInController {

    private final ViewState viewState ;

    @FXML
    private JFXTextField logInTextField;
    @FXML
    private JFXButton logInButton;
    @FXML
    private JFXPasswordField passwordTextField;

    public LogInController(ViewState viewState) {
        this.viewState = viewState ;
    }

    @FXML
    void logInButtonClicked(ActionEvent event) {
        LogInDAO logInDAO = new LogInDAO();
        if(logInDAO.checkIfLoginAndPasswordIsCorrect(logInTextField.getText(),passwordTextField.getText()))
        {
            viewState.showMainMenu();
        }
        else
        {
                 (...)
        }
    }

}

类似地,

public class MainMenuController {

    private final ViewState viewState ;

    public MainMenuController(ViewState viewState) {
        this.viewState = viewState ;
    }

    @FXML
    void internalMedicineButtonClicked(ActionEvent event) throws IOException {
        viewState.showListOfPatientsMainMedicineView();
    }
}

,对于其他控制器也类似.

and similarly for the other controller.

请注意,您正在实例化ViewState中的每个控制器,因此只需为该类提供对它可能需要的其他每个模型的访问权限即可.

Note that you are instantiating each controller in ViewState, so just give that class access to each of the other models it may need.

最后,您可以使用以下所有方法来启动所有

Finally, you boot all this up with

public class MyApp extends Application {

    @Override
    public void start(Stage primaryStage) {
        ViewState viewState = new ViewState(/* pass models here...*/);
        viewState.showLogIn();
        Scene scene = new Scene(viewState.currentViewProperty().get());
        scene.rootProperty().bind(viewState.currentViewProperty());
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

这篇关于如何获得对另一个控制器的引用-JavaFX的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆