Issue
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.
Solution
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.
Answered By - James_D
Answer Checked By - Willingham (JavaFixing Volunteer)