Create a new window/PApplet from another PApplet

I stumbled upon a way to easily spawn new windows from Processing and couldn't find it anywhere else so I thought I'd post it here. Unsure if it's the best way but it appears to be working. Feedback and improvements appreciated. This will only work for Processing 3.

First tab, for the demo to work right out of the box this sketch has to be called "SecondWindowTest"

/**
 * Demo on how to spawn a second sketch from Processing
 * Facilitated by ControlP5, but not necessary for this purpose
 * by CMB, 2016
 *
 */



import controlP5.*;

ControlP5 cp5;

//Reference to the secondary sketch so we can call its methods and access its variables from outside
SecondSketch second;

//This value will be accessed by the other sketch
int backgroundValue = 0;

public void settings()
{
  size(800, 600);
}

public void setup()
{
  surface.setResizable(true);

  cp5 = new ControlP5(this);

  cp5.addButton("secondWindow")
    .setPosition(20, 20)
    .setSize(125, 25)
    .setLabel("Second Window")
    .getCaptionLabel().alignY(CENTER).alignX(CENTER);

  cp5.addTextfield("textField")
    .setSize(125, 25)
    .setPosition(20, 75);
}

public void draw()
{
  background(backgroundValue);
}

public void secondWindow()
{
  //Launch the other sketch!

  //This structure assumes you only want one instance of the other sketch
  //If that's not what you want simply call the constructor to launch a new, independent instance

  //if the other sketch is closed, start a new one
  if (second== null) second = new SecondSketch(this);
  else
  {
    //if it's already running, bring it to the front
    second.moveToTop();
  }
}

public void textField(String input)
{
  //Send some text to the other sketch
  if (second != null)
  {
    second.someText = input;
  }
}

Second tab

//Code in this class like in any other sketch
//However, this class can't have any nested classes like a regular sketch:
//if you want to use another class inside this secondary sketch and draw in it,
//you gotta pass it a reference to this class and draw on its internal PGraphics "g"
class SecondSketch extends PApplet
{
  //A reference to the main sketch
  //notice how the file name of the main sketch is important as that becomes the name of the class upon compiling
  SecondWindowTest parent;

  ControlP5 gui;

  //This String will be sent to us from the main sketch
  String someText= "";

  //The constructor will take care of everything
  public SecondSketch(SecondWindowTest parent)
  {
    //store a reference to the first sketch so we can do things with it
    this.parent = parent;

    //This will actually launch the new sketch
    runSketch(new String[] {
      "SecondSketch"  //must match the name of this class
      }
      , this);  //the second argument makes sure this sketch is created instead of a brand new one...
  }

  public void settings()
  {
    size(700, 500);
  }

  public void setup()
  {

    super.surface.setResizable(true);

    //give it some GUI to interact with
    gui = new ControlP5(this);
    gui.addSlider("mainBackground")
      .setRange(0, 255)
      .setPosition(20, 50)
      .setLabel("Main sketch background colour")
      .setSize(125, 25);
  }

  public void draw()
  {
    background(50);
    fill(255);

    //Display the text that can be altered from the main sketch
    text(someText, 20, 20);
  }

  //Without this, the main sketch would close if the user clicked on the second sketch' close button!
  //(it appears to work funky with the escape button though, beware)
  public void exit()
  {
    parent.second = null;
    dispose();
  }

  //Callback from ControlP5
  public void mainBackground(float value)
  {
    //Change main sketch' background value
    parent.backgroundValue = (int) value;
  }

  //Little hack to bring the frame to the top
  public void moveToTop()
  {
    surface.setAlwaysOnTop(true);
    surface.setAlwaysOnTop(false);
  }
}

Comments

  • Since you are just having another tab, the Processing pre processor just puts the class inside the main class. So why do you need to reference the variables of the main class with parent.variableName?

  • You are correct: it's not needed in this case. I found this out by working in another IDE and it's a relict from that.

    Still it could be useful if you have variables that share name across the two sketches. Now you can access parent.mouseX and parent.mouseY in addition to mouseX and mouseY in the secondary sketch, for example. For this reason I'm going to leave the code like it is, but it works fine without a reference to parent (you can do backgroundValue = (int) value, and so on).

  • Since all you need are the basic, predefined variables, you can use a PApplet as parent instead of the name of the main class.

Sign In or Register to comment.