JavaFX: Best practice for navigating between UI screens
Asked Answered
R

2

12

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?

Romilly answered 22/11, 2016 at 19:56 Comment(2)
Please post a minimal reproducible example.Ambulator
I requested an example demonstrating the problem because I want to know what you've tried so far. This is a question I would expect you could answer yourself through some introductory tutorials or a little tinkering on your part.Ambulator
S
17

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.

Snap answered 22/11, 2016 at 20:18 Comment(1)
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 JavaFXRomilly
I
6

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.

Ironclad answered 22/11, 2016 at 21:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.