0

I'm currently trying to create a basic money saver program for a school project using javafx/fxml so i'm still learning. I am currently trying to set up a way in which when the user closes the program, it runs some code to save the value currently displayed in a textField endGoal. The problem is the Textfield in controller keeps throwing a NullPointException. Is there anyway to un-null it or fix it? problem on line endGoal.setText("This is fake.");.

The Controller:

package sample;

import javafx.application.Platform;
import javafx.animation.*;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import java.io.*;
import java.io.FileReader;
import javafx.application.*;

import javax.annotation.PostConstruct;

public class MainPageController {
@FXML
private Button openPage1;

@FXML
private Button openPage2;

@FXML
private Button generateNewGoal;

@FXML
private Button resetGoal;

@FXML
private TextField moneySaved;

@FXML
private TextField currentGoal;

@FXML
public BorderPane BorderPane;

@FXML
public Stage myStage;



public void initialize() throws Exception{
    FileReader reader = new FileReader("Goal.txt");
    BufferedReader br = new BufferedReader(reader);
    String goal = br.readLine();
    currentGoal.setText(goal);
    reader.close();
}

@PostConstruct
public void start(Stage stage1)throws Exception{
    myStage = stage1;
    FXMLLoader loader = new FXMLLoader(getClass().getResource("MainPage.fxml"));
    Parent root = loader.load();
    loader.getController();
    loader.load();
    loader.getController();
    stage1.getScene().getWindow();
    myStage.setOnCloseRequest(e -> onEnd());

}

public void openPage1(ActionEvent event) throws Exception {
    FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("MandatoryCostCollector.fxml"));
    Parent root = (Parent) fxmlLoader.load();
    Stage stage = new Stage();
    stage.setScene(new Scene(root));
    stage.setTitle("Money Saver Program");
    stage.show();
    ((Node) event.getSource()).getScene().getWindow().hide();
}

public void openPage2(ActionEvent event) throws Exception {
    FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("PayDataCollector.fxml"));
    Parent root = (Parent) fxmlLoader.load();
    Stage stage = new Stage();
    stage.setScene(new Scene(root));
    stage.setTitle("Money Saver Program");
    stage.show();
    ((Node) event.getSource()).getScene().getWindow().hide();
}

public void resetGoal(ActionEvent event) throws Exception {
    currentGoal.setText("");
}}

    public void saveData()throws Exception{
    endGoal.setText("This is fake.");
    FileWriter writer = new FileWriter("Goal.txt");
    String goal = (endGoal.getText());
    writer.write(goal);
    writer.close();
}

The Main:

 package sample;

import com.sun.org.apache.xpath.internal.Arg;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import jdk.nashorn.internal.runtime.regexp.joni.constants.Arguments;

 import javax.xml.soap.Text;
 import java.io.*;
 import java.util.*;

 public class Main extends Application  {

@FXML
public TextField currentGoal;

File f = new File("Goal.txt");

public String finalGoal;


@Override
public void start(Stage primaryStage)throws Exception  {
    boolean bool = false;
    if (f.exists() )
    {
        Parent root = FXMLLoader.load(getClass().getResource("MainPage.fxml"));
        primaryStage.setTitle("Money Saver Program");
        primaryStage.setScene(new Scene(root, 600, 400));
        primaryStage.show();
    }
    else
    {
        bool = f.createNewFile();
        Parent root = FXMLLoader.load(getClass().getResource("OpeningPage.fxml"));
        primaryStage.setTitle("Money Saver Program");
        primaryStage.setScene(new Scene(root, 638, 400));
        primaryStage.show();
    }

    primaryStage.setOnCloseRequest(e -> closeProgram());

}

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

public void closeProgram(){

    Platform.exit();
}

public void stop()throws Exception{
    mainPageController.saveData();
    System.out.print("Goal has been saved!");

}
}
}

