Why am I having the NullPointerException error?

Hi guys. I can’t understand why I am getting this NullPointerException
error, and the line “text(FileName, width/2, 146);” is highlighted.
Thanks for your help once again.

João

import controlP5.*;
ControlP5 cp5;
DropdownList d1;
DropdownList d2;
PFont font, font1, font2, font3;
import processing.serial.*; //import the Serial library
Serial myPort;
PrintWriter output;

String EepromData[];
String FileName;
String[] NamePath;
String GetFilePath;

byte LoadFileCheck = 0;
int OnlyName;

void setup() {
  clear();
  size(250, 250); // Create Window
  cp5 = new ControlP5(this);
  font = createFont("Arial Bold", 18);
  font1 = createFont("Arial Bold", 10);
  font2 = createFont("Arial Bold", 13);
  font3 = createFont("Arial Bold", 12);
  
  // Add Button
  cp5.addButton("Open") // "Start" is the name of the Button
    .setPosition(140, 165) // x and y coordinates of upper left corner of Button
    .setSize(80, 20)     // (Width, Height)
    .setFont(font1)
    .setColorBackground(color(216, 216, 216))
    .setColorForeground(color(232, 232, 232))
    .setColorActive(color(186, 188, 188))
    .setColorLabel(color(0, 0, 0))
    ;
    
     cp5.addButton("Save") // "Start" is the name of the Button
    .setPosition(30, 165) // x and y coordinates of upper left corner of Button
    .setSize(80, 20)     // (Width, Height)
    .setFont(font1)
    .setColorBackground(color(216, 216, 216))
    .setColorForeground(color(232, 232, 232))
    .setColorActive(color(186, 188, 188))
    .setColorLabel(color(0, 0, 0))
    ;
  
}

void draw() {
  background(0, 120, 255); // Background Color (r, g, b) or (0 to 255)
  textFont(font);
  
  pushStyle();
  if (LoadFileCheck != 1){
    textFont(font3);
    textAlign(CENTER);
   text("No File Selected", width/2, 146);
  }
  if (LoadFileCheck == 1) {
    textFont(font3);
      // Start a new style
    textAlign(CENTER);
    text(FileName, width/2, 146);
  }
  
 popStyle();

}



void Save() {
 selectOutput("Select a file to write to:", "fileSelected");
}

void fileSelected(File selection) {
  if (selection == null) {
    println("Window was closed or the user hit cancel.");
  } else {
    println("User selected " + selection.getAbsolutePath());
  }
}

void Open() {

    selectInput ( "Open iLoopino8 Eeprom:", "fileSelected_in", dataFile( "*.il7" ));

}

void fileSelected_in(File selection) {
  textFont(font3);

  if (selection == null) {
LoadFileCheck = 0;

  } else {

    LoadFileCheck = 1;

    EepromData = (loadStrings(selection.getAbsolutePath()));

    GetFilePath = selection.getAbsolutePath();
    NamePath = splitTokens(GetFilePath, System.getProperty("file.separator"));
    OnlyName = NamePath.length;
    FileName = (NamePath[OnlyName - 1]);

    println();
    println();
    println(FileName);

    //  text(FileName, 2, 146);
  }

}
1 Like

Well, it looks like I found a fix. Placing “noLoop();” and “loop();”
Any comments on this would be appreciated. I am a beginner and would like to understand why :slight_smile:

void Open() {
noLoop();
    selectInput ( "Open iLoopino8 Eeprom:", "fileSelected_in", dataFile( "*.il8" ));

}

void fileSelected_in(File selection) {
  textFont(font3);

  if (selection == null) {
LoadFileCheck = 0;

  } else {

    LoadFileCheck = 1;

    EepromData = (loadStrings(selection.getAbsolutePath()));

    GetFilePath = selection.getAbsolutePath();
    NamePath = splitTokens(GetFilePath, System.getProperty("file.separator"));
    OnlyName = NamePath.length;
    FileName = (NamePath[OnlyName - 1]);

    println();
    println();
    println(FileName);

    //  text(FileName, 2, 146);
  }
loop();
}

Hello,

Try this:
String FileName = "";

image

I created a test.iL7 to test.

Reference:
https://forum.processing.org/two/discussion/8071/why-do-i-get-a-nullpointerexception

:)

1 Like

Hi, thanks, as I said, I fixed it by using “noLoop();” and “loop();” when loading the file

1 Like

I am not able to reproduce your problem with the initial post-1 code. However, it is probably a race condition between selectInput() and draw(). The selectInput thread sets LoadFileCheck to 1, but then draw is able to get into the condition before the selectInput thread can set FileName.

Unlike almost everything else in processing, which behaves like a single thread following a control flow, dialogs such as selectInput() spawn a separate thread while draw() continues, so this kind of problem while modifying shared variables is possible.

You say that you have fixed this by turning off drawing while your selectInput thread runs. If draw doesn’t run at all, it won’t hit the null variable early and error out. However, noLoop() and loop() don’t need to be used in this way – you can still make your code work during input dialogs without turning off draw() just by being careful about how you set and access variables.

Specifically: you are getting a NullPointerException error from text(FileName, width/2, 146);
This is because you declare it without assignment (String FileName;) – now it is null. You have created a gate boolean – byte LoadFileCheck = 0; – which you set to 1 if fileSelected_in receives a non-null selection.

BUT – does having a selection guarantee that FileName will be assigned? According to your issue, it does not guarantee that – apparently LoadFileCheck is set to 1, then draw happens while FileName is still null.

The easiest way of all to guard against this is either:

  1. initialize FileName as an empty string "" – then it will display with text(), even if it prints nothing. (as @glv recommended)
  2. or, gate your actual value. Forget LoadFileCheck, and instead:
  if (FileName == null){
    text("No File Selected", width/2, 146);
  } else {
    text(FileName, width/2, 146);
  }

Ideally, do both! Initialize the string as "" for display safety, then check it for null explicitly just to be safe – a load dialogue might reset it to null on an error, for example.

The key concept here is that you are testing the actual display value for the actual error-causing value. This is useful throughout display in Processing – you often don’t need to set guard fields when you can check the values themselves.

If you really needed to use this guard field design in a separate thread – and you don’t! – then the solution would be to invert the value assignments. Instead of:

  1. LoadFileCheck = 1; // my variable is safe to use!
  2. FileName = "foo"; // set my variable – oops, already accessed with error

do it the other way:

  1. FileName = "foo"; // set my variable
  2. LoadFileCheck = 1; // my variable is safe to use!
    EepromData = (loadStrings(selection.getAbsolutePath()));
    GetFilePath = selection.getAbsolutePath();
    NamePath = splitTokens(GetFilePath, System.getProperty("file.separator"));
    OnlyName = NamePath.length;
    FileName = (NamePath[OnlyName - 1]);

    LoadFileCheck = 1;
4 Likes