Deeply-layered nested classes

Hello.
I’m trying to make nested classes to make some sort of system in my classes. I am working insode Visual Studio Code, where you can hide lines of code.

When I try:

static class A{
    static class B{
        class C{
            C(){}
        }
    }
}


A.B.C ins = new A.B.C();

it gives me an error: …** No enclosing instance of type Test.A.B is accessible. Must qualify the allocation with an enclosing instance of type Test.A.B (e.g. x.new A() where x is an instance of Test.A.B).*

When I try

class A{
    A(){}
    class B{
        B(){}
        class C{
            C(){}
        }
    }
}

The only way it works is when I do:

A.B.C inst = ((new A()).new B()).new C();

Why can’t I make nested classes like in java?

1 Like
  • If your code is inside “.pde” files, all your classes & interfaces are nested to a PApplet subclass.
  • As a workaround, you can declare them all as static, so they behave like top classes.
  • Or move them to a “.java” file. Processing’s IDE (PDE) recognizes “.java” files in addition to “.pde”.
2 Likes

In this example, all of the 3 nested classes are declared as static:

void setup() {
  A.B.C c = new A.B.C();
  exit();
}

static class A {
  static class B {
    static class C {
    }
  }
}

And in this 1, the innermost class C isn’t static. We need to instantiate class A.B before instantiating class C:

void setup() {
  A.B.C c = new A.B().new C();
  exit();
}

static class A {
  static class B {
    class C {
    }
  }
}
3 Likes

Thanks for the reply.
So, the outer most class is the PAplet. Is it static or not?

That’s right! It is a PApplet subclass. :sunglasses:
All top classes are implicitly static by nature. :nerd_face:

Ok, so I tried this:

static class A{
  class B(){
    
  }
}

A.B b = A.new B();

And the console said:

Status ERROR: org.eclipse.jdt.core code=4 Exception occurred during compilation unit conversion:
----------------------------------- SOURCE BEGIN -------------------------------------
import processing.core.*;
import processing.data.*;
import processing.event.*;
import processing.opengl.*;
import java.util.HashMap;
import java.util.ArrayList;
import java.io.File;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;

public class sketch_180705a extends PApplet {
public void setup() {
static class A{
  class B{
    
  }
}

A.B b = A.new B(

}
}

----------------------------------- SOURCE END ------------------------------------- java.lang.IllegalArgumentException

So, there is a new bug I guess.

This works inside the PApplet subclass:

class A{
  class B{
    
  }
}

A.B b = new A().new B();
class A{
  class B{ 
    class C{
      
    }
  }
}

A.B.C b = new A().new B().new C();

Also, I can’t set any class to be static.

I have tried in IntelliJ IDEA and the code modify this way works for me:

package com.processing.sketch;

import processing.core.PApplet;

public class Sketch extends PApplet {

    public void settings() {
    }

    public void setup() {
        A.B.C ins = new A().new B(). new C();
    }

    public void draw() {
    }

    public static void main (String[] args) {

        Sketch object = new Sketch();
        PApplet.runSketch(new String[]{"Sketch"}, object);
    }


    class A{
        A(){}
        class B{
            B(){}
            class C{
                C(){}
            }
        }
    }

}

Let me know if it dose what you want to achieve and if it works in your environment as well.

As I had stated already: :roll_eyes:

In other words: We can’t have top classes or interfaces inside “.pde” files! :cry:
Most we can do is declaring them as static. That’s as far as we can get to actual top classes’ behavior: :expressionless:

static class A {
  static class B {
  }
}

A.B ab;

void setup() {
  ab = new A.B();
  exit();
}

And again, as I had previously advised you at that very same post: :face_with_monocle:

Simply place those classes & interfaces inside a “.java” file. They’d become actual top classes & interfaces. :coffee:

1 Like

Yes, but I don’t want want to move outside the Aplet subclass, because I need to draw stuff.
Also I can’t declare any class static if there is another class in it. And in fact I can’t even declare the inner class static. The error displaying field says, I can only declare them virtual on abstract.

I have an idea, that I could outside of PAplet subclass create PGraphics to draw in and then inside the PApplet subclass just draw all PGraphics instances.

Or, I could get the instance of the PGraphics inside the PApplet subclass and draw directly in it outside of the PAplet subclass. I don’t know how to get the PGrapgics instance tho.

I need to work inside the PApplet class only because I need to be able to draw. If I could draw outside of it, I’d use .java files.

mat650: That is basically what I tried…

1 Like

Placing code in “.java” files instead of “.pde” was just an advise.
Declaring nested classes as static is pretty close to the same behavior of top classes in “.java” files after all.

However, whether a class is top, static or inner, got nothing to do w/ drawing stuff or not!

If a top class couldn’t do it like you state, how is it possible that libraries written for Processing are able to?

The trick is to request the PApplet’s reference in their constructor, store it as a field, and then use it in order to draw on that PApplet’s canvas.

Nested static classes can do the same as top classes. Just demand the PApplet’s reference.

2 Likes

Once a class has a hold of some running PApplet reference, it can grab its canvas by invoking getGraphics().

Although we don’t really need to; given we can invoke drawing methods directly through the PApplet reference.

2 Likes

Oh, then that is why all kinds of classes from libraries, that can draw, need to be initalized outside of any class inside the outer PAplet subclass in order to get the this to return PApplet, so that it can get a reference to the PAplet subclass.

I got more from this topic, than I asked for. Thanks very much. :slight_smile:

1 Like

By the way, how do you mark a topic answered?

1 Like