问题描述
假设我有3个视图和3个控制器:LogInController
,LogInView
MainMenuController
,MainMenuView
ListOfPatientsInternalMedicineController
,ListOfPatientsInternalMedicineView
.
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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!