mike eustace
mike eustace

Reputation: 61

processing - passing variables as parameters - getting NullPointerException

I have written the code with the constructor which passes in the variables to Lsystem.

This should allow me to create numerous 'Trees', messing around with the parameters each time.

However, I'm getting a NullPointerException with the line

for (int i=0; i < m_state.length(); i++) {

I understand that I need to use this. somewhere (having read all I can), but am stuck as to how to make my code work.

If someone can show me what the correct code should look like, I'd be much obliged.

Thank you in advance.

class Tree {

  // member variables
  int    m_lineLength;       // turtle line length
  int    m_x;                // initial x position
  int    m_y;                // initial y position
  float  m_branchAngle;      // turtle rotation at branch
  float  m_initOrientation;  // initial orientation
  String m_state;            // initial state
  float  m_scaleFactor;      // branch scale factor
  String m_F_rule;           // F-rule substitution
  String m_H_rule;           // H-rule substitution
  String m_f_rule;           // f-rule substitution
  int    m_numIterations;    // number of times to substitute

  // constructor
  // (d = line length, x & y = start position of drawing)
  Tree(int d, int x, int y, float m_branchAngle, float m_initOrientation, String m_state, float m_scaleFactor, String m_F_rule, String m_H_rule, String m_f_rule, int m_numIterations) {
    m_lineLength = d;
    m_x = x;
    m_y = y; 
    m_branchAngle = (25.7/180.0)*PI;
    m_initOrientation = -HALF_PI;
    m_scaleFactor = 1;
    m_state = "F";
    m_F_rule = "F[+F]F[-F]F";
    m_H_rule = "";
    m_f_rule = "";
    m_numIterations = 5;

    // Perform L rounds of substitutions on the initial state
    for (int k=0; k < m_numIterations; k++) {
      m_state = substitute(m_state);
    }
  }

  void draw() {
    pushMatrix();
    pushStyle();

    stroke(0);
    translate(m_x, m_y);        // initial position
    rotate(m_initOrientation);  // initial rotation

    // now walk along the state string, executing the
    // corresponding turtle command for each character
    for (int i=0; i < m_state.length(); i++) {
      turtle(m_state.charAt(i));
    }

    popStyle();
    popMatrix();
  }

  // Turtle command definitions for each character in our alphabet
  void turtle(char c) {
    switch(c) {
    case 'F': // drop through to next case
    case 'H':
      line(0, 0, m_lineLength, 0);
      translate(m_lineLength, 0);
      break;
    case 'f':
      translate(m_lineLength, 0);
      break;
    case 's':
      scale(m_scaleFactor);
      break;
    case '-':
      rotate(m_branchAngle);
      break;
    case '+':
      rotate(-m_branchAngle);
      break;
    case '[':
      pushMatrix();
      break;
    case ']':
      popMatrix();
      break;
    default:
      println("Bad character: " + c);
      exit();
    }
  }

  // apply substitution rules to string s and return the resulting string
  String substitute(String s) {
    String newState = new String();
    for (int j=0; j < s.length(); j++) {
      switch (s.charAt(j)) {
      case 'F':
        newState += m_F_rule;
        break;
      case 'H':
        newState += m_F_rule;
        break;
      case 'f':
        newState += m_f_rule;
        break;
      default:
        newState += s.charAt(j);
      }
    }
    return newState;
  }

}

and

Tree tree;

void setup() {
  int SZ = 512;  // screen size

  int d = 2;
  int x = SZ/2;
  int y = SZ;

  float m_branchAngle = (25.7/180.0)*PI;
  float m_initOrientation = -HALF_PI; 
  String m_state = "F";
  float m_scaleFactor = 1;
  String m_F_rule = "F[+F]F[-F]F";
  String m_H_rule = ""; 
  String m_f_rule = "";
  int m_numIterations = 5;

  size(SZ,SZ);
  background(255);
  noLoop();

  tree = new Tree(d, x, y, m_branchAngle, m_initOrientation, m_state, m_scaleFactor, m_F_rule, m_H_rule, m_f_rule, m_numIterations);  
}

void draw() {
  tree.draw();
}

Upvotes: 0

Views: 119

Answers (1)

Kevin Workman
Kevin Workman

Reputation: 42174

Let's take a look at a simplified version of your Tree constructor:

String m_state;

Tree(String m_state) {
    m_state = "F";
    for (int k=0; k < m_numIterations; k++) {
      m_state = substitute(m_state);
    }
}

Notice that you have two variables named m_state: one class-level instance variable, and one argument into the constructor. That means the constructor-level variable is hiding the class-level variable. Anything you do with the m_state variable inside your constructor is referring to the constructor-level variable, not the class-level variable.

Then later you use the class-level variable, which you've never actually initialized. That's what's causing your NullPointerException.

One way to fix the problem is to use the this keyword to specifically refer to the class-level variable:

String m_state;

Tree(String m_state) {
    this.m_state = "F";
    for (int k=0; k < m_numIterations; k++) {
      this.m_state = substitute(this.m_state);
    }
}

But then, if you aren't using the constructor-level m_state variable for anything, why do you bother with it at all? So you might be able to eliminate the parameter altogether, if you're just going to set it equal to "F" anyway.

Upvotes: 2

Related Questions