NullPointer Exception on setText() while everythin

2020-04-11 08:53发布

问题:

I'm receiving the following exception trying to call setText() on my annotated label, from the start() method. I've seen a similar question, but the reason why it didn't work for that person is because his label isn't annotated, while mine is.

java.lang.NullPointerException
at io.github.blubdalegend.openbravery.OpenBravery.applyBuild(OpenBravery.java:67)
at io.github.blubdalegend.openbravery.OpenBravery.start(OpenBravery.java:58)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(Unknown Source)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(Unknown Source)
at java.lang.Thread.run(Unknown Source)

This is my main class:

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());
    }

}

My build.fxml starts like this:

   <?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>

So what did I miss here?

回答1:

You're not calling applyBuild() on the controller, you're calling it on the application instance. The @FXML-annotated fields are only initialized in the controller. It's much better to make the controller and the application separate classes, to avoid this kind of confusion. It is also bad practice to create two instances of the Application class.

Write a separate class as the controller: do not use the Application subclass as the controller class.



标签: java javafx fxml