3

I want to apologize in advance, as this is discussed previously in "Passing Parameters Directly From the Caller to the Controller", but I followed every possible solution I found and still I can't get it work.

I have difficulty in passing a parameter from one controller to another.

Specifically:

LoginController passes username to MainController.

When I click login button LoginController sets the username to the MainController. But, when Main.fxml is loaded username is NULL.

As trying to figure it out, I would like to ask:

  1. When MainController initialize() method gets called? I suppose by the time LoginController calls st.show(); ?
  2. If the previous is correct, then why MainController username is NULL, since we have already set its value in LoginController using mainController.setUsername(username) ?

Any help would be appreciated.

This is my code.

LoginController.java

public class LoginController implements Initializable {
    ...
    @FXML TextField username;

    @FXML public void actionLoginButton() {
        ...
        Stage st = new Stage();
        FXMLLoader loader = new FXMLLoader(getClass().getResource("Main.fxml"));
        Region root = (Region) loader.load();

        Scene scene = new Scene(root);
        st.setScene(scene);

        MainController mainController = loader.<MainController>getController();
        mainController.setUsername(username.getText());

        st.show();
    }
    ...
}

MainController.java

public class MainController implements Initializable {
    ...
    String username;

    @FXML Label lblWelcomeUser;

    public void setUsername(String usrname) {
        this.username = usrname;
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        ...    
        lblWelcomeUser.setText("Welcome, " + this.username);
        ...
    }
    ...
}
Community
  • 1
  • 1
John Astralidis
  • 357
  • 2
  • 4
  • 16

1 Answers1

5

The issue is the timing of your call to set username.

The initialize() method of MainController is called during the execution of the following statement:

Region root = (Region) loader.load();

At this time, the username field in MainController is null and so its value is reported as null in the welcome message. Your call to setUsername() occurs after the MainController.initialize() method has completed.

In general, the initialize() method of controller classes loaded with the FXML loader should never try to do anything with instance fields whose values have not been injected by the FXML loader. These instance fields will not have been initialized at the time that the initialize() method is invoked.

scottb
  • 9,908
  • 3
  • 40
  • 56
  • Thank you for your reply. The only solution I could figure out is to create a new User class and to store data in it. But, this is "too much" for storing only one parameter. So, for cases like this use static fields instead? – John Astralidis Jul 11 '15 at 19:51
  • 1
    Just change your `setUsername(String usrName)` to call `lblWelcomeUser.setText("Welcome, "+usrName);`. – James_D Jul 11 '15 at 20:18
  • @James_D This was so obvious that I couldn't see it at all ! Just one minor change and voila! I've been trying this the whole day. I'm really embarrassed. Thank you so much guys! – John Astralidis Jul 11 '15 at 20:34
  • if this answer helped you with your problem, please check it as the accepted answer. – scottb Jul 14 '15 at 22:35