1

my program creates files for a game that I can making, it has a method called Update, which runs on program startup, reading all files in the folder "mob", it runs fine when there are no file, however, if create a file in the mobs folder, with stuff in it, when the program runs it throws a NullPointerException despite the context in the file isn't null.

By the way It's a JavaFX FXML program

FXMLDocumentController

package fightwriter;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.Scanner;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;

public class FXMLDocumentController implements Initializable {

    String content;

    @FXML // fx:id="TFname"
    private TextField TFname; // Value injected by FXMLLoader

    @FXML // fx:id="TFhp"
    private TextField TFhp; // Value injected by FXMLLoader

    @FXML // fx:id="TFattMin"
    private TextField TFattMin; // Value injected by FXMLLoader

    @FXML // fx:id="TFattH"
    private TextField TFattH; // Value injected by FXMLLoader

    @FXML // fx:id="TFdex"
    private TextField TFdex; // Value injected by FXMLLoader

    @FXML // fx:id="TFpots"
    private TextField TFpots; // Value injected by FXMLLoader

    @FXML // fx:id="TFspAtt1Name"
    private TextField TFspAtt1Name; // Value injected by FXMLLoader

    @FXML // fx:id="TFspAtt1M"
    private TextField TFspAtt1M; // Value injected by FXMLLoader

    @FXML // fx:id="TFspAtt1H"
    private TextField TFspAtt1H; // Value injected by FXMLLoader

    @FXML // fx:id="TFspAtt2Name"
    private TextField TFspAtt2Name; // Value injected by FXMLLoader

    @FXML // fx:id="TFspAtt2M"
    private TextField TFspAtt2M; // Value injected by FXMLLoader

    @FXML // fx:id="TFspAtt2H"
    private TextField TFspAtt2H; // Value injected by FXMLLoader

    @FXML // fx:id="create"
    private Button create; // Value injected by FXMLLoader

    @FXML // fx:id="ErrorMsgs"
    private TextArea ErrorMsgs; // Value injected by FXMLLoader

    @FXML // fx:id="list"
    private TextArea list; // Value injected by FXMLLoader

    @FXML // fx:id="save"
    private Button save; // Value injected by FXMLLoader

    @FXML
    void createOnAction(ActionEvent event) {
        ErrorMsgs.setText("");
        try {
            File mobs = new File(System.getProperty("user.dir") + "\\mobs");
            mobs.mkdir();
            FileWriter fw = new FileWriter(new File(System.getProperty("user.dir") + "\\mobs\\" + TFname.getText() + ".mob"));
            try (BufferedWriter bw = new BufferedWriter(fw)) {
                bw.write("name=" + TFname.getText() + "\r\nhp=" + TFhp.getText() + "\r\nattM=" + TFattMin.getText() + "\r\n"
                        + "attH=" + TFattH.getText() + "\r\ndex=" + TFdex.getText() + "\r\npots=" + TFpots.getText() + "\r\n"
                        + "spAtt1Name=" + TFspAtt1Name.getText() + "\r\nspAtt1M=" + TFspAtt1M.getText() + "\r\nspAtt1H=" + TFspAtt1H.getText() + "\r\n"
                        + "spAtt2Name=" + TFspAtt2Name.getText() + "\r\nspAtt2M=" + TFspAtt2M.getText() + "\r\nspAtt2H=" + TFspAtt2H.getText());
            }
        } catch (IOException ex) {
            ErrorMsgs.appendText(ex.getMessage());
        }
        Update();
    }

    @FXML
    void saveOnAction(ActionEvent event) {
        ErrorMsgs.setText("");
        Update();
    }

