Java 正确加载和注释所有内容时,setText()上出现NullPointer异常

Java 正确加载和注释所有内容时,setText()上出现NullPointer异常,java,javafx,fxml,Java,Javafx,Fxml,我在尝试从start()方法调用带注释标签上的setText()时收到以下异常。我见过一个类似的问题,但它对那个人不起作用的原因是他的标签没有注释,而我的标签是 java.lang.NullPointerException 位于io.github.blubdalegend.openbravery.openbravery.applyBuild(openbravery.java:67) 位于io.github.blubdalegend.openbravery.openbravery.start(op

我在尝试从
start()
方法调用带注释标签上的
setText()
时收到以下异常。我见过一个类似的问题,但它对那个人不起作用的原因是他的标签没有注释,而我的标签是

java.lang.NullPointerException
位于io.github.blubdalegend.openbravery.openbravery.applyBuild(openbravery.java:67)
位于io.github.blubdalegend.openbravery.openbravery.start(openbravery.java:58)
位于com.sun.javafx.application.launchempl.lambda$launchApplication1$162(未知来源)
com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(未知来源)
位于com.sun.javafx.application.PlatformImpl.lambda$null$173(未知来源)
位于java.security.AccessController.doPrivileged(本机方法)
com.sun.javafx.application.PlatformImpl.lambda$runLater$174(未知来源)
在com.sun.glass.ui.InvokeLaterDispatcher$Future.run(未知源)
在com.sun.glass.ui.win.WinApplication.\u runLoop(本机方法)
在com.sun.glass.ui.win.WinApplication.lambda$null$148(未知来源)
位于java.lang.Thread.run(未知源)
这是我的主要课程:

public class OpenBravery extends Application implements Initializable {

    @FXML
    private Button rerollButton;

    @FXML
    private Label champL;

    public static void main(String[] args) {
        System.out.println("Downloading files from Dropbox...");
        updateFiles();
        System.out.println("Download complete!");
        Application.launch(OpenBravery.class, (java.lang.String[]) null);

    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        rerollButton.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {

            }
        });
    }

    private static void updateFiles() {
        FileManager fm = new FileManager();
        fm.downloadChamps();
        fm.downloadItems();
    }

    @Override
    public void start(Stage stage) {
        try {
            Pane pane = (Pane) FXMLLoader.load(OpenBravery.class.getResource("build.fxml"));
            Scene scene = new Scene(pane);
            stage.setScene(scene);
            stage.setTitle("OpenBravery");
            stage.setResizable(false);
            applyBuild();
            stage.show();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void applyBuild() {
        Build build = new Build();
        champL.setText(build.getChamp());
    }

}
公共类OpenBravery扩展应用程序实现可初始化{
@FXML
私有按钮重新滚动按钮;
@FXML
自有品牌champL;
公共静态void main(字符串[]args){
System.out.println(“从Dropbox下载文件…”);
updateFiles();
System.out.println(“下载完成!”);
launch(OpenBravery.class,(java.lang.String[])null;
}
@凌驾
公共void初始化(URL位置、ResourceBundle资源){
rerollButton.setOnAction(新的EventHandler如下启动:

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

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


<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity"
    minWidth="-Infinity" prefHeight="297.0" prefWidth="362.0"
    xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
    fx:controller="io.github.blubdalegend.openbravery.OpenBravery">
    <children>
        <Label layoutX="14.0" layoutY="14.0" text="Your build:">
            <font>
                <Font size="32.0" />
            </font>
        </Label>
        <Label fx:id="champL" layoutX="14.0" layoutY="61.0" prefHeight="32.0"
            prefWidth="288.0" text="Label">
            <font>
                <Font size="17.0" />
            </font>
        </Label>


那么,我错过了什么呢?

您没有调用applyBuild()在控制器上,您在应用程序实例上调用它。
@FXML
-注释字段仅在控制器中初始化。最好将控制器和应用程序分开,以避免这种混淆。创建
应用程序
类的两个实例也是不好的做法


编写一个单独的类作为控制器:不要使用
应用程序
子类作为控制器类。

champL
可能仍然为空?可能与初始化顺序有关。我怀疑它找不到build.fxml,因为当我在没有setText()行的情况下运行时,它只会创建窗口(虽然显然没有设置标签的文本)。不确定初始化顺序。奇怪的是,
initialize()
不会在
applyBuild()
之前运行吗?如果是,那么,
rerollButton
到那时显然不是空的。@DanGetz是的,但是
initialize()
是在控制器上调用的,而不是在
应用程序的
实例上调用的。哦,哇,这样就有了这个类的两个实例?第二个实例是在哪里创建的?第二个实例是由
fxmloader
创建的,因为FXML文件将这个类指定为控制器类。可以访问第二个控制器对象吗?例如将对象传递给Controller@MichaelKrejci是的,当然可以:请看,但我强调每个FXML文件都应该有一个专用的
控制器
类,并且不应该使用
应用程序
类。是的,我在一个类中实现了它,但我最终创建了一个单独的控制器类。这样做更干净,可读性更强。