The FXML:

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

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

      <BorderPane fx:id="BorderPane" maxHeight="-Infinity" maxWidth="-      Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0"           prefWidth="600.0" xmlns="http://javafx.com/javafx/8"           xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.MainPageController">
    <top>
         <VBox prefHeight="65.0" prefWidth="600.0"            BorderPane.alignment="CENTER">
           <children>
               <TextField alignment="CENTER" editable="false"         prefHeight="68.0" prefWidth="600.0" text="Welcome to the Money Saving Program">
                 <font>
                     <Font name="Arial Rounded MT Bold" size="26.0" />
                 </font>
             </TextField>
            </children>
         </VBox>
      </top>
     <left>
          <VBox prefHeight="335.0" prefWidth="159.0"       BorderPane.alignment="CENTER">
           <children>
              <Button fx:id="openPage1" mnemonicParsing="false"       onAction="#openPage1" prefHeight="88.0" prefWidth="167.0" text="1. Open      Mandatory Cost Collector" wrapText="true">
                 <font>
                     <Font name="Arial" size="18.0" />
                  </font>
              </Button>
               <Button fx:id="openPage2" mnemonicParsing="false" onAction="#openPage2" prefHeight="60.0" prefWidth="173.0" text="2. Open Pay Data Collector" wrapText="true">
                 <font>
                    <Font name="Arial" size="18.0" />
                </font>
             </Button>
         </children>
       </VBox>
     </left>
    <right>
         <VBox prefHeight="335.0" prefWidth="166.0" BorderPane.alignment="CENTER">
           <children>
               <TextField fx:id="endGoal" promptText="\$">
                <font>
                       <Font name="Arial" size="40.0" />
                    </font>
               </TextField>
                <Button fx:id="resetGoal" contentDisplay="RIGHT" mnemonicParsing="false" onAction="#resetGoal" prefHeight="33.0" prefWidth="173.0" text="Reset Goal" wrapText="true">
                   <font>
                      <Font name="Arial" size="18.0" />
                   </font>
               </Button>
           </children>
        </VBox>
    </right>
     <bottom>
       <HBox prefHeight="100.0" prefWidth="200.0" BorderPane.alignment="CENTER">
           <children>
        <Button fx:id="generateNewGoal" mnemonicParsing="false" prefHeight="63.0" prefWidth="161.0" text="3. Generate your new goal" translateY="36.0" wrapText="true">
               <font>
                   <Font name="Arial" size="18.0" />
                </font>
             </Button>
           <TextField alignment="CENTER" editable="false" prefHeight="75.0" prefWidth="221.0" text="Money saved this week" translateX="38.0" translateY="23.0">
                 <font>
                   <Font name="Arial" size="18.0" />
                 </font>
              </TextField>
              <TextField fx:id="moneySaved" editable="false" prefHeight="75.0" prefWidth="180.0" promptText="\$" translateX="38.0" translateY="23.0">
                  <font>
                     <Font name="Arial" size="40.0" />
                  </font>
                 </TextField>
           </children>
        </HBox>
       </bottom>
       <center>
       <VBox prefHeight="200.0" prefWidth="100.0" BorderPane.alignment="CENTER">
          <children>
             <TextField editable="false" maxHeight="-Infinity" maxWidth="-Infinity" prefHeight="68.0" prefWidth="167.0" text="Your current goal" translateX="108.0">
                   <font>
                     <Font name="Arial" size="18.0" />
                 </font>
                </TextField>
             </children>
         </VBox>
       </center>
   </BorderPane>

The Error:

Exception in Application stop method
Exception in thread "main" java.lang.RuntimeException: Exception in    Application stop method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:922)
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 sample.MainPageController.saveData(MainPageController.java:99)
at sample.Main.stop(Main.java:73)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$163(LauncherImpl.java:882)
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)
Dylan52
  • 61
  • 2
  • 10
  • 1
    Possible duplicate of [What is a NullPointerException, and how do I fix it?](http://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – fabian Jul 09 '16 at 07:03
  • I have read that page and tried to fix it however I just end up with a smaller NullPointException Error I have traced the problem to the `finalGoal = (currentGoal.getText());` in the `stop()` method. I'm thinking it might be due to currentGoal however I'm not exactly sure of the problem or how to fix it. I updated the post to show the new code and error. @fabian – Dylan52 Jul 09 '16 at 07:34
  • This issue has come up often; Maybe the dupe I linked isn't the best one, but currently i cannot find a good one. It should be the same issue I explained here however (even though it's hard to see from the question): http://stackoverflow.com/a/38101399/2991525 i.e. your `Application` instance is not the controller instance the `currentGoal` field is injected to... – fabian Jul 09 '16 at 08:26

1 Answers1

0

Try replacing

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

by

FXMLLoader loader = new FXMLLoader(getClass().getResource("MainPage.fxml"));
loader.setController(this);
Parent root = loader.load();

The reason you have to do this is that the FXMLLoader will create a new instance of the controller class specified in the fxml file because it can not know if such an object already exists. However, you can specify an object via the setController() method, which will than be populated with your fxml GUI elements.

0xJonas
  • 289
  • 1
  • 7