如何引用另一个控制器 - JavaFX

时间:2017-10-24 16:27:19

标签: javafx

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

internalMedicineButtonClicked方法将我的场景更改为另一个(包含其他一些内容),但在这个新场景中,我想要一个允许我返回MainMenu(goBacktoMainMenuButtonClicked()方法)的按钮。这里发生了我的问题。我如何能够引用MainMenuController(与logInController中创建的fxml文件对应的那个)来填充setController()方法。

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类:

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

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 ?
    }
}

1 个答案:

答案 0 :(得分:1)

考虑使用其他模型来表示当前视图。您可以按以下方式实现此目的:

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可以:

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

和其他控制器类似。

请注意,您正在ViewState中实例化每个控制器,因此只需让该类访问其可能需要的其他每个模型。

最后,用

启动所有这些
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();
    }
}