JavaFx 不会改变场景

JavaFx won't schange Scenes

package Data_Project;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.io.IOException;

public class Main extends Application {
    public Stage window;
    @Override
    public void start(Stage primaryStage) throws Exception{
        window = primaryStage;
        //Scene1
        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        Parent root1 = FXMLLoader.load(getClass().getResource("Admin.fxml"));
        Controller a1 = new Controller();
        a1.getSubmitButton().setOnAction(e -> {
            window.setScene(new Scene(root1,500,500));
        });
        window.setTitle("Log in");
        window.setScene(new Scene(root,500,500));
        window.show();
    }


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

    }
}

嘿,我在使用这段代码时遇到错误,我不知道出了什么问题。

Exception in Application start method Exception in thread "main" java.lang.RuntimeException: Exception in Application start method at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:875) at com.sun.javafx.application.LauncherImpl.lambda$launchApplication7(LauncherImpl.java:157) at com.sun.javafx.application.LauncherImpl$$Lambda/989110044.run(Unknown Source) at java.lang.Thread.run(Thread.java:745) Caused by: java.lang.NullPointerException at Data_Project.Main.start(Main.java:20)

XML:

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

<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<GridPane alignment="center" hgap="10" vgap="10" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Data_Project.Controller">
   <children>

          <Label text="Username" GridPane.columnIndex="1" GridPane.rowIndex="1" />
          <TextField fx:id="userField" GridPane.columnIndex="2" GridPane.rowIndex="1" />
          <Label text="Password" GridPane.columnIndex="1" GridPane.rowIndex="3" />
          <PasswordField fx:id="passField" GridPane.columnIndex="2" GridPane.columnSpan="1" GridPane.rowIndex="3" />
          <Button fx:id="submitButton" onAction="#submitForm" text="Log in" GridPane.columnIndex="2" GridPane.columnSpan="2" GridPane.rowIndex="4" />
          <Label fx:id="errorLabel" textFill="#c30808" GridPane.columnIndex="2" GridPane.columnSpan="2" GridPane.rowIndex="6" />
   </children>

</GridPane>






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

<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<GridPane alignment="center" hgap="10" vgap="10" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Data_Project.Admin">
    <children>

        <Label text="Username" GridPane.columnIndex="1" GridPane.rowIndex="1" />
        <TextField fx:id="userField" GridPane.columnIndex="2" GridPane.rowIndex="1" />
        <Label text="Password" GridPane.columnIndex="1" GridPane.rowIndex="3" />
        <PasswordField fx:id="passField" GridPane.columnIndex="2" GridPane.columnSpan="1" GridPane.rowIndex="3" />
        <Button fx:id="submitButton" text="Log in" GridPane.columnIndex="2" GridPane.columnSpan="2" GridPane.rowIndex="4" />
        <Label fx:id="errorLabel" textFill="#c30808" GridPane.columnIndex="2" GridPane.columnSpan="2" GridPane.rowIndex="6" />
    </children>

</GridPane>

XML 都是不同的文件,但这里显示为 1 个文件,它们具有相同的属性,都是因为它用于测试场景切换器,但由于某种原因我无法获取它工作!

控制器class:

package Data_Project;


import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Scene;
import javafx.scene.control.*;


public class Controller{
    Scene window;
    @FXML Button submitButton;
    @FXML TextField userField;
    @FXML PasswordField passField;
    @FXML Label errorLabel;

    public void submitForm(ActionEvent actionEvent) {
       authorizedUser user = new authorizedUser();
        if(!user.checkCredentials(userField.getText(), passField.getText()))
        {
            errorLabel.setText("Invalid credentials");
        }
    }


    public Button getSubmitButton() {
        return submitButton;
    }
}

管理员:

package Data_Project;


import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Scene;
import javafx.scene.control.*;


public class Admin{
    Scene window;
    @FXML Button submitButton;
    @FXML TextField userField;
    @FXML PasswordField passField;
    @FXML Label errorLabel;

    public Button getSubmitButton() {
        return submitButton;
    }
}

FXMLLoader 解析 FXML 文件,创建控制器实例 class(如果指定)并将任何 @FXML 注释字段注入该控制器实例。

如果您像使用

一样创建自己的控制器实例
Controller a1 = new Controller();

然后 FXMLLoader 对那个实例一无所知(怎么会呢?)所以 @FXML-注释字段没有被初始化。因此当你打电话给

a1.getSubmitButton()

它 returns null 所以你得到一个 NullPointerException.

要解决此问题,请替换

Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));

Controller a1 = new Controller();

FXMLLoader loader = new FXMLLoader(getClass().getResource("sample.fxml"));
Parent root = loader.load();
Controller a1 = loader.getController();

这为您提供了对 FXMLLoader 创建的 控制器实例 的引用,因此它的 @FXML 注释字段已正确初始化。