# Self rendering objects?

**URL:** <https://discourse.processing.org/t/self-rendering-objects/4427>\
**Category:** Coding Questions\
**Created:** [October 13, 2018, 2:42pm UTC](https://discourse.processing.org/t/self-rendering-objects/4427 "2018-10-13T14:42:06Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![GaizkaNaz](https://avatars.discourse-cdn.com/v4/letter/g/ea666f/32.png) [@GaizkaNaz](https://discourse.processing.org/u/GaizkaNaz)\
**Post date:** [October 13, 2018, 2:42pm UTC](https://discourse.processing.org/t/self-rendering-objects/4427/1 "2018-10-13T14:42:06Z")

</div>

Hello everybody!

I’m working on my own GUI project. Can someone point me on the right direction to make “self rendering objects”?

For example, ive got a class Buttons, i would like to make an instance of that class and the button render on the screen each frame without me having to call a MyButton.Render() function.

Thank you all.

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [October 13, 2018, 4:31pm UTC](https://discourse.processing.org/t/self-rendering-objects/4427/2 "2018-10-13T16:31:04Z")

</div>

The following code shows how an object can ‘self-register’ to draw itself. In a GUI you will also need to register for mouse and key events more info can be found [here](https://github.com/processing/processing/wiki/Library-Basics).

```auto
Button b;

void setup() {
  size(300, 200);
  b = new Button(this, 30, 20, 200, 30);
}

void draw() {
  background(255, 255, 200);
}

public class Button {

  PApplet pa;
  int x, y, w, h;

  public Button(PApplet pa, int x, int y, int w, int h) {
    this.pa = pa;
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h; 
    pa.registerMethod("draw", this);
  }

  public void draw() {
    pa.pushMatrix();
    pa.pushStyle();
    pa.fill(180, 180, 255);
    pa.stroke(0, 0, 128);
    pa.strokeWeight(2);
    pa.translate(x, y);
    pa.rect(0, 0, w, h);
    pa.popStyle();
    pa.popMatrix();
  }
}

```

Processing already has some GUI libraries you might look at G4P and ControlP5 😀

---

<div class="post-metadata">

**Author:** ![GaizkaNaz](https://avatars.discourse-cdn.com/v4/letter/g/ea666f/32.png) [@GaizkaNaz](https://discourse.processing.org/u/GaizkaNaz)\
**Post date:** [October 13, 2018, 7:18pm UTC](https://discourse.processing.org/t/self-rendering-objects/4427/3 "2018-10-13T19:18:06Z")

</div>

Hello quark!

Thank you for your reply! This will very helpfull.

Yes, i know there are some GUI libraries already, in fact, i’ve been using G4P for a long time and i love it, but i just wanted to do my own modest version 🙂

Thank you again

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [October 26, 2018, 3:21pm UTC](https://discourse.processing.org/t/self-rendering-objects/4427/4 "2018-10-26T15:21:49Z")

</div>

One thing to think hard about when developing a collection of self-rendering objects is whether you want them to be responsible for their own positions, or whether you want a container (or the sketch) to manage positioning them.

It is often the case that, reflexively, one may start passing lots of xywh around everywhere for everything. That isn’t always necessary.

For example, in the Processing, `rect()` is xywh, while `box()` and `sphere` do not have an xyz – you position them with `translate()` calls. Both methods are effective, but different. In UI, an interesting example might be an accordion or drop-down menu items – you might want them to have relative offsets, or just indexes and no positions at all.

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [October 26, 2018, 4:25pm UTC](https://discourse.processing.org/t/self-rendering-objects/4427/5 "2018-10-26T16:25:42Z")

</div>

> [@jeremydouglass](#):
>
> One thing to think hard about when developing a collection of self-rendering objects is whether you want them to be responsible for their own positions, or whether you want a container (or the sketch) to manage positioning them.

For me it is an easy choice because good OO (object orientation) design requires classes to be autonomous so a self-rendering object (i.e. a GUI control) must be responsible for its own position, size, colour etc. The trick here is to realise that the position of the object need not be the actual screen position but relative to some parent control.

**In G4P _all_ controls have their own [x,y] position attributes / fields.**

G4P has the `GPanel` class which implements a floating panel to which _any_ other G4P control can be added. In this case the panel position [x,y] holds the actual screen position and the [x,y] fields of any added control are relative to the panels position.

To enable this the GPanel class maintains a list of other controls that have been added to it.

The scrollbars (`GSlider` class) used in `GTextArea`, `GTextField` and `GDropList` work in a similar manner.

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [October 26, 2018, 4:40pm UTC](https://discourse.processing.org/t/self-rendering-objects/4427/6 "2018-10-26T16:40:58Z")

</div>

Right, it depends on your goals: if you want your objects to be autonomously self-rendering, they should have what they need.

An interesting recent counter-use-case was this animated text stream.

> [@Animated text / Spacing problem](https://discourse.processing.org/t/animated-text-spacing-problem/4559/4):
>
> You are storing absolute coordinates (x, y) in your Letter class - but there is no way for each letter to know its cumulative offset without giving it a way to check the list of all the letters to the left of it. Its absolute position shouldn’t be its job. Instead, you want a cursor variable or class. Each time a letter is printed, it knows its own width (because the textSize is set) – at that moment, it needs to tell the cursor how wide it is, and the cursor will advance by that much. Then pr…

OP set out to make the letter autonomously renderable, but that was needlessly complex – in fact, they were always being rendered relative to an accumulation of shifting previous objects, so one alternate approach that made sense was for them not to store their own location, but instead be positioned in a typing stream.

Of course, that approach makes more sense if you are changing the locations of every object every frame or constantly re-sequencing – not common for most GUI control elements.

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [October 26, 2018, 5:28pm UTC](https://discourse.processing.org/t/self-rendering-objects/4427/7 "2018-10-26T17:28:58Z")

</div>

I saw the discussion about animated text and what you say is reasonable.

In this case I would have a class called `AnimatedText` which would have a `private` inner class to represent a single character lets call it `Character` so can only be accessed by the enclosing class `AnimatedText`.

So where do we store the display coordinates for individual characters?  
Two options

1. Inside the `Character` class and updated by the `AnimatedText` class.
2. Inside and updated by the `AnimatedText` class as a collection.

For me option (1) is the correct choice.

Why not option (2), because it requires two collections one for coordinates and one for characters and they must synchronised / linked to maintain the position \<\> character link.

Option (1) requires just one collection so easily enables lots of clever text manipulation e.g. inserting / deleting / reordering characters etc.

---

<div class="post-metadata">

**Author:** ![kll](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kll/32/964_2.png) [@kll](https://discourse.processing.org/u/kll)\
**Post date:** [October 27, 2018, 2:39am UTC](https://discourse.processing.org/t/self-rendering-objects/4427/8 "2018-10-27T02:39:04Z")

</div>

@quark i like your example and used it, until i got stuck:

as a not “self rendering” i would have to call the .draw methode manually,  
( and when ever I WANT. )  
with this one i not need, it draws always  
and that’s the point, it must have a **show & hide methode** add to the  
auto draw.

could you pls help to add this for this example?

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [October 27, 2018, 11:09am UTC](https://discourse.processing.org/t/self-rendering-objects/4427/9 "2018-10-27T11:09:09Z")

</div>

I have modified the sketch so the self-rendering object can be invisible. The ‘v’ key toggles visibility.

```auto
Button b;

void setup() {
  size(300, 200);
  b = new Button(this, 30, 20, 200, 30);
}

void draw() {
  background(255, 255, 200);
  fill(0);
  textSize(16);
  text("Hit 'v' to make visible / invisible", 30, 100);
}

void keyReleased() {
  if (key == 'v') {
    b.setVisible(!b.isVisible());
  }
}

public class Button {

  PApplet pa;
  int x, y, w, h;
  boolean visible = true;

  public Button(PApplet pa, int x, int y, int w, int h) {
    this.pa = pa;
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h; 
    pa.registerMethod("draw", this);
  }

  public void setVisible(boolean visible) {
    this.visible = visible;
  }

  public boolean isVisible() {
    return visible;
  }

  public void draw() {
    if (visible) {
      pa.pushMatrix();
      pa.pushStyle();
      pa.fill(180, 180, 255);
      pa.stroke(0, 0, 128);
      pa.strokeWeight(2);
      pa.translate(x, y);
      pa.rect(0, 0, w, h);
      pa.popStyle();
      pa.popMatrix();
    }
  }
}

```

---

<div class="post-metadata">

**Author:** ![kll](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kll/32/964_2.png) [@kll](https://discourse.processing.org/u/kll)\
**Post date:** [October 27, 2018, 11:21am UTC](https://discourse.processing.org/t/self-rendering-objects/4427/10 "2018-10-27T11:21:55Z")

</div>

now it looks so easy… perfect,  
i was thinking there is a “unregistering” of the draw needed.

---

<div class="post-metadata">

**Author:** ![Ov3rM1nD](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/ov3rm1nd/32/1756_2.png) [@Ov3rM1nD](https://discourse.processing.org/u/Ov3rM1nD)\
**Post date:** [January 29, 2019, 8:00pm UTC](https://discourse.processing.org/t/self-rendering-objects/4427/11 "2019-01-29T20:00:07Z")

</div>

Hello @quark, I tried your code and did some experiments with it, and I tried to follow the tutorial you quoted [here](https://github.com/processing/processing/wiki/Library-Basics). I have some questions and I know that you are an expert on this subject, so if you can help me clarify these questions I will be very grateful. I have been trying to understand this subject for a long time. Here is the code:

```auto
Button btn;
color c;
int num;

void setup() {
  size(300, 200);
  btn = new Button(this, width/2, height/2, 150, 30);
  textSize(50);
  textAlign(CENTER);
}

void draw() {
  background(c);
  text(num, width/2, height/3);
}

void buttonMouseover(Button b) {
  if(frameCount % 60 == 0) c = color(random(255), random(255), random(255));
  num++;
}

// ***BUTTON CLASS***
import java.lang.reflect.*;

public class Button {
  PApplet pa;
  Method myEventMethod;

  float x, y, w, h;
  int fillColor;
  boolean visible = true;

  public Button(PApplet pa, float x, float y, float w, float h) {
    this.pa = pa;
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h; 
    fillColor = 0xff04B4FF;

    // check to see if the host applet implements
    // public void buttonMouseover(Button b)
    try {
      myEventMethod = pa.getClass().getMethod("buttonMouseover", new Class[] { Button.class });
    } 
    catch (Exception e) {
      // no such method, or an error.. which is fine, just ignore
    }

    pa.registerMethod("draw", this);
    pa.registerMethod("mouseEvent", this);
  }

  public void setVisible(boolean visible) {
    this.visible = visible;
  }
  public boolean isVisible() {
    return visible;
  }

  public void draw() {
    if (visible) {
      pa.pushMatrix();
      pa.pushStyle();
      pa.rectMode(PConstants.CENTER);
      pa.fill(fillColor);
      pa.translate(x, y);
      pa.rect(0, 0, w, h);
      pa.popStyle();
      pa.popMatrix();

      makeEvent();
    }
  }

  public boolean isInside() {
    boolean horizontal = pa.mouseX > x - w/2 && pa.mouseX < x + w/2;
    boolean vertical = pa.mouseY > y - h/2 && pa.mouseY < y + h/2;
    return horizontal && vertical;
  }

  public void mouseEvent(MouseEvent m) {
    //if (isInside() && m.getAction() == MouseEvent.PRESS) setVisible(!isVisible());
    if (isInside() && m.getAction() == MouseEvent.PRESS) fillColor = 0xffFF0000;
    if (isInside() && m.getAction() == MouseEvent.RELEASE) fillColor = 0xff04B4FF;
  }

  public void makeEvent() {
    if (myEventMethod != null) {
      try {
        if (isInside()) myEventMethod.invoke(pa, new Object[] { this });
      } 
      catch (Exception e) {
        System.err.println("Disabling buttonMouseover() because of an error.");
        e.printStackTrace();
        myEventMethod = null;
      }
    }
  }
}

```

I added a `mouseEvent()` through `registerMethod()` just like you did with `draw()`. Is it correct the way I did it? I’ve also added a `buttonMouseover()` through `java.lang.reflect.*`; following [the tutorial](https://github.com/processing/processing/wiki/Library-Basics). I do not know what `makeEvent()` does, can you help me understand what it does? Do I have to call it in `draw()` inside the button class, just like I did in the code above? Because only in that way I was able to make it work … is this method supposed to be invoked elsewhere?  
Finally, regarding the `buttonMouseover()` method, is this a good example - in this specific case for a button class - to use this type of technique? What’s the name of this concept and where can i find good source to read and learn? Thank you in advance 🙂

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [January 30, 2019, 11:49am UTC](https://discourse.processing.org/t/self-rendering-objects/4427/12 "2019-01-30T11:49:55Z")

</div>

@Ov3rM1nD  
Congratulations on getting as far as you have. First things first

> [@Ov3rM1nD](#):
>
> I added a `mouseEvent()` through `registerMethod()` just like you did with `draw()` . Is it correct the way I did it?

Yes that’s very good.

> [@Ov3rM1nD](#):
>
> I’ve also added a `buttonMouseover()` through `java.lang.reflect.*` ;

This technique uses **_Java Reflection_** and can be a difficult topic to master but you have made an excellent start. Java Reflection allows the user to examine the source code (classes, attributes, methods etc) at runtime and is really neat. It is the main technique I use in G4P and GUI Builder.

> [@Ov3rM1nD](#):
>
> I do not know what `makeEvent()` does, can you help me understand what it does?

in the constructor this code looks for our event handler and if found stores a reference to it in `myEventMethod`, if it can’t find the method `myEventMethod` will be initialised to `null`.

```auto
myEventMethod = pa.getClass().getMethod("buttonMouseover", new Class[] { Button.class });

```

So in the makeEvent method you first test to make sure the method exists then the crunch comes here

```auto
myEventMethod.invoke(pa, new Object[] { this });

```

`myEventMethod.invoke` - execute the method referenced by `myEventMethod`  
`pa` - is the object the underlying method is invoked from  
`new Object[] { this }` - a list or parameters to be passed to the method, in this case a single parameter of type `Button`

> [@Ov3rM1nD](#):
>
> Do I have to call it in `draw()` inside the button class, just like I did in the code above?

Two questions here, the first answer _is do not call it from the draw()_ because you already have registered your button for mouse events so remove the call from draw and changeb the mouseEvent to

```auto
public void mouseEvent(MouseEvent m) {
    //if (isInside() && m.getAction() == MouseEvent.PRESS) setVisible(!isVisible());
    if (isInside() && m.getAction() == MouseEvent.PRESS) fillColor = 0xffFF0000;
    if (isInside() && m.getAction() == MouseEvent.RELEASE) fillColor = 0xff04B4FF;
    if (isInside() && visible && m.getAction() == MouseEvent.MOVE) makeEvent();
  }

```

I would also modify this method further to use a switch statement to avoid multiple calls to isInsie and getAction like this

```auto
  public void mouseEvent(MouseEvent m) {
    if (isInside()) {
      switch (m.getAction()) {
      case MouseEvent.PRESS:
        fillColor = 0xffFF0000;
        break;
      case MouseEvent.RELEASE:
        fillColor = 0xff04B4FF;
        break;

      case MouseEvent.MOVE:
        if (visible) makeEvent();
        break;
      }
    }
  }

```

It is possible to call the method `makeEvent` from outside the class but it doesn’t make sense to do so and would only confuse someone reading your code.

> [@Ov3rM1nD](#):
>
> Finally, regarding the `buttonMouseover()` method, is this a good example - in this specific case for a button class - to use this type of technique?

It is a good example and the concept is called _Reflection_

If you google ‘java reflection tutorial’ there and lots of sites listed that might help.