    public void Update() {
        File mobs = new File(System.getProperty("user.dir") + "\\mobs");
        File[] lists = mobs.listFiles();
        if (lists != null) {
            for (File f : lists) {
                try {
                    content = new Scanner(f).useDelimiter("\\Z").next();
                    if (content != null) {
                        ***list.appendText(content + "\n\n\n\n\n\n");***
                    }
                } catch (FileNotFoundException ex) {
                    ErrorMsgs.appendText(ex.getMessage());
                }
            }
        }
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {

    }

}

FXMLDocument

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Separator?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane id="AnchorPane" prefHeight="759.0" prefWidth="1104.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fightwriter.FXMLDocumentController">
    <children>
        <TextField fx:id="TFname" layoutX="41.0" layoutY="35.0" promptText="Name" />
        <TextField fx:id="TFhp" layoutX="41.0" layoutY="89.0" promptText="Health" />
        <TextField fx:id="TFattMin" layoutX="41.0" layoutY="145.0" promptText="Minimum Attack" />
        <TextField fx:id="TFattH" layoutX="41.0" layoutY="204.0" promptText="Maximun Attack" />
        <TextField fx:id="TFdex" layoutX="41.0" layoutY="260.0" promptText="Dexterity" />
        <TextField fx:id="TFpots" layoutX="41.0" layoutY="318.0" promptText="# of Health Potions" />
        <TextField fx:id="TFspAtt1Name" layoutX="41.0" layoutY="373.0" promptText="Special Attack 1 Name" />
        <TextField fx:id="TFspAtt1M" layoutX="41.0" layoutY="428.0" promptText="Special Attack 1 min dmg" />
        <TextField fx:id="TFspAtt1H" layoutX="41.0" layoutY="486.0" promptText="Special Attack 1 max dmg" />
        <TextField fx:id="TFspAtt2Name" layoutX="41.0" layoutY="543.0" promptText="Special Attack 2 Name" />
        <TextField fx:id="TFspAtt2M" layoutX="41.0" layoutY="600.0" promptText="Special Attack 2 min dmg" />
        <TextField fx:id="TFspAtt2H" layoutX="41.0" layoutY="658.0" prefHeight="31.0" prefWidth="187.0" promptText="Special Attack 2 max dmg" />
        <Separator layoutX="604.0" orientation="VERTICAL" prefHeight="760.0" prefWidth="0.0" />
        <Button fx:id="create" layoutX="42.0" layoutY="702.0" mnemonicParsing="false" onAction="#createOnAction" prefHeight="31.0" prefWidth="77.0" text="Create" />
        <TextArea fx:id="ErrorMsgs" editable="false" layoutX="240.0" layoutY="35.0" prefHeight="698.0" prefWidth="351.0" promptText="ErrorMsgs" />
        <TextArea fx:id="list" editable="false" layoutX="629.0" layoutY="21.0" prefHeight="711.0" prefWidth="448.0" />
        <Button fx:id="save" layoutX="135.0" layoutY="702.0" mnemonicParsing="false" onAction="#saveOnAction" text="Update List" />
    </children>
</AnchorPane>

FightWriter (Main class)

package fightwriter;

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

public class FightWriter extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));

        Scene scene = new Scene(root);

        stage.setScene(scene);
        stage.show();

        FXMLDocumentController L = new FXMLDocumentController();
        ***L.Update();***
    }

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

}

Error

Executing C:\Users\21114693\Documents\NetBeansProjects\FightWriter\dist\run803916352\FightWriter.jar using platform C:\Program Files\Java\jdk1.8.0_102\jre/bin/java
Exception in Application start method
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
    at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$155(LauncherImpl.java:182)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
    at fightwriter.FXMLDocumentController.Update(FXMLDocumentController.java:103)
    at fightwriter.FightWriter.start(FightWriter.java:21)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
    ... 1 more
