JavaFX中具有一个阶段和多个场景的登录应用程序

JavaFX中具有一个阶段和多个场景的登录应用程序,java,javafx,fxml,stage,scenebuilder,Java,Javafx,Fxml,Stage,Scenebuilder,我正在做一个时间表项目。我已经成功地创建了一个登录系统和菜单,但当我按下按钮时,它会打开一个新窗口(带有舞台、场景)。我读到这不是最好的方法。最好的方法是只有一个初级阶段,那就是当我启动应用程序时,登录 但我已经寻找了关于一个阶段的多个场景的信息,但我没有找到任何好的解决方案。非常感谢您的帮助;)希望你能理解我想要实现的目标。值得一提的是,我正在处理Scenebuilder和fxml文件,所以我基本上只想将一个新的.fxml场景加载到主阶段 因此,我在另一个线程中进行了研究,并尝试创建一个Vis

我正在做一个时间表项目。我已经成功地创建了一个登录系统和菜单,但当我按下按钮时,它会打开一个新窗口(带有舞台、场景)。我读到这不是最好的方法。最好的方法是只有一个初级阶段,那就是当我启动应用程序时,登录

但我已经寻找了关于一个阶段的多个场景的信息,但我没有找到任何好的解决方案。非常感谢您的帮助;)希望你能理解我想要实现的目标。值得一提的是,我正在处理Scenebuilder和fxml文件,所以我基本上只想将一个新的.fxml场景加载到主阶段

因此,我在另一个线程中进行了研究,并尝试创建一个VistaFramework来处理所有场景更改。 但我不完全理解它,我无法让它发挥作用

package application;

import javafx.fxml.FXMLLoader;

import java.io.IOException;

import controllers.MainController;

/**
 * Utility class for controlling navigation between vistas.
 *
 * All methods on the navigator are static to facilitate
 * simple access from anywhere in the application.
 */
public class VistaNavigator {

    /**
     * Convenience constants for fxml layouts managed by the navigator.
     */
    public static final String MAIN    = "LoginGUI.fxml";
    public static final String NEW_USER = "NewUserGUI.fxml";
    public static final String STARTMENU = "StartMenuGUI.fxml";

    /** The main application layout controller. */
    private static MainController mainController;

    /**
     * Stores the main controller for later use in navigation tasks.
     *
     * @param mainController the main application layout controller.
     */
    public static void setMainController(MainController mainController) {
        VistaNavigator.mainController = mainController;
    }

    /**
     * Loads the vista specified by the fxml file into the
     * vistaHolder pane of the main application layout.
     *
     * Previously loaded vista for the same fxml file are not cached.
     * The fxml is loaded anew and a new vista node hierarchy generated
     * every time this method is invoked.
     * @param fxml the fxml file to be loaded.
     */

    public static void loadVista(String fxml) {
        try {
            mainController.setVista(
                FXMLLoader.load(
                    VistaNavigator.class.getResource(
                        fxml
                    )
                )
            );
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
我在loadVista()中遇到错误。在mainController.setvisa(“类型mainController中的方法setvisa(节点)不适用于参数(对象)”每个FXML文件不一定是新场景

fxml只是一个视图文件,其
根元素
与Javafx提供的任何元素相同。它可能有多个布局(作为根布局的一部分)和控件,具体取决于您的需求

要了解有关fxml的更多信息,您可以查看

FXML教程

现在,FXML准备就绪后,您可以用不同的方式加载它:

  • 加载为场景的根
  • 作为已加载布局的一部分加载
  • 加载为新场景的根,并将其指定给当前阶段
  • 为了帮助您理解以上几点,这里为每一点提供了一个示例。在这里,我演示了一个
    LoginController
    类,它是一个用于加载
    FXML
    的控制器

    示例-1

    FXMLLoader loader = new FXMLLoader(LoginController.class.getResource("root.fxml"));
    AnchorPane login = (AnchorPane) loader.load();
    Scene scene = new Scene(login); 
    
    示例-2

    FXMLLoader loader = new FXMLLoader(LoginController.class.getResource("root.fxml"));
    AnchorPane login = (AnchorPane) loader.load();
    BorderPane borderPane = (BorderPane)scene.getRoot();
    borderPane.setCenter(login);
    
    示例-3

    FXMLLoader loader = new FXMLLoader(LoginController.class.getResource("root.fxml"));
    AnchorPane login = (AnchorPane) loader.load();
    Scene scene = new Scene(login);
    stage.setScene(scene);//Stage loads the new scene, which has the layout of the fxml
    
    N.B.有关如何在不同控制器上访问舞台/场景的更多详细信息,请通过


    Hmm。但是在例3中,什么是stage?什么是login?我的stage在主类中。我如何从我的LoginController类访问它?
    login
    是我们从FXML加载的
    AnchorPane
    LoginController
    只是一个参考,你可以用
    主类替换LoginController
    classOkey。是的,我明白。但现在我在我的登录控制器中,当我按下“登录”按钮时。它应该会更改场景和fxml文件。我的意思是我现在在我的LoginController中,但a如何才能访问我的主要阶段?请帮助我完成这一步。我将非常感谢您的帮助。这是我正在尝试根据登录用户权限禁用和启用菜单项。您好,自从我是javafx新手以来,我一直有相同的问题。谢谢很多情况下,这个答案是一个很好的例子。除此之外,我想问一下,使用scenebuilder(.fxml)还是使用代码动态创建场景更好。什么对性能更好?每次按下相应的按钮时,加载场景比动态生成场景要快?谢谢!