Can anyone help explain the following use of "this" and "PApplet"?

Hello,

I’m stumbling around using Benedikt Groß’s ANI library for processing, and was getting really confused. I’m probably in over my head.

I was trying to create what his library calls AniSequences inside a class I created and kept hitting an error that I didn’t know how to fix. Later, I accidentally came across a solution that seems to have fixed it, but I don’t understand how it did this. I was hoping someone could explain to me… like you would a six year old.

So in a sketch without using classes, after importing the library and initializing it with:
Ani.init(this);
setting up a sequence looks something like the following:

AniSequence seq;
void setup() {
  seq = new AniSequence(this);
  blah blah blah
}

OK. So when I tried doing this inside a class, i tried something like this:

Class Thing {
  AniSequence seq;

  Thing() {
    seq = new AniSequence(this);
    blah blah blah
  }
}

But this kept giving me the error: “The Constructor ani.AniSequence(Thing)” does not exist.
No matter what I did, I couldn’t get processing to see it.

So looking at someone else’s code on here, I found this technique:

Inside the main sketch:

thing1 = new Thing(this);

And then, inside the class:

Class Thing {
  AniSequence seq;

  Thing(PApplet _p) {
    seq = new AniSequence(_p);
    blah blah blah
  }
}

So far… the above seems to be working.
But I have no idea what’s happening. Could someone explain it?
I thought I understood what “this” meant, but apparently not. I don’t understand what using “this” is passing into the class. And I have zero idea what PApplet is or what it’s doing.

Thank you for reading this far.
Beginner programmer, any and all help is greatly appreciated.

1 Like

The keyword this refers to the current object so in setup it refers to a PApplet object but inside the class Thing if refers to a Thing object. The AniSequence constructor is expecting a PApplet object hence the error. The solution is

Class Thing {
  AniSequence seq;

  Thing(PApplet app) {
    seq = new AniSequence(app);
    blah blah blah
  }
}

and in setup

Thing thing;

void setup() {
  thing = new Thing(this);
  blah blah blah
}

There are tutorials and videos on using object orientation (classes and objects) on the Processing main site that you should check out.

Another way to put it is that keyword this is of the same datatype of the class it’s inside.

For example, inside class Thing, this refers to an instance of datatype Thing.

Outside of any class but yet inside a file w/ extension “.pde”, this refers to an instance of datatype PApplet.

More precisely, a subtype of PApplet whose name matches the sketch’s root folder.

Rather than relegating to a class the responsibility of instantiating another class (same for loading assets), do it within setup() and pass it as an argument to the class's constructor:

1 Like

There is always more than one way to do anything in programming and this is a valid alternative where you might have many Thing objects sharing a common AniSequence object.

On the other hand if you have many Thing objects and each has its own instance of AniSequence then I would go with the technique I described and instantiate the AniSequence object inside the Thing class constructor.

The programmer much make the choice based on knowledge of their own OO design and class interactions.

1 Like

That’s very reasonable in this case.

However we can still pre-instantiate separate AniSequence objects within setup() for each Thing we instantiate.

Both external & internal instantiation approaches are valid for classes which depend on the PApplet class.

This replay is based on the premise that every Thing object has its own AniSequence object

This assumes that all Thing objects are going to be instantiated inside setup which might not be the case. Consider a situation when you want to create a Thing object every time the T key is typed and add it to some global list

With the technique I described I would have

void keyTyped(){
  list.add(new Thing(this));
}

With the technique you described we would need

void keyTyped(){
  list.add(new Thing(new AniSequence(this)));
}

The programmer must remember to create two objects instead of one.

As I said before - it is down to the programmer to make choices based on knowledge of their own OO design and class interactions.

1 Like

Though I appreciate the attempt, I must admit I’m a little frustrated by this response as the tutorials and videos concerning object orientation do not ever mention ‘this’ or PApplet.

Processing in JAVA mode uses the object orientated (OO) language Java.

In OO you can consider a class as a sophisticated data type and the Java programming language is based on a huge number of classes. As well as these classes the programmer (aka user) can create their own classes and we call them user defined classes (UDCs). By convention Java capitalises the first letter of its name, so PApplet is the name of a UDC, in fact it is part of the Processing library of classes. The PApplet class provides the core functionality to initialise and manage the running sketch including the creation of the window the sketch runs in.

If we wanted a UDC called Foo then we would start with the code

class Foo {
  // attributes and methods (aka fields and functions) of the Foo class go here
}

This is a class definition and we can create objects of type Foo with the new keyword like this

Foo fa, fb;
fa = new Foo();
fb = new Foo();

OK now lets say the Foo class has two attributes x and y and a constructor to initialise these attributes. Our Foo class might look like

class Foo {
  int x;    // in this class it is referred to as this.x
  int y;    // in this class it is referred to as this.y

  // Constructor is always named after class
  Foo(int x, int y){  
    this.x = x;
    this.y = y;
  }
}

Notice the use of the keyword this, here it is being used correctly to reference the attributes and we can now create our Foo objects like this

fa = new Foo(11, 22);
fb = new Foo(33, 44);

So in your skecth code example

AniSequence seq;
void setup() {
  seq = new AniSequence(this);
  blah blah blah
}

you might wonder about the use of this.

Before Processing executes your sketch it wraps the code inside the PApplet class definition, something like this (gross over-simplification of what happens)

class PApplet {

  // Start of sktech code entered by user e.g.
  AniSequence seq;
  void setup() {
      seq = new AniSequence(this);
      // blah blah blah
  }
 // End of sketch code entered by user

} // End of PApplet calss definition

this now refers to the PApplet object created by Processing.

Notice that the AniSequence constructor is expecting a PApplet object but in this code

Class Thing {
  AniSequence seq;

  Thing() {
    seq = new AniSequence(this);
    blah blah blah
  }
}

this is a Thing object hence the error message.

Hope this helps :grin:

1 Like

Thank you!
I understood most of what you said, except for the use of this in the constructor.

class Foo {
  int x;    // in this class it is referred to as this.x
  int y;    // in this class it is referred to as this.y

  // Constructor is always named after class
  Foo(int x, int y){  
    this.x = x;
    this.y = y;
  }
}

I’ve never seen this used in a constructor in any tutorials or reference books.
Instead of:

  Foo(int x, int y){  
    this.x = x;
    this.y = y;
}

I’ve only seen it done like:

  Foo(int x_, int y_){  
    x = x_;
    y = y_;
}

Is that way wrong? Why is this.x necessary?

In Java the keyword this is necessary when we have a local variable or parameter temporarily overshadowing a field w/ the same name:

The constructor’s parameters x & y happen to match the name of fields Foo::x & Foo::y above.

So inside the whole body of Foo’s constructor, when we write x or y, we’re referring to parameters x & y in place of fields x & y, b/c the former are overshadowing the latter there.

Inside a code block w/o local variables or parameters overshadowing their corresponding field names, keyword this is optional in Java, b/c the compiler is sure now that name can only be a field.

1 Like