Can you write two different Java FX scenes as two separate classes?

Pete picture Pete · Apr 11, 2016 · Viewed 11.4k times · Source

I'm a beginning Java programmer, finishing up the "Java 101" class at my local university. I'm also pushing myself to learn some extra topics on the side, including Java FX. I've worked through the Java FX tutorials on Oracle's website, plus sat through some YouTube videos, plus read "Java FX for Dummies" (which was the best book I could find for a beginner.) All of this material has taught me a lot of the basics, but some stuff that (should be) relatively simple escapes me.

For example: Let's say I have a Java FX program that uses multiple scenes on one stage. When the user clicks a "Switch!" button, the second scene is swapped out for the first. Easy. I can do all of this in one .java file, no problem. (See code below)

But my .java class file is getting really long and cumbersome to troubleshoot. It would be great if I could define/declare/initialize one scene as one class in one .java file and the second scene as another class in another .java file. This would make keeping track of the components of each scene much, much easier. The problem is, I can't figure out how to do this.

I'd imagine that you would write a Scene1.java class and then a Scene2.java class, and simply pass the stage object between the two when you want to switch scenes. But I can't find an example of how this is done, and all my attempts result in compiler errors or really scary runtime errors.

Does anyone know how this can be done? If so, what would I have to do to modify the SwitchScenes2() method below to create the new Scene2 object and pass it the stage?

Thanks! RAO

/*
    JavaFXExample.java
*/

import javafx.application.*;
import javafx.stage.*;
import javafx.scene.*;
import javafx.scene.layout.*;
import javafx.scene.control.*;
import javafx.event.*;
import javafx.geometry.*;

public class JavaFXExample extends Application{

    public static void main(String[] args){
    launch(args);   
}

Button btnSw1;
Button btnSw2;
Button btnClose;
HBox hbox1;
VBox vbox1;
Scene scene1;
Scene scene2;
Stage stage;

@Override public void start(Stage primaryStage){
    btnSw1 = new Button("Switch Scenes!");
    btnSw1.setOnAction(
        e -> SwitchScenes2() );
    btnSw2 = new Button("Switch back!");
    btnSw2.setOnAction(
        e -> SwitchScenes1() );
    btnClose = new Button();
    btnClose.setText("Close me!");
    btnClose.setOnAction(e -> CloseWindowClick());

    hbox1 = new HBox(10);
    hbox1.getChildren().addAll(btnSw1);
    vbox1 = new VBox(10);
    vbox1.getChildren().addAll(btnSw2, btnClose);

    scene1 = new Scene(hbox1, 300, 300);
    scene2 = new Scene(vbox1, 200, 400);

    stage = primaryStage;
    stage.setScene(scene1);
    stage.setTitle("Example App");
    stage.show();
   }

    public void SwitchScenes1(){
        stage.setScene(scene1);
    }
    public void SwitchScenes2(){
        stage.setScene(scene2);
    }
    public void CloseWindowClick(){
        stage.close();
    }
}

Answer

CVarg picture CVarg · Apr 12, 2016

What you will want to do is create separate classes that both have functions to return the scene. From there you will want to initialize these classes and with a button call a function that will add data to these scene or create a new blank scene (as a quick way to "delete" the scene). But if you want a more professional way to switch between scenes like this you will want to check out the TabPane().

Scene1 scene1 = new Scene1();
Scene2 scene2 = new Scene2();

TabPane tabPane = new TabPane();
Tab tab1 = new Tab();
tab1.setContent(scene1);
tabPane.getTabs().add(tab1);
Tab tab2 = new Tab();
tab2.setContent(scene2);
tabPane.getTabs().add(tab2);