0

I have a login stage (300 x 250), I want to open another main stage (fullscreen) if the credentials are correct.

I have figured out how to check the login credentials, but how can I close the login stage and open another stage?

harsh.gupta
  • 45
  • 2
  • 10

2 Answers2

0

If my application is supposed to work in one window I prefer using a GUI manager singleton class, which manages changing windows. Below I provided the complete code of a simple application which uses this mechanism. Let's assume all the files are in one package, called sample.

Main.java - you initialize the JavaFX components here:

package sample;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import java.io.IOException;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
      FXMLLoader loader = new FXMLLoader();
      loader.setLocation(Main.class.getResource("/sample/root.fxml"));
      try{
        StackPane rootPane;
        rootPane = loader.load();
        GuiManager guiModel = GuiManager.getInstance();
        guiModel.setRootPane(rootPane);
        Scene scene = new Scene(rootPane);
        primaryStage.setScene(scene);
        primaryStage.show();
        guiModel.changeWindow("/sample/firstwindow.fxml");
      } catch (IOException exception) {
        exception.printStackTrace();
      }


    }

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

}

root.fxml - all the windows are supposed to be based on it:

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

<?import javafx.scene.layout.StackPane?>

<StackPane fx:id="rootPane"
           xmlns="http://javafx.com/javafx/8.0.60"
           xmlns:fx="http://javafx.com/fxml/1"
           prefWidth="1" prefHeight="1"/>

firstwindow.fxml - first actual window which will be displayed:

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.VBox?>

<VBox xmlns:fx="http://javafx.com/fxml" fx:controller="sample.FirstWindowController">
    <Label text="First window"/>
    <Button text="Change window" onAction="#changeWindow"/>
</VBox>

FirstWindowController.java - a controller class of the first window:

package sample;

import javafx.fxml.FXML;

public class FirstWindowController {

  @FXML
  private void changeWindow() {
    GuiManager.getInstance().changeWindow("/sample/secondwindow.fxml");
  }
}

secondwindow.fxml - it will be displayed after clicking the button of the first window:

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.VBox?>

<VBox xmlns:fx="http://javafx.com/fxml" fx:controller="sample.SecondWindowController" >
    <Label text="Second window"/>
    <Button text="Change window" onAction="#changeWindow"/>
</VBox>

SecondWindowController.java - a controller class of the second window:

package sample;

import javafx.fxml.FXML;

public class SecondWindowController {

  @FXML
  private void changeWindow() {
    GuiManager.getInstance().changeWindow("/sample/firstwindow.fxml");
  }
}

GuiManager.java - a class that manages changing windows based on the root:

package sample;

import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.stage.Window;
import java.io.IOException;

public class GuiManager {

  private StackPane rootPane;
  private static GuiManager instance;

  public static GuiManager getInstance() {
    if (instance == null) {
      instance = new GuiManager();
    }
    return instance;
  }

  private GuiManager() {}

  public void changeWindow(String path) {
    changeWindow(rootPane, path, this);
    rootPane.setPrefWidth(-1);
    rootPane.setPrefHeight(-1);
  }

  public static void changeWindow(Pane pane, String newWindowPath, Object callingController) {
    Window window = pane.getScene().getWindow();
    double x = window.getX() + getHorizontalMidpoint(window);
    double y = window.getY() + getVerticalMidpoint(window);

    ObservableList<Node> childrenList = pane.getChildren();
    removeAllIncludedChildren(childrenList);

    FXMLLoader loader = new FXMLLoader(callingController.getClass().getResource(newWindowPath));

    try {
      pane.getChildren().add(loader.load());
      Stage primaryStage = (Stage) window;
      primaryStage.setMinHeight(0);
      primaryStage.setMinWidth(0);
      window.sizeToScene();
      window.setX(x - getHorizontalMidpoint(window));
      window.setY(y - getVerticalMidpoint(window));
      primaryStage.setMinHeight(window.getHeight());
      primaryStage.setMinWidth(window.getWidth());
    } catch (IOException exception) {
      exception.printStackTrace();
    }
  }

  private static double getHorizontalMidpoint(Window window) {
    int horizontalBisectionCoefficient = 2;
    return window.getWidth() / horizontalBisectionCoefficient;
  }

  private static double getVerticalMidpoint(Window window) {
    int verticalBisectionCoefficient = 2;
    return window.getHeight() / verticalBisectionCoefficient;
  }

  private static void removeAllIncludedChildren(ObservableList<Node> childrenList) {
    for (int childIndex = 0; childIndex < childrenList.size(); childIndex++) {
      childrenList.remove(childIndex);
    }
  }

  public void setRootPane(StackPane rootPane) {
    this.rootPane = rootPane;
  }
}
0

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 click the original answer and upvote it. The guy deserves...

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

BarriaKarl
  • 79
  • 7