# Closing a second window

**URL:** <https://discourse.processing.org/t/closing-a-second-window/381>\
**Category:** Coding Questions\
**Created:** [May 25, 2018, 7:55pm UTC](https://discourse.processing.org/t/closing-a-second-window/381 "2018-05-25T19:55:02Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![lmccandless](https://avatars.discourse-cdn.com/v4/letter/l/f0a364/32.png) [@lmccandless](https://discourse.processing.org/u/lmccandless)\
**Post date:** [May 25, 2018, 7:55pm UTC](https://discourse.processing.org/t/closing-a-second-window/381/1 "2018-05-25T19:55:02Z")

</div>

I want to be able to create a second window. The problem is I want the user to be able to close the second window, but doing so closes both the second and main frame. Is there a way I can prevent this?

```auto
PWindow win;

public void settings() {
  size(320, 240);
}

void setup() { 
  win = new PWindow();
}

void draw() {
  background(255, 0, 0);
  fill(255);
  rect(10, 10, frameCount, 10);
}

void mousePressed() {
  println("mousePressed in primary window");
} 

class PWindow extends PApplet {
  PWindow() {
    super();
    PApplet.runSketch(new String[] {this.getClass().getSimpleName()}, this);
  }

  void settings() {
    size(500, 200);
  }

  void setup() {
    background(150);
  }

  void draw() {
    ellipse(random(width), random(height), random(50), random(50));
  }

  void mousePressed() {
    println("mousePressed in secondary window");
  }
}

```

---

<div class="post-metadata">

**Author:** ![colouredmirrorball](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/colouredmirrorball/32/234_2.png) [@colouredmirrorball](https://discourse.processing.org/u/colouredmirrorball)\
**Post date:** [May 25, 2018, 8:02pm UTC](https://discourse.processing.org/t/closing-a-second-window/381/2 "2018-05-25T20:02:12Z")

</div>

This did the trick for me:

```auto

PWindow win;

public void settings() {
  size(320, 240);
}

void setup() { 
  surface.setLocation(20,20);
  win = new PWindow();
}

void draw() {
  background(255, 0, 0);
  fill(255);
  rect(10, 10, frameCount, 10);
}

void mousePressed() {
  println("mousePressed in primary window");
  if(win == null) win = new PWindow();
} 

class PWindow extends PApplet {
  PWindow() {
    super();
    PApplet.runSketch(new String[] {this.getClass().getSimpleName()}, this);
  }

  void settings() {
    size(500, 200);
  }

  void setup() {
    background(150);
  }

  void draw() {
    ellipse(random(width), random(height), random(50), random(50));
  }

  void mousePressed() {
    println("mousePressed in secondary window");
  }
  
  void exit()
  {
    dispose();
    win = null;
  }
}

```

Clicking in the first window when the second is closed will also open a new secondary window.

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [May 25, 2018, 8:16pm UTC](https://discourse.processing.org/t/closing-a-second-window/381/3 "2018-05-25T20:16:17Z")

</div>

- [https://Forum.Processing.org/two/discussion/17310/intercept-window-closure-in-p2d-renderer-processing-3#Item\_5](https://Forum.Processing.org/two/discussion/17310/intercept-window-closure-in-p2d-renderer-processing-3#Item_5)

---

<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:** [May 25, 2018, 9:05pm UTC](https://discourse.processing.org/t/closing-a-second-window/381/4 "2018-05-25T21:05:22Z")

</div>

Above link gives the example `SetDefaultCloseEvent` sketch, which uses `jogamp.newt.Window.setDefaultCloseOperation()` to set a default close policy.

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [May 25, 2018, 9:45pm UTC](https://discourse.processing.org/t/closing-a-second-window/381/5 "2018-05-25T21:45:46Z")

</div>

Actually, what is passed to **setDefaultCloseOperation()** is either the enums from `com.jogamp.nativewindow.WindowClosingProtocol.WindowClosingMode`:

[http://JogAmp.org/deployment/jogamp-next/javadoc/jogl/javadoc/com/jogamp/nativewindow/WindowClosingProtocol.WindowClosingMode.html](http://JogAmp.org/deployment/jogamp-next/javadoc/jogl/javadoc/com/jogamp/nativewindow/WindowClosingProtocol.WindowClosingMode.html)

Or the constants from interface `javax.swing.WindowConstants`:

[https://Docs.Oracle.com/javase/10/docs/api/javax/swing/WindowConstants.html](https://Docs.Oracle.com/javase/10/docs/api/javax/swing/WindowConstants.html)

Depending on the result of PGraphics::**isGL()** method. 🧐

---

<div class="post-metadata">

**Author:** ![colouredmirrorball](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/colouredmirrorball/32/234_2.png) [@colouredmirrorball](https://discourse.processing.org/u/colouredmirrorball)\
**Post date:** [May 25, 2018, 9:46pm UTC](https://discourse.processing.org/t/closing-a-second-window/381/6 "2018-05-25T21:46:59Z")

</div>

Wouldn’t that prevent the user from closing the second window?

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [May 25, 2018, 9:51pm UTC](https://discourse.processing.org/t/closing-a-second-window/381/7 "2018-05-25T21:51:15Z")

</div>

[https://Docs.Oracle.com/javase/tutorial/uiswing/components/frame.html#windowevents](https://Docs.Oracle.com/javase/tutorial/uiswing/components/frame.html#windowevents)

---

<div class="post-metadata">

**Author:** ![colouredmirrorball](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/colouredmirrorball/32/234_2.png) [@colouredmirrorball](https://discourse.processing.org/u/colouredmirrorball)\
**Post date:** [May 25, 2018, 10:11pm UTC](https://discourse.processing.org/t/closing-a-second-window/381/8 "2018-05-25T22:11:40Z")

</div>

Ah, I get it now. It makes the window invisible, and pauses the sketch but it can be made visible again easily.

OP is essentially running two PApplets on the same JVM. My method terminates the secondary sketch but keeps the JVM open so the primary one can stay running.

So OP has the choice - either terminate one sketch entirely or keep it invisibly running and call it back fast when needed.

This is the code I came up with. There appears to be an issue when you close the primary sketch while the secondary sketch is still running, it crashes with the error “ThreadDeath”.

```auto
PWindow win;

public void settings() {
  size(320, 240);
}

void setup() { 
  surface.setLocation(20, 20);
  win = new PWindow();
}

void draw() {
  background(255, 0, 0);
  fill(255);
  rect(10, 10, frameCount, 10);
}

void mousePressed() {
  println("mousePressed in primary window");
  win.makeVisible();
} 

class PWindow extends PApplet {
  static final String RENDERER = P3D;
  PWindow() {
    super();
    PApplet.runSketch(new String[] {this.getClass().getSimpleName()}, this);
  }

  void settings() {
    size(500, 200, RENDERER);
  }

  void setup() {
    background(150);
    setDefaultClosePolicy(this, false);
  }

  void draw() {
    ellipse(random(width), random(height), random(50), random(50));
    println("running!", frameCount);
  }

  void mousePressed() {
    println("mousePressed in secondary window");
  }

  void exit()
  {
    dispose();
    win = null;
  }

  final void setDefaultClosePolicy(PApplet pa, boolean keepOpen) {
    final Object surf = pa.getSurface().getNative();
    final PGraphics canvas = pa.getGraphics();

    if (canvas.isGL()) {
      final com.jogamp.newt.Window w = (com.jogamp.newt.Window) surf;

      for (com.jogamp.newt.event.WindowListener wl : w.getWindowListeners())
        if (wl.toString().startsWith("processing.opengl.PSurfaceJOGL"))
          w.removeWindowListener(wl); 

      w.setDefaultCloseOperation(keepOpen?
        com.jogamp.nativewindow.WindowClosingProtocol.WindowClosingMode
        .DO_NOTHING_ON_CLOSE :
        com.jogamp.nativewindow.WindowClosingProtocol.WindowClosingMode
        .DISPOSE_ON_CLOSE);
    } else if (canvas instanceof processing.awt.PGraphicsJava2D) {
      final javax.swing.JFrame f = (javax.swing.JFrame)
        ((processing.awt.PSurfaceAWT.SmoothCanvas) surf).getFrame(); 

      for (java.awt.event.WindowListener wl : f.getWindowListeners())
        if (wl.toString().startsWith("processing.awt.PSurfaceAWT"))
          f.removeWindowListener(wl);

      f.setDefaultCloseOperation(keepOpen?
        f.DO_NOTHING_ON_CLOSE : f.DISPOSE_ON_CLOSE);
    }
  }
  
  public void makeVisible()
  {
    surface.setVisible(true);

  }
}

```

---

<div class="post-metadata">

**Author:** ![lmccandless](https://avatars.discourse-cdn.com/v4/letter/l/f0a364/32.png) [@lmccandless](https://discourse.processing.org/u/lmccandless)\
**Post date:** [May 25, 2018, 10:43pm UTC](https://discourse.processing.org/t/closing-a-second-window/381/9 "2018-05-25T22:43:44Z")

</div>

For my application hiding the second window is preferred to terminating it, thanks guys

I’m also running into an issue where I want to apply a shader filter to both windows.  
Both are set to use P2D. The second window sporadically crashes with errors when trying to do things like filter(blur) using the blur shader from the example /topics/shader/blurfilter

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [May 25, 2018, 10:46pm UTC](https://discourse.processing.org/t/closing-a-second-window/381/10 "2018-05-25T22:46:14Z")

</div>

That PWindow::**exit()** method is never called back.  
Instead, move that **exit()** to the main sketch PApplet in order to avoid that “ThreadDeath”:

```java
@Override void exit() {
  win.dispose();
  super.exit();
}

```

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [May 25, 2018, 10:50pm UTC](https://discourse.processing.org/t/closing-a-second-window/381/11 "2018-05-25T22:50:56Z")

</div>

> [@lmccandless](#):
>
> … crashes with errors when trying to do things like `filter(blur);`…

Never mutate a PApplet’s PGraphics main canvas outside its own “Animation Thread”! 👺

---

<div class="post-metadata">

**Author:** ![lmccandless](https://avatars.discourse-cdn.com/v4/letter/l/f0a364/32.png) [@lmccandless](https://discourse.processing.org/u/lmccandless)\
**Post date:** [May 25, 2018, 10:53pm UTC](https://discourse.processing.org/t/closing-a-second-window/381/12 "2018-05-25T22:53:33Z")

</div>

I am doing it inside the new PApplet’s draw(){}, is that not the right location?

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [May 25, 2018, 10:56pm UTC](https://discourse.processing.org/t/closing-a-second-window/381/13 "2018-05-25T22:56:43Z")

</div>

Yes, for its own main canvas… 🤨

However, if you try to mutate the other PApplet’s main canvas from there, it’s gonna crash! 👻

---

<div class="post-metadata">

**Author:** ![lmccandless](https://avatars.discourse-cdn.com/v4/letter/l/f0a364/32.png) [@lmccandless](https://discourse.processing.org/u/lmccandless)\
**Post date:** [May 25, 2018, 11:19pm UTC](https://discourse.processing.org/t/closing-a-second-window/381/14 "2018-05-25T23:19:03Z")

</div>

> **[lmccandless/repixel3](https://github.com/lmccandless/repixel3)**
>
> Tool for recoloring pixel art made in Processing 3 - lmccandless/repixel3

Here is my project, kind of in an early development stage right now. The idea is you left click to select a color from the spritesheet(or group of squares on the left), and rightclick to replace that color with whatever color is under the mouse pointer.

I’m trying to apply my PShader called highlight to both frames.

If you run the program, toggle the box labeled highlight, and left click on the spritesheet or the colored squares on the left, you’ll see my shader highlight the pixels and it all works fine.

Then if you click the histogram button, it opens the new window, and things get screwy. White and black random rectangles and sometimes GL errors. The filter is applied to the new window on line 53 of histogram.pde. If highlight is disabled, it works fine.

Usually but not always the error is GLException: array vertex\_buffer\_object must be bound to call this method

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [May 26, 2018, 1:14am UTC](https://discourse.processing.org/t/closing-a-second-window/381/15 "2018-05-26T01:14:21Z")

</div>

> [@lmccandless](#):
>
> The filter is applied to the new window on line 53 of “histogram.pde”.

So basically you’re invoking **filter()**, passing the PShader loaded & created by the main PApplet on the canvas of the 2nd PApplet.

I know close to nothing about “.glsl” files, but is it feasible for each PApplet to have its own PShader of that same “.glsl” file?

If not, maybe create an extra PGraphics on the 1st PApplet.  
But exclusively use that PGraphics on the 2nd PApplet.  
Perhaps then you can call **filter()** over that PGraphics inside the 2nd PApplet.

---

<div class="post-metadata">

**Author:** ![GeorgeJava](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/georgejava/32/7646_2.png) [@GeorgeJava](https://discourse.processing.org/u/GeorgeJava)\
**Post date:** [December 4, 2019, 4:36pm UTC](https://discourse.processing.org/t/closing-a-second-window/381/16 "2019-12-04T16:36:16Z")

</div>

When i add super.exit to second PApplet it close both Windows…

---

<div class="post-metadata">

**Author:** ![kfrajer](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kfrajer/32/196_2.png) [@kfrajer](https://discourse.processing.org/u/kfrajer)\
**Post date:** [December 8, 2019, 8:14pm UTC](https://discourse.processing.org/t/closing-a-second-window/381/17 "2019-12-08T20:14:08Z")

</div>

Please show your code or a minimum version demonstrating your approach.

Kf

---

<div class="post-metadata">

**Author:** ![Lexyth](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/lexyth/32/7403_2.png) [@Lexyth](https://discourse.processing.org/u/Lexyth)\
**Post date:** [December 8, 2019, 9:19pm UTC](https://discourse.processing.org/t/closing-a-second-window/381/18 "2019-12-08T21:19:10Z")

</div>

This is where the question was resolved. @kfrajer

> [@PApplet second win exit, create ... RAM overfill](https://discourse.processing.org/t/papplet-second-win-exit-create-ram-overfill/16090/5):
>
> Ok, i keep going with javax swing, i wanted to create a setting windows… smiley
