Treeno1
Treeno1

Reputation: 139

Switching scenes the FXML way (SceneBuilder)

I have two scenes, scene 1 has a Label on it that simply reads "This is scene 1", it also has a button on it with the text "Press me to go to scene 2". scene 2 is similar to scene 1 but the Label and text on scene 2 say the opposite.

The problem is very simple, or at least should be. I am able to do this the javaFX way but cannot seem to do it the FXML way.

I have a main class -

import java.io.IOException;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;

public class ManinApp extends Application
{
Stage primaryStage;
private AnchorPane rootLayout;

public static void main(String [] args)
{
    launch(args);
}
public void start(Stage primaryStage)
{
    this.primaryStage = primaryStage;
    this.primaryStage.setTitle("Two Scenes");

    initRootLayout();
    //showSecondScene();
}
public void initRootLayout()
{
    try
    {
        FXMLLoader loader = new FXMLLoader();
        loader.setLocation(ManinApp.class.getResource("Scene1.fxml"));
        rootLayout = (AnchorPane) loader.load();

        Scene scene = new Scene(rootLayout);
        primaryStage.setScene(scene);
        primaryStage.show();

    }
    catch(IOException e)
    {
        e.printStackTrace();
    }
}
/**
public void showSecondScene()
{
    try
    {
        FXMLLoader loader = new FXMLLoader();
        loader.setLocation(ManinApp.class.getResource("Scene2.fxml"));
        AnchorPane secondScene = (AnchorPane)loader.load();
        rootLayout.getChildren().add(secondScene);



    }
    catch(IOException e)
    {
        e.printStackTrace();
    }
}
*/
public Stage getPrimaryStage()
{
    return primaryStage;
}

}

the showSecondScene() has been commented out for now. My understanding is that you also need a Controller class to wire up the code to SceneBuilder?

the solution the FX way was

         btnscene1.setOnAction(e ->
            {
        if(e.getSource() == btnscene1)
            thestage.setScene(scene2);
        else
            thestage.setScene(scene1);

            });
        btnscene2.setOnAction(e ->
           {
       if(e.getSource()==btnscene2)
        thestage.setScene(scene1);
        else
           thestage.setScene(scene2);
      });

apologies for the formatting!

how am I able to do this using a controller class from which i am able to use the primary stage and two scene declared in my main class?

i hope it makes sense

Upvotes: 3

Views: 1231

Answers (2)

Jerome Cambon
Jerome Cambon

Reputation: 51

I think your are doing quite well. FXML (and SceneBuilder) are used correctly here.

I would suggest few things:

  • Use a root container (e.g. StackPane) to host either scene1 or scene2 (better names would be layout1 / layout2). You don't need to use different Scene here.
  • Load both fxml files at init time (or lazy loading if needed)
  • switch from one to the other by removing the content of the root container, and adding the other one.

Now, if the layouts are big, with a lot of css involved, and you need to switch very often from layout1 to layout2, you may want to add both layout in the root container. Then, use:

setVisible()
setManaged()

... on the root of the layout you want to hide / show. Doing this, you avoid the layout and css steps that is done as soon as you add a node in the scene graph.

Upvotes: 2

dzim
dzim

Reputation: 1153

While I technically understand, what you want to achieve, I'm still lost about the reason behind it.

If you just want to switch the "main" content of the window, use a StackPane as the root, add multiple Layouts to that stack, and solve your problem by switching the one you want to work on #toFront().

Normally the Layouts on the stack are transparent (except for the controls like buttons and so on, of course), so you would either need to set a background of the stacked Layouts OR (which I would prefer) toggle the visibility of the one in the back (or set opaqueness to 0, or something like that).

Upvotes: 0

Related Questions