Excercise 9-8: From the book "Learning Processing" Daniel Shiffman

Hi, the question in the book is...

"Write a Button class (see Example 5-5 for a non-object-oriented button). The Button class should register when a mouse is pressed over the button and change color. Create buttons of different sizes and locations using an array. Before writing the main program, sketch out the Button class. Assume the button is off when it first appears."

I can get this to work for a single button and have it change colour no problem with a mouse click but when I try to add multiple buttons using an array, if I click a button, ALL the buttons change colour. What I would like is to use an array where if i click just a single button ONLY that button changes colour, not all of the buttons in the array. How could I fix this? Thanks.

Button[] buttons = new Button[15];

void setup() {
  size(800, 800);
  smooth(4);
  background(0);

  for (int i = 0; i < buttons.length; i++) {
    buttons[i] = new Button(random(0, width), random(0, height), 100, 25);
  }
}

void draw() {
  background(0);
  for (int i = 0; i < buttons.length; i++) {
    buttons[i].display();
  }
}

class Button {

  float x;
  float y;
  float w;
  float h;
  boolean on;

  Button(float tempX, float tempY, float tempW, float tempH) {
    x = tempX;
    y = tempY;
    w = tempW; 
    h = tempH;
    on = false;
  }

  void display() {
    noStroke();
    if (isClicked(mouseX, mouseY) && mousePressed) {
      fill(255, 0, 0);
    }    
    rect(x, y, w, h);
  }

  boolean isClicked(float mousex, float mousey) {
    if (mousex > x && mousex < x + w && mousey > y && mousey < y + h) {
      return on = true;
    }
    return on = false;
  }
}
Tagged:

Answers

  • Answer ✓

    The color set by fill() is persistent. Everything you draw after setting the fill color to red (line 39) will be drawn in red too - even other buttons that you draw!

    Add this as line 37.5:

    fill(255);
    
  • Two ways of creating non-persistent fill():

    1. set it, then set it back

      if (isClicked(mouseX, mouseY) && mousePressed) {
        fill(255, 0, 0);
      }    
      rect(x, y, w, h);
      fill(255, 255, 255);
      
    2. isolate change(s) with pushStyle(), then revert them with popStyle()

      pushStyle();
      if (isClicked(mouseX, mouseY) && mousePressed) {
        fill(255, 0, 0);
      }    
      rect(x, y, w, h);
      popStyle();
      
  • Thanks guys I've done some programming in OpenGL before using model-view transformations with push and pop matrix etc, I would assume push and pop style works in a similar way by manipulating the underlying matrix, think I might stick with the last option. Cheers.

  • edited September 2017

    Yes -- in this case, pushMatrix() manipulates the underlying translation, rotation, scale, etc.

    pushStyle() is a stack of settings for fill, stroke, colorMode, etc.

Sign In or Register to comment.