Exception running application fightwriter.FightWriter
Java Result: 1
Deleting directory C:\Users\21114693\Documents\NetBeansProjects\FightWriter\dist\run803916352
Mine Rockers
  • 213
  • 3
  • 12
  • 1
    We need to know the line where the error occurs and the full stacktrace too. – BackSlash Jan 26 '17 at 10:37
  • Ohhh yes thank you I forgot thank you so much – Mine Rockers Jan 26 '17 at 10:38
  • Why does everybody ask such questions before reading something like "[How to use a debugger](http://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems)"? – Axel Jan 26 '17 at 10:39
  • are you expected we read all these lines and searching for errors ? :) where is the error ? – Mohsen_Fatemi Jan 26 '17 at 10:39
  • @Axel it just might not be as simple as you think. – Mine Rockers Jan 26 '17 at 10:40
  • 1
    What? Place a breakpoint on uncaught NPE and starting your program is not simple? – Axel Jan 26 '17 at 10:41
  • @Axel phew gave me a heart attack, placing a break point doesn't cause the error to dissipate – Mine Rockers Jan 26 '17 at 10:43
  • 1
    @MineRockers Of course, this is not what breakpoints do. They just telòl the debugger to pause the execution of a program at a pre-defined line so that you can investigate and see what are the values of the variable you use. In your case you can use it to find what is causing your `NullPointerException` – BackSlash Jan 26 '17 at 10:44
  • @BackSlash I did what you say and the context isn't null – Mine Rockers Jan 26 '17 at 10:47
  • Which is line 103 of `FXMLDocumentController.java`? Which is line 21 of `FightWriter.java`? Highlight them. – BackSlash Jan 26 '17 at 10:50
  • @MineRockers I just noticed you highlighted a line with three asterisks: `list.appendText(content + "\n\n\n\n\n\n");` You check that `content` is not `null`, but what about `list`? Likely it's `null` if it throws a NPE. – BackSlash Jan 26 '17 at 11:02
  • Fields annotated `@FXML` are initialized in the controller by the `FXMLLoader` when the FXML file is loaded. They don't get magically initialized in all instances of the same class. You are not calling `Update()` on the controller, you are just calling it on some arbitrary instance of `FXMLDocumentController` that you created. – James_D Jan 26 '17 at 12:10

1 Answers1

0

If you look at the stacktrace, you see that the only variable that might be null is list:

if (content != null) {
    list.appendText(content + "\n\n\n\n\n\n"); // <-- line from stacktrace
}

This might seem confusing, because you did this before:

if (lists != null) {

But that's another variable (note the 's'). The below comment next to the declaration of list is obviously not true:

@FXML // fx:id="list"
private TextArea list; // Value injected by FXMLLoader

I don't have too much experience with JavaFX, but I think your code is called before FXMLLoader has done it's job.

Axel
  • 13,939
  • 5
  • 50
  • 79
  • The FXMLLoader is what's generated my methods, by using JavaFx Scene Builder. The variable list is the TextArea, lists is the list of files in the folder "Mob" list is a text area, not a String – Mine Rockers Jan 26 '17 at 11:46
  • Who said it was a String? String does not have a method called `appendString()`. What's clear is that `list` is not (yet) initialised when the code is executed. Change `if (content != null) {` to `if (content != null && list != null) {` and see what the effect is (if it stillcrashes, it will be at another location). – Axel Jan 26 '17 at 12:45
  • The error is gone, but the data from the files aren't being displayed in the Text Area – Mine Rockers Jan 26 '17 at 12:54
  • also a weird thing, when I click on update list which calls the update method, only 1 file is read and displayed, I have 3 – Mine Rockers Jan 26 '17 at 12:56
  • @MineRockers See my comment in the OP. You are not calling `Update` on the controller, so it will not affect anything in the UI. – James_D Jan 26 '17 at 12:56
  • @James_D how would I call Update then? – Mine Rockers Jan 26 '17 at 13:04
  • Call it on the controller. You get the controller from the `FXMLLoader` *instance* using `getController()`. See for example http://stackoverflow.com/questions/14187963/passing-parameters-javafx-fxml – James_D Jan 26 '17 at 13:10
  • @James_D I don't really get the example, could you provide one for me please? I would really appreciate it! – Mine Rockers Jan 26 '17 at 13:19
  • The accepted answer to the question I linked above has well over 100 upvotes at the time of writing. I think it's highly unlikely I can improve on that. It shows two different ways to get a reference to the controller and call methods on it. – James_D Jan 26 '17 at 13:28
  • @James_D I don't think I'm getting it, I already have a FXMLLoader in my main class. – Mine Rockers Jan 26 '17 at 13:33
  • @MineRockers Again, just do it the same way as in that example. As is strongly emphasized there, don't use the static `load(URL)` method, create a `FXMLLoader` instance instead and call methods on it. – James_D Jan 26 '17 at 13:36
  • @James_D I'm very new to programming, by the way, I did this FXMLLoader FXML = new FXMLLoader(getClass().getResource("FXMLDocument.fxml")); what do I do next? FXML.Update();? – Mine Rockers Jan 26 '17 at 13:39
  • @James_D if I do FXML.load(L.Update()); It says void type not allowed here – Mine Rockers Jan 26 '17 at 13:52
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/134082/discussion-between-mine-rockers-and-james-d). – Mine Rockers Jan 26 '17 at 13:52