我正在构建一个具有多个屏幕的JavaFX应用程序,因此使用其控制器构建多个FXML文件。当应用程序启动所有FXML文件时,控制器的初始化方法已经完成。
我有一个锁屏,用户需要输入密码才能进入下一个屏幕。密码正确时,将检索员工的姓名并加载主菜单屏幕。
我想将用户名传递给主菜单屏幕中的标签,但我不能使用控制器的initialize方法,因为它已被调用。
有没有办法在显示FXML屏幕时执行操作,让我能够在控制器之间传递字符串?
非常感谢任何帮助!
PS。如果您想查看代码,请在下方发表评论。
编辑(为了更好地理解)
您可以在下面找到代码:
Main.java
public class Main extends Application {
public static String screen1ID = "loginscherm";
public static String screen1File = "Lockscreen.fxml";
public static String screen2ID = "mainmenu";
public static String screen2File = "MainMenu.fxml";
//public static String screen3ID = "screen3";
//public static String screen3File = "Screen3.fxml";
public static Functions databaseConnection;
@Override
public void start(Stage stage) throws Exception {
databaseConnection = new Functions();
databaseConnection.DB_Connect();
octocash.GUI_Screens.ScreensController mainContainer = new octocash.GUI_Screens.ScreensController();
mainContainer.loadScreen(Main.screen1ID, Main.screen1File);
mainContainer.loadScreen(Main.screen2ID, Main.screen2File);
mainContainer.setScreen(Main.screen1ID);
Group root = new Group(); //als je meerdere vensters in moet laden
root.getChildren().addAll(mainContainer);
Scene scene = new Scene(root);
stage.setScene(scene);
stage.setFullScreen(true); //full screen without borders (no program menu bars)
stage.setFullScreenExitHint(""); //Don't show "Press ESC to exit full screen"
//stage.setFullScreenExitKeyCombination(KeyCombination.NO_MATCH); //NIET AANZETTEN VOOR JE IETS ANDERS GEMAAKT HEBT ZODAT JE ERUIT KUNT
stage.show();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
LockscreenController.java
public class LockscreenController implements Initializable, ControlledScreen {
ScreensController myController;
@FXML
private PasswordField passwordField;
public FlowPane mainContent;
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
@Override
public void initialize(URL url, ResourceBundle rb) {
mainContent.setPrefSize(screenSize.getWidth(), screenSize.getHeight());
}
public void setScreenParent(ScreensController screenParent){
myController = screenParent;
}
@FXML
private void goToMainMenu(){
myController.setScreen(octocash.Main.screen2ID);
}
public static String employeeName;
public static String employeeIsAdmin;
@FXML
private void checkPassword(ActionEvent event){
String input = passwordField.getText();
String needsToBeChecked;
needsToBeChecked = (new octocash.Functions()).hashPassword(input);
String[][] employeeInfo = octocash.Main.databaseConnection.getData("some_query", Arrays.asList("naam","isAdmin"));
if(employeeInfo[0][0] != null) {
employeeName = employeeInfo[0][0];
employeeIsAdmin = employeeInfo[0][1];
goToMainMenu();
passwordField.setText("");
}
else{
passwordField.setText("");
}
}
}
MainMenuController.java
public class MainMenuController implements Initializable, ControlledScreen {
ScreensController myController;
public FlowPane mainContent;
public ToolBar toolBar;
public Region spacerToolbar;
public HBox buttonHolder;
public Button exitButton;
public Label currentlyLoggedIn;
public Button testButton;
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
@Override
public void initialize(URL url, ResourceBundle rb) {
mainContent.setPrefSize(screenSize.getWidth(), screenSize.getHeight());
toolBar.setMinWidth(screenSize.getWidth());
buttonHolder.setHgrow(spacerToolbar, Priority.ALWAYS); //Align buttonHolder to the right
}
public void setScreenParent(ScreensController screenParent){
myController = screenParent;
}
@FXML
private void exitApplication(){
Stage stage = (Stage) exitButton.getScene().getWindow();
stage.close();
}
}
现在:我想从LockscreenController获取employeeName的值并将其发送到MainMenuController,而不使用initialize方法。
答案 0 :(得分:1)
你必须找到一种方法来链接它们之间的控制器,或者只是必须有权访问其他控制器的控制器,你必须实现像
这样的方法 mainController.refreshMainMenuLabel(User user)
所以当用户登录时,该控制器将调用mainController的refreshMainMenuLabel
修改
ill给你一个2控制器的例子
首先定义AppContext
public static class AppContext{
//you can add the controllers by their variables
private Controller1 test1;
private Controller2 test2;
//or from a list which will require handling , but it will be more dynamic
private List<Controller> controllers;
private static AppContext context=null;
//You make the constructor private so its really a sigleton ,
//cause noone can access it from outer package
private AppContext()
{
}
public static AppContext getAppContext(){
if(context==null)
context=new AppContext();
return context;
}
public void setController1(Controller1 e)
{
test1=e;
}
public void setController2(Controller2 e)
{
test2=e;
}
public Controller1 getController1()
{
return test1;
}
public Controller2 getController2()
{
return test2;
}
}
所以这些方法可以像appContext.getAppContext()一样调用.getController1()来自应用程序的任何地方因为getAppcontext是静态的, 如果您有任何问题请告诉我