假设我有3个视图和3个控制器:
LogInController
,LogInView
MainMenuController
,MainMenuView
ListOfPatientsInternalMedicineController
,ListOfPatientsInternalMedicineView
。
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 ?
}
}
答案 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();
}
}