Search code examples
javajavafxfxmlscenebuilderscene

How do i display different fxml files on a stage for scene builder? Switching scene?


There are other tutorials on such, but they are not in a very basic manner. Most of them have other aspects which makes beginners like myself harder to understand...

How do I switch scene or FXML files on a stage by use of a button?

Main.Java Class

package application;
	

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

public class Main extends Application {

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

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("Screen 1.fxml"));
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root, 300, 275));
        primaryStage.show();
    }


}

Controller.java Class

package application;

import javafx.fxml.FXMLLoader;

public class Controller {

	public void goToScreen2(){
		System.out.println("Going to screen2");
		
		
		
	} 
	
	public void goToScreen1(){
		System.out.println("Going to screen1");
		


		
		
	} 
}

Screen 1 fxml file

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>

<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.Controller">
   <children>
      <Button layoutX="203.0" layoutY="132.0" mnemonicParsing="false" onAction="#goToScreen2" text="Go to screen 2" />
   </children>
</Pane>

Screen 2 fxml file

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>


<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.Controller">
   <children>
      <Button layoutX="248.0" layoutY="116.0" mnemonicParsing="false" onAction="#goToScreen1" text="Go to screen 1" />
   </children>
</Pane>


Solution

  • Store controllers in the application, and show associated components as needed.

    Main.Java Class

    public class Main extends Application {
        public Controller controller1;
        public Controller controller2;
        private Stage primaryStage;
    
        public static void main(final String[] args) {
            launch(args);
        }
    
        @Override
        public void start(final Stage primaryStage) throws IOException {
            this.primaryStage = primaryStage;
    
            controller1 = load("Screen 1.fxml");
            controller2 = load("Screen 2.fxml");
    
            primaryStage.setTitle("Hello World");
            controller1.goToScreen1();
            primaryStage.show();
        }
    
        public Controller load(final String name) throws IOException {
            final FXMLLoader loader = new FXMLLoader(getClass().getResource(name));
            loader.load();
            final Controller controller = loader.getController();
            controller.configure(this, new Scene(loader.getRoot()));
            return controller;
        }
    
        public void show(final Scene scene) {
            primaryStage.setScene(scene);
        }
    }
    

    Controller.java Class

    public class Controller {
        private Main application;
        private Scene scene;
    
        public void configure(final Main application, final Scene scene) {
            this.application = application;
            this.scene = scene;
        }
    
        public void show() {
            application.show(scene);
        }
    
        public void goToScreen2() {
            application.controller2.show();
        }
    
        public void goToScreen1() {
            application.controller1.show();
        }
    }