Trying to toggle multiple layers' visibility - New to Processing/Java,

Some experience in PHP but new to Java. I have a working layer visibility toggle but I’d like to make my toggleVis function able to handle more layers by passing a parameter. Any help out there, please? Here’s my code.

PGraphics layer1;
PGraphics layer1bak;
boolean transparent1 = false;

void setup() {
  size(400, 600);
  layer1 = createGraphics(width, height);
  background(255);
  stroke(0);
}

void draw(){
    background(255);
    layer1.beginDraw();
    layer1.stroke(0, 102, 153);
    layer1.endDraw();
    image(layer1, 0, 0); 
}

void keyPressed() {
  if (key == '1') {
    println("making the line");
    layer1.beginDraw();
    layer1.line(0,10,200,200);
    layer1.endDraw();
  }else if (key == '2') {
    toggleVis();
  }
}

void mousePressed() {
  layer1.beginDraw(); 
  layer1.clear();
  layer1.endDraw(); 
}
void toggleVis(){
   if (transparent1==true) {
      println("showing the line");
      layer1.beginDraw();
      layer1.loadPixels();
      layer1bak.loadPixels(); 
      arrayCopy(layer1bak.pixels, layer1.pixels); 
      layer1.updatePixels();  
      layer1.endDraw();
      //transparent1=false;
    
   }else{
      println("hiding the line");
      layer1bak = createGraphics(layer1.width, layer1.height, JAVA2D); 
      layer1bak.beginDraw();
      layer1.loadPixels();
      layer1bak.loadPixels(); 
      arrayCopy(layer1.pixels, layer1bak.pixels); 
      layer1bak.updatePixels();  
      layer1bak.endDraw();
      layer1.beginDraw();
      layer1.clear();
      layer1.endDraw();
      //transparent1=true;
   }
   
   transparent1 = !transparent1;//toggles the boolean
}

Hi PerryJohnson,

You could store your PGraphics objects in a data structure then use that data structure’s functions to toggle through your layers. Any tutorial on Java’s collections library may help you find the one that best suits your needs.

It might also help to distinguish the functions that switch between layers from the functions that change the content of a certain layer (loading, copying, and clearing pixels).

import java.util.Deque;
import java.util.LinkedList;
import processing.awt.PGraphicsJava2D;

// Number of layers to load into queue in setup.
int count = 5;

// Declare a data structure to hold multiple layers,
// for example a double-ended queue interface which
// uses a linked list implementation.
Deque<PGraphics> layers = new LinkedList<PGraphics>();

void setup() {
  size(512, 256);

  // The default renderer is excluded from
  // this example, but to include it, reference g.
  // PGraphics baseLayer = g;

  float centerY = height * 0.5;
  float rad = min(width, height) * 0.5;
  float iToStep = 1.0 / float(count - 1);

  // Create initial listing of layers.
  for (int i = 0; i < count; ++i) {

    // Create renderer.
    // PGraphics is an interface returned by the createGraphics function;
    // PGraphicsJava2D is the implementation which depends on Java's AWT library.
    PGraphicsJava2D current = (PGraphicsJava2D)createGraphics(width, height, JAVA2D);

    // Draw whatever.
    current.beginDraw();

    // Draw circle.
    float step = i * iToStep;
    float centerX = lerp(rad, width - rad, step);
    current.ellipseMode(RADIUS);
    current.noStroke();
    current.fill(lerpColor(0xffff0000, 0xff0000ff, step));
    current.ellipse(centerX, centerY, rad, rad);

    // Draw text label.
    String label = String.format("LAYER %d", i);
    current.textSize(30);
    current.textAlign(CENTER, CENTER);
    current.fill(0xffffffff);
    current.text(label, centerX, centerY);
    current.endDraw();

    // Add PGraphics to the double-ended queue.
    layers.add(current);
  }
}

void draw() {
  background(0xffffffff);

  // Display current layer(s).
  PGraphics current = layers.getLast();
  image(current, 0.0, 0.0);
}

void mouseReleased() {
  
  // Toggle layers.
  layers.addLast(layers.removeFirst());
}
1 Like

