How to switch scenes in JavaFX

Deadly 提交于 2019-11-29 04:08:29

I wrote this controller to keep track of the different scenegraphes.

public class ScreenController {
    private HashMap<String, Pane> screenMap = new HashMap<>();
    private Scene main;

    public ScreenController(Scene main) {
        this.main = main;
    }

    protected void addScreen(String name, Pane pane){
         screenMap.put(name, pane);
    }

    protected void removeScreen(String name){
        screenMap.remove(name);
    }

    protected void activate(String name){
        main.setRoot( screenMap.get(name) );
    }
}

So I can write:

ScreenController screenController = new ScreenController(scene);
screenController.add("calculator", FXMLLoader.load(getClass().getResource( "calculator.fxml" )));
screenController.add("testSwitch", FXMLLoader.load(getClass().getResource( "TestSwitch.fxml" )));
screenController.activate("calculator");

This was a workaround for a fullscreen application, where the MacOS fullscreen transition was shown every time a stage switches its scene.

Instead of switching Scenes, switch a root node on already existing Scene

If you want to go along with changing the scene you would do it like this (note that the Stage is a member of the application):

private Stage primaryStage;

@Override
public void start(Stage primaryStage) throws Exception {
    this.primaryStage = primaryStage;
    ...
}

public void changeScene(String fxml){
    Parent pane = FXMLLoader.load(
           getClass().getResource(fxml));

   Scene scene = new Scene( pane );
   primaryStage.setScene(scene);
}

However as already pointed out by @Eugene_Ryzhikov it is a better solution to just change the root content of the existing scene:

public void changeScene(String fxml){
    Parent pane = FXMLLoader.load(
           getClass().getResource(fxml));

   primaryStage.getScene().setRoot(pane);
}

It seems OP already solved it but since it is still open and unsolved i will share a solution i found in another answer. Remember to either select an correct answer or post your own solution when a question is solved, it helps people in the future that runs in the same issue (like i did).

I just run in the same issue and this answer solved my issue perfectly while being short and clean.

@FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
label.setText("Hello World!");
//Here I want to swap the screen!

Stage stageTheEventSourceNodeBelongs = (Stage) ((Node)event.getSource()).getScene().getWindow();
// OR
Stage stageTheLabelBelongs = (Stage) label.getScene().getWindow();
// these two of them return the same stage
// Swap screen
stage.setScene(new Scene(new Pane()));

}

PS.: Remember to check the original answer and upvote it. The guy deserves...

PPS.: I am not sure just copying an answer is okay (instead of just sharing the link through a comment) but since this doesnt have a correct answer yet i decided to do it for visibility.

TypesController.java
package todoapp;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.stage.Stage;

public class TypesController implements Initializable {
@FXML
private CheckBox c1;
@FXML
private CheckBox c2;
public void clicked(ActionEvent e) throws IOException {
Parent home_page_parent =FXMLLoader.load(getClass().getResource("AddDcuFXML.fxml"));
Scene home_page_scene = new Scene(home_page_parent);
Stage app_stage = (Stage) ((Node) e.getSource()).getScene().getWindow();
app_stage.hide(); //optional
app_stage.setScene(home_page_scene);
app_stage.show();
}
public void clicked1(ActionEvent e) throws IOException {
Parent home_page_parent =   FXMLLoader.load(getClass().getResource("AddDcuFXML.fxml"));
    Scene home_page_scene = new Scene(home_page_parent);
    Stage app_stage = (Stage) ((Node)e.getSource()).getScene().getWindow();
   app_stage.hide(); //optional
   app_stage.setScene(home_page_scene);
   app_stage.show();
   }
  @Override
  public void initialize(URL arg0, ResourceBundle arg1) {
 // TODO Auto-generated method stub
  } }
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.image.*?>
 <?import javafx.scene.text.*?>
 <?import java.lang.*?>
 <?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="491.0" prefWidth="386.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="todoapp.TypesController">
<children>
  <CheckBox fx:id="c1" layoutX="55.0" layoutY="125.0" mnemonicParsing="false" onAction="#clicked" text="ADD dcu" />
  <CheckBox fx:id="c2" layoutX="55.0" layoutY="177.0" mnemonicParsing="false" onAction="#clicked1" text="Display dcu" />
  <Label layoutX="31.0" layoutY="58.0" prefHeight="37.0" prefWidth="276.0" text="Choose any one of the options" textFill="#1b29cd">
     <font>
        <Font name="Arial Bold" size="18.0" />
     </font>
  </Label>
</children>

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!