JavaFX: Best practice for navigating between UI screens

16,301

Solution 1

First, let's start out with the Stage .vs. Scene issue:

As known, the JavaFX hierarchy is based on: Stage -> Scene -> Nodes (etc).

See here:

enter image description here

Practically speaking, a rule-of-thumb in my opinion is the future:

  • If you plan on going forward to a different place in the flow of your program (login -> profile, for example) - change the Stage.

  • If you are in the same enviroment (login for the first time -> login after multiple wrong tries) - change the Scene.

As for lambdas: Ahhmmm... if your current Java/JavaFX version has the abillity - there is no reason not to use. For more about controller handlers in Java 8, see this great tutorial.

Solution 2

I use this approach for changing scenes in JavaFX:

/**
 * Controller class for menuFrame.fxml
 */
public class MenuFrameControl implements Initializable {

    @FXML private Button sceneButton1;
    @FXML private Button sceneButton2;
    @FXML private Button sceneButton3;

   /**
     * Event handling method, loads new scene from .fxml file
     * according to clicked button and initialize all components.
     * @param event
     * @throws IOException
     */
    @FXML
    private void handleMenuButtonAction (ActionEvent event) throws IOException {
        Stage stage = null;
        Parent myNewScene = null;

        if (event.getSource() == sceneButton1){
            stage = (Stage) sceneButton1.getScene().getWindow();
            myNewScene = FXMLLoader.load(getClass().getResource("/mvc/view/scene1.fxml"));
        } else if (event.getSource() == sceneButton2){
            stage = (Stage) flightBtn.getScene().getWindow();
            myNewScene = FXMLLoader.load(getClass().getResource("/mvc/view/scene2.fxml"));
        } else if (event.getSource() == sceneButton3) {
            stage=(Stage) staffBtn.getScene().getWindow();
            myNewScene = FXMLLoader.load(getClass().getResource("/mvc/view/scene3.fxml"));
        }

        Scene scene = new Scene(myNewScene);
        stage.setScene(scene);
        stage.setTitle("My New Scene");
        stage.show();
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) { }

So basically when you click the button, it saves actually displayed Stage object into stage variable. Then it loads new Scene object from .fxml file into myNewScene variable and then put this fresh loaded Scene object into your saved Stage object.

With this code you can make basic three button menu, where each button switch to different scene, using just single Stage object.

Share:
16,301
Admin
Author by

Admin

Updated on June 14, 2022

Comments

  • Admin
    Admin almost 2 years

    I want to change UI screens from login.fxml to home.fxml.

    Should I change the Stage or the Scene? I'm not sure which is the best practice? Also, can I use a lambda expression for the handler in the controller?

  • Admin
    Admin over 7 years
    Thanks! I'll probably stick for the Old-School version for now as I'm beginning out and implement lambdas later when I'm more comfortable with JavaFX