2017-08-21 129 views
0

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

我已经想通了如何检查登录凭证,但是如何关闭登录阶段并打开另一个阶段?

+0

'stage.hide()'将关闭一个阶段。创建一个新的舞台并调用show()来显示它。 –

+0

https://github.com/sedj601/SimpleLoginFx – Sedrick

回答

0

如果我的应用程序应该在一个窗口中工作,我更喜欢使用GUI管理器singleton类,它管理更改窗口。下面我提供了使用这种机制的简单应用程序的完整代码。假设所有文件都在一个包中,称为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 - 根据根管理更改窗口的类:

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

我只是在同一个问题上运行,并且this answer完美解决了我的问题,同时又短又干净。

@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 .:记住要点击原来的答案,并给予好评的。这家伙值得...

PPS .:我不知道只是复制一个答案是好的(而不是通过评论分享链接),但由于这没有一个正确的答案,但我决定做它的可见性。