-1

I'm new to JavaFx and I've been trying to get this working for the last 2 days:

I have a scene (MainScene.fxml) that only consists of a border pane. In the border pane head I have an anchor pane that should always stay the same. And in the border pane center, I've already managed to load another scene (LoginScene.fxml) with my "MainController.java" when initializing.

Now the following problem: My LoginScene has a button with which I want to change the scene in my Border Pane center again. So far I haven't found a solution how I can load the scene in my "MainController.java" from my "LoginController.java" with a button ActionEvent. Is that even possible or is there a better solution?

MainController.java

package application;

import java.io.IOException;

import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;

public class MainController {

    @FXML
    public BorderPane borderpane;
    @FXML
    private Button exitButton;

    @FXML
    private void btnExit() {
        Platform.exit();
    }

    @FXML
    private void initialize() throws IOException {
        AnchorPane view = FXMLLoader.load(getClass().getResource("/ui/LoginScene.fxml"));
        borderpane.setCenter(view);
    }
}

LoginController.java

package application;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;

public class LoginController {
    @FXML
    private Button loginButton;

    @FXML
    void btnLogin(ActionEvent event) {

    }
}

MainScene.fxml MainScene

LoginScene.fxml LoginScene

ManagerScene.fxml ManagerScene should replace the login scene inside my Border Pane center when the login button is pressed.

Trizakz
  • 5
  • 2
  • 1
    Similar question: [Loading new fxml in the same scene](https://stackoverflow.com/questions/18619394/loading-new-fxml-in-the-same-scene) – jewelsea Jun 03 '22 at 19:32

1 Answers1

2

Just pass an appropriate object to the LoginController telling it what to do when the button is pressed:

public class MainController {

    @FXML
    public BorderPane borderpane;
    @FXML
    private Button exitButton;

    @FXML
    private void btnExit() {
        Platform.exit();
    }

    @FXML
    private void initialize() throws IOException {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("/ui/LoginScene.fxml"));
        AnchorPane view = loader.load();
        LoginController loginController = loader.getController();
        loginController.setOnLogin(() -> loadManagerView());
        borderpane.setCenter(view);
    }

    private void loadManagerView() {
        try {
            Parent managerView = FXMLLoader.load(getClass().getResource("/ui/ManagerScene.fxml"));
            borderpane.setCenter(managerView);
        } catch (Exception exc) {
            exc.printStackTrace();
        }
    }
}

and

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;

public class LoginController {
    @FXML
    private Button loginButton;

    private Runnable onLogin ;

    @FXML
    void btnLogin(ActionEvent event) {
        onLogin.run();
    }

    public void setOnLogin(Runnable onLogin) {
        this.onLogin = onLogin ;
    }
}

There are many other options; e.g. using a view model which keeps track of the "current view" as a JavaFX Property, observing that from the MainController and updating it from the LoginController. See, among quite a few examples, this question.

James_D
  • 201,275
  • 16
  • 291
  • 322