Philayyy Philayyy - 3 months ago 38
Java Question

How to pass an object between windows in JavaFX

I am new to java and need help understanding objects. I'm attempting to make an application in javaFx but having trouble to pass objects between the windows. Currently, there is a login window, if the login details are correct via checking the database, the dashboard window opens. However, I now need the

BackendInterface
object I just created when pressing the login button in the dashboard window to call its methods from the
BackendInterface
class. What I have now gives a null pointer exception.

Adding a constructor to the
LoginController
class which passes
this.backendInterface
yields a fxml load exception

So my question is how do you pass an instantiated object to another window to use it's methods?

Main

public class MainGui extends Application {

@Override
public void start(Stage primaryStage) throws Exception {

Parent root = FXMLLoader.load(getClass().getResource("login.fxml"));
primaryStage.setTitle("Login");
primaryStage.setScene(new Scene(root));
primaryStage.show();

}


public static void main(String[] args) {
launch(args);
}
}


LoginController for login button

public class LoginController {

BackendInterface backendInterface;

@FXML
TextField username;

@FXML
PasswordField password;

@FXML
Button loginButton;

@FXML
Label loginLabel;

@FXML
public void loginButtonPress(){

if (username.getText().isEmpty() == true || password.getText().isEmpty() == true ) {

loginLabel.setText("Please enter data in the fields below");

} else {

//initialises backend interface with username and password
backendInterface = new BackendInterface(username.getText(), password.getText().toCharArray());

//opens a connection to the database
backendInterface.openConnection();

if (backendInterface.getConnectionResponse() == "success"){

//return and print response
System.out.println(backendInterface.getConnectionResponse());

//directs the user to the dashboard after successful login
try{

FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("dashboard.fxml"));
Parent root1 = (Parent) fxmlLoader.load();
Stage stage = new Stage();
stage.initModality(Modality.APPLICATION_MODAL);
stage.setTitle("Welcome " + username.getText());
stage.setScene(new Scene(root1));
stage.show();

//Closes the login screen window
Stage stage2 = (Stage) loginButton.getScene().getWindow();
stage2.hide();

} catch (Exception e){
e.printStackTrace();
}

} else {
//warns user of invalid login
loginLabel.setText(backendInterface.getConnectionResponse());
}
}
}
}


DashboardController for button on dashboard

public class DashboardController {

@FXML
public void doStuff(){

LoginController loginController = new LoginController();

loginController.backendInterface.printSomething();


}

}


UPDATED SOLUTION based on Clayns response:

First Controller load new page and pass object

FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("dashboard.fxml"));
loader.load();
Parent p = loader.getRoot();
Stage stage = new Stage();
stage.setScene(new Scene(p));

DashboardController dashboardController = loader.getController();
dashboardController.setBackendInterface(backendInterface);


Second Controller retrieve object method

public void setBackendInterface(BackendInterface backendInterface) {
this.backendInterface = backendInterface;
}

Answer

You are creating a new LoginControllerin your DashboardController that has nothing to do with the one that was used for the login.

You should give your DashboardController a method to set the BackendInterface and than in the LoginController use fxmlLoader.getController() to get the DashboardController and pass the BackendInterface to it.

Edit: The answer from fabian works the same way