One possible approach, out of many. Does it help?

Kf

PGraphics layer1;
PGraphics layer2;

PGraphics pg;


//boolean transparent1 = false;

void setup() {
  size(600, 400);
  layer1 = createGraphics(width, height);
  layer2 = createGraphics(width, height);
  background(255);
  stroke(0);
  
  surface.setTitle("Press either 1 or 2 to show line, mouse click to clear");

  layer1.beginDraw();
  layer1.stroke(0, 102, 153);
  layer1.line(0, 10, 200, 200);
  layer1.endDraw();
  
  layer2.beginDraw();
  layer2.stroke(200, 102, 10);
  layer2.strokeWeight(5);
  layer2.line(200, 10, 0, 200);
  layer2.endDraw();
}

void draw() {
  background(255);
  
  if(pg!=null)
  image(pg, 0, 0);
}

void keyPressed() {
  if (key == '1') {
    pg=layer1;
  }   else if (key == '2') {
    pg=layer2;
  }
}

void mousePressed() {
  
  pg=null;
}

Thanks to those who replied. Ultimately I ended up going this way, setting up three arrays - layers, layersOff, and layersTransparency and then when I’m working with them I can access them simply by number.

PGraphics[] layers = new PGraphics[5];
PGraphics[] layersOff = new PGraphics[5];
boolean[] layersTransparency = new boolean[5];

boolean isShiftDown, isCtrlDown, isAltDown;

void setup() {
  size(400, 600);
  for (int i = 0; i < layers.length; i++) {
    layers[i] = createGraphics(width, height);
    layersTransparency[i] = false;
  }
  background(255);
  stroke(0);
}

void draw(){
  background(255);
  for (int i = 0; i < layers.length; i++) {
    layers[i].beginDraw();
    layers[i].endDraw();
    image(layers[i],0,0);
  }
}

void keyPressed() {
  setKey(keyCode, true);
  if (key == 'x') {
    layers[1].beginDraw();
    layers[1].line(0,10,200,200);
    layers[1].endDraw();
    
    layers[2].beginDraw();
    layers[2].rect(100,100,200,200);
    layers[2].endDraw();
    
    layers[3].beginDraw();
    layers[3].ellipse(100,100,200,200);
    layers[3].endDraw();
    
  }else if (key == '1') {
    if(isCtrlDown){
      toggleVis(1);
    }else{
      // regular keyboard shortcut, could be brush selection 
    }
  }else if (key == '2') {
    if(isCtrlDown){
      toggleVis(2);
    }else{
      // regular keyboard shortcut, could be brush selection 
    }
  }else if (key == '3') {
    if(isCtrlDown){
      toggleVis(3);
    }else{
      // regular keyboard shortcut, could be brush selection 
    }
  }
}

void keyReleased() {
  setKey(keyCode, false);
}

void setKey(int k, boolean bool) {
  if      (k == SHIFT)    isShiftDown = bool;
  else if (k == CONTROL)  isCtrlDown  = bool;
  else if (k == ALT)      isAltDown   = bool;
}

void mousePressed() {
  layers[0].beginDraw(); 
  layers[0].clear();
  layers[0].endDraw(); 
}
void toggleVis(int layer){
   if (layersTransparency[layer]==true) {
      layers[layer].beginDraw();
      layers[layer].loadPixels();
      layersOff[layer].loadPixels(); 
      arrayCopy(layersOff[layer].pixels, layers[layer].pixels); 
      layers[layer].updatePixels();  
      layers[layer].endDraw();
   }else{
      layersOff[layer] = createGraphics(layers[layer].width, layers[layer].height, JAVA2D); 
      layersOff[layer].beginDraw();
      layers[layer].loadPixels();
      layersOff[layer].loadPixels(); 
      arrayCopy(layers[layer].pixels, layersOff[layer].pixels); 
      layersOff[layer].updatePixels();  
      layersOff[layer].endDraw();
      layers[layer].beginDraw();
      layers[layer].clear();
      layers[layer].endDraw();
   }
   
   layersTransparency[layer] = !layersTransparency[layer];//toggles the boolean
}

1 Like