bashoogzaad
bashoogzaad

Reputation: 4781

Perform action on showing FXML with JavaFX 8

I am building a JavaFX application with multiple screen, and therefore multiple FXML files with their controllers. The initialize method of the controller is already done when the application starts for all FXML files.

I have a lockscreen, where a user needs to type a password to enter the next screen. When the password is correct, the name of the employee is retrieved and the main menu screen is loaded.

I would like to pass the name of the user to a label in the main menu screen, but I can not use the initialize method of the controller, since it is already called.

Is there a way to perform an action on showing a FXML screen, to enable me to pass the string between controllers?

Any help is much appreciated!

ps. If you would like to see the code, comment below.

EDIT (for better understanding)

Below you can find the code:

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

Now: I want to get the value for employeeName from LockscreenController and send it to MainMenuController, without using the initialize method.

Upvotes: 1

Views: 740

Answers (1)

AntJavaDev
AntJavaDev

Reputation: 1262

you have to figure out a way to link the controllers between them , or just the controllers that must have access to other controllers and you have to implement a method like

mainController.refreshMainMenuLabel(User user)

so when a user is logged in, that controller will call the refreshMainMenuLabel of the mainController

EDIT

ill give you an example with 2 controllers

1st define the 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;
           }  

        }

so those methods can be called like AppContext.getAppContext().getController1() from everywhere in your app cause getAppcontext is static, if you have any problems let me know

Upvotes: 1

Related Questions