2
votes

I have an assignment where I have to display "gym machines" and their data through the PApplet processor. I need to use polymorphism and inheritance (a treadmill is a GymMachine, etc.). Each gym machine must have its own draw method. I just can't figure out how to avoid a NullPointerException.

This is the code in my "ProcessingExample.java" file, the code that will actually draw the images through a processor:

import processing.core.PApplet;
import processing.core.PImage;

public class ProcessingExample extends PApplet {

  public long start_time;

  public static int canvas_x = 1200;
  public static int canvas_y = 800;

  TreadMill treadmill;
  Stepper stepper;
  Bicycle bicycle;

  public ProcessingExample(){
    start_time = System.currentTimeMillis();
  }

  public void setup(){
    size(canvas_x, canvas_y);
    treadmill = new TreadMill();
    stepper = new Stepper();
    bicycle = new Bicycle();
  }

  public void draw(){
    // treadmill
    treadmill.draw();
  }
}

This is my GymMachine class, from which the treadmill will derive:

import processing.core.PApplet;
import processing.core.PImage;

public class GymMachine extends PApplet {
  public long start_time;

  public static int canvas_x = 1200;
  public static int canvas_y = 800;

  public GymMachine(){
    start_time = System.currentTimeMillis();
  }

  public void draw(){ // for now I am just trying to draw the background, a block of color on 1/3 of the canvas
    fill(83, 85, 171);
    rect(0, 0, canvas_x / 3, canvas_y);
  }
}

Here is my treadmill class just for the sake of clarity:

import processing.core.PApplet;
import processing.core.PImage;

public class TreadMill extends GymMachine {
  private int angleOfInclination;
  private double mph;

  public TreadMill(){
    angleOfInclination = 1;
    mph = 1.0;
    image = "treadmill.png";
  }

  public TreadMill(int i, double m){
    if (i >= 1 && i <= 15){ // data validation
      angleOfInclination = i;
    }
    else { // else, defer to defaults
      angleOfInclination = 1;
    }

    if (m >= 1.0 && m <= 15.0){
      mph = m;
    }
    else {
      mph = 1.0;
    }
  }

  public void setAngleOfInclination(int i){
    if (i >= 1 && i <= 15){ // data validation
      this.angleOfInclination = i;
    }
  }

  public void setMPH(double m){
    if (m >= 1.0 && m <= 15.0){ // data validation
      this.mph = m;
    }
  }

  public long getCaloriesUsed(){
     return 20 *(long) mph + 15 * angleOfInclination;
  }

  public String toString(){
    return "Angle of inclination is " + angleOfInclination + " degrees; Speed is " + mph + " mph; Calories burned: " + this.getCaloriesUsed();
  }
}

For the past 5 hours, I haven't been able to figure out why treadmill.draw() complains a NullPointerException. I'm not quite sure what the null variable is. I have tried making ProcessingExample and GymMachine the same class, because I thought maybe it needed access to the "same canvas," but the problem then is that ProcessingExample keeps calling itself, since I need to create an instance of treadmill somewhere. I have also read that rather than making GymMachine extend PApplet, I could make the constructor take an argument of type PApplet, (i.e. GymMachine(PApplet p){...}), but then I cannot get TreadMill to derive from this. Any help is appreciated.

1

1 Answers

1
votes

Only one class should extend the PApplet class.

Think of a PApplet as a whole sketch running in a window. You only want one window to show up, right? So you only want one PApplet class.

You don't want each GymMachine to show up in its own window. You want multiple GymMachines to be drawn in one window. So get rid of the extends PApplet on the GymMachine class.

After you do that, you'll get some compiler errors because the GymMachine class won't recognize functions like fill() or rect(). To fix this, you'll need to pass in an instance of the main sketch class (the class that does extend PApplet) into the secondary sketch class. The this keyword comes in handy for this.

Finally, you'll have to use the reference to the main PApplet sketch to call Processing functions. Here's an example:

public class MySketch extends PApplet{

  Thing thing = new Thing(this);

  public void draw(){
    thing.draw();
  }
}

public class Thing{
  PApplet mainSketch;

  public Thing(PApplet mainSketch){
    this.mainSketch = mainSketch;
  }

  public void draw(){
    mainSketch.ellipse(100, 100, 100, 100);
  }
}

See the Calling Processing Functions From Non-Sketch Classes section of this tutorial for more info.