如何在JavaFX中切换阶段

时间:2017-08-21 22:59:23

标签: javafx javafx-2 javafx-8

我有登录阶段(300 x 250),如果凭据正确,我想打开另一个主舞台(全屏)。

我已经弄清楚如何检查登录凭据,但是如何关闭登录阶段并打开另一个阶段?

1 个答案:

答案 0 :(得分:0)

如果我的应用程序应该在一个窗口中工作,我更喜欢使用GUI管理器单例类来管理更改窗口。下面我提供了使用这种机制的简单应用程序的完整代码。我们假设所有文件都在一个包中,称为sample

Main.java - 您在此处初始化JavaFX组件:

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 - 所有的窗口都应该基于它:

<?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 - 将显示的第一个实际窗口:

<?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 - 第一个窗口的控制器类:

package sample;

import javafx.fxml.FXML;

public class FirstWindowController {

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

secondwindow.fxml - 点击第一个窗口的按钮后显示:

<?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 - 第二个窗口的控制器类:

package sample;

import javafx.fxml.FXML;

public class SecondWindowController {

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

GuiManager.java - 一个根据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;
  }
}