# G4P Close Window Vs Hide Window

**URL:** <https://discourse.processing.org/t/g4p-close-window-vs-hide-window/44761>\
**Category:** Libraries\
**Created:** [July 12, 2024, 6:37pm UTC](https://discourse.processing.org/t/g4p-close-window-vs-hide-window/44761 "2024-07-12T18:37:37Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Thundercat](https://avatars.discourse-cdn.com/v4/letter/t/dbc845/32.png) [@Thundercat](https://discourse.processing.org/u/Thundercat)\
**Post date:** [July 12, 2024, 6:37pm UTC](https://discourse.processing.org/t/g4p-close-window-vs-hide-window/44761/1 "2024-07-12T18:37:37Z")

</div>

Hi Peter, This was discussed in [another threa](https://discourse.processing.org/t/g4p-java-concurrent-modification-exception-error-when-exit-called/44532/25)d, but I felt it needed its own dedicated thread.

I want to be able to handle when a user clicks the “x” button to close a GWindow, and also be able to “hide” it using a button if they click the button.

I’ve added a close handler, but it does not trigger when the “x” is clicked on a GWindow. Neither does it trigger when the window is hidden.

Here’s an example:

```auto
// Need G4P library
import g4p_controls.*;
// You can remove the PeasyCam import if you are not using
// the GViewPeasyCam control or the PeasyCam library.
import peasy.*;

GWindow window = null;
GButton button0; 

public void setup(){
  size(480, 320, JAVA2D);
  createGUI();
  customGUI();
  // Place your setup code here
  
}

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

// Use this method to add additional statements
// to customise the GUI controls
public void customGUI(){

}

void showGWindow() {
  
  if (window == null) {
    window = GWindow.getWindow(this, "Title", 100, 100, 200, 100, JAVA2D);
    window.setAlwaysOnTop(true);
    window.setActionOnClose(G4P.HIDE_WINDOW);//CLOSE_WINDOW//HIDE_WINDOW
    //window.addMouseHandler(this, "windowMouse");
    //window.addKeyHandler(this, "windowKey");
    window.addDrawHandler(this, "windowDraw"); 
    window.addOnCloseHandler(this, "windowClose");
    
    button0 = new GButton(window, 50, 20, 80, 30);
    button0.setText("OK");
    button0.addEventHandler(this, "button0_click1");
  }
  else {
    window.setVisible(true);
    println("not null");
  }
  
}//showGWindow

void windowDraw(PApplet app, GWinData data) {

}

void button0_click1(GButton source, GEvent event) {
  window.setVisible(false);  
}

public void windowClose(GWindow source){
  println("windowClose called!");     
}

/* =========================================================
 * ==== WARNING ===
 * =========================================================
 * The code in this tab has been generated from the GUI form
 * designer and care should be taken when editing this file.
 * Only add/edit code inside the event handlers i.e. only
 * use lines between the matching comment tags. e.g.

 void myBtnEvents(GButton button) { //_CODE_:button1:12356:
     // It is safe to enter your event code here  
 } //_CODE_:button1:12356:
 
 * Do not rename this tab!
 * =========================================================
 */

public void button3_click1(GButton source, GEvent event) { //_CODE_:button3:413930:
  println("button3 - GButton >> GEvent." + event + " @ " + millis());
  showGWindow();
} //_CODE_:button3:413930:

// Create all the GUI controls. 
// autogenerated do not edit
public void createGUI(){
  G4P.messagesEnabled(false);
  G4P.setGlobalColorScheme(GCScheme.BLUE_SCHEME);
  G4P.setMouseOverEnabled(false);
  surface.setTitle("Sketch Window");
  button3 = new GButton(this, 197, 145, 80, 30);
  button3.setText("open win");
  button3.addEventHandler(this, "button3_click1");
}

// Variable declarations 
// autogenerated do not edit
GButton button3; 

```

What I’d like is to be able to trap for both situations, when the user clicks the “x” on the OS dialog box window, or when the button OK is clicked.

Is there a way to handle this correctly?

Thanks,

Mike

---

<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:** [July 13, 2024, 3:43pm UTC](https://discourse.processing.org/t/g4p-close-window-vs-hide-window/44761/2 "2024-07-13T15:43:10Z")

</div>

> [@Thundercat](#):
>
> I want to be able to handle when a user clicks the “x” button to close a GWindow, and also be able to “hide” it using a button if they click the button.

Worked for me with your code.

> [@Thundercat](#):
>
> I’ve added a close handler, but it does not trigger when the “x” is clicked on a GWindow. Neither does it trigger when the window is hidden.

The close handler method is _ **only called** _ when the window is closed i.e. the action on close is CLOSE\_WINDOW. If action on close is HIDE\_WINDOW or KEEP\_OPEN then the close handler is not closed. The hint is in the function name 😀

Having said that your code also worked as expected.

I have refactored uour code and renamed some things to make it easier to follow. Here it is -

```auto
import g4p_controls.*;
import java.awt.Font;

GWindow window = null;
GButton btnOpenWindow, btnCloseWindow, btnAction;

int what_to_do_on_close = G4P.CLOSE_WINDOW ; //HIDE_WINDOW//KEEP_OPEN;

public void setup() {
  size(480, 320, JAVA2D);
  G4P.setDisplayFont ("Arial", Font.PLAIN, 16);
  createGUI();
  fill(0);
  textSize(16);
  textAlign(CENTER, CENTER);
}

public void draw() {
  background(230);
  String actionText = "UNDEFINED";
  switch(what_to_do_on_close) {
  case G4P.CLOSE_WINDOW:
    actionText = "CLOSE_WINDOW";
    break;
  case G4P.HIDE_WINDOW:
    actionText = "HIDE_WINDOW";
    break;
  case G4P.KEEP_OPEN:
    actionText = "KEEP_OPEN";
    break;
  }
  text("Action when trying to close window", 0, 10, width, 50);
  text(actionText, 0, 40, width, 50);
}

public void showGWindow() {
  if (window == null) {
    window = GWindow.getWindow(this, "Title", 400, 300, 300, 120, JAVA2D);
    window.setAlwaysOnTop(true);
    // Change 'what_to_do_on_close' above
    window.setActionOnClose(what_to_do_on_close);
    //window.addMouseHandler(this, "windowMouse");
    //window.addKeyHandler(this, "windowKey");
    window.addDrawHandler(this, "windowDraw");
    window.addOnCloseHandler(this, "windowCloseAction");

    btnAction = new GButton(window, 50, 70, 120, 30);
    btnAction.setText("HIDE window");
    btnAction.addEventHandler(this, "btnAction_Click");
    println("Create window");
  } else {
    window.setVisible(true);
    println("Make window visible");
  }
}//showGWindow

public void windowDraw(PApplet app, GWinData data) {
  app.background(200, 255, 200);
}

public void btnAction_Click(GButton source, GEvent event) {
  System.out.println("Hiding window");
  window.setVisible(false);
}

public void windowCloseAction(GWindow source) {
  println("windowCloseAction called!");
  window = null;
}

public void btnOpenWindow_Click(GButton source, GEvent event) {
  showGWindow();
}

public void btnCloseWindow_Click(GButton source, GEvent event) {
  println("Close window button clicked");
  window.close();
}

public void createGUI() {
  G4P.messagesEnabled(false);
  G4P.setGlobalColorScheme(GCScheme.BLUE_SCHEME);
  G4P.setMouseOverEnabled(false);
  surface.setTitle("Sketch Window");
  btnOpenWindow = new GButton(this, 60, 145, 160, 30);
  btnOpenWindow.setText("OPEN window");
  btnOpenWindow.addEventHandler(this, "btnOpenWindow_Click");
  btnCloseWindow = new GButton(this, 260, 145, 160, 30);
  btnCloseWindow.setText("CLOSE window");
  btnCloseWindow.addEventHandler(this, "btnCloseWindow_Click");
}

```

---

<div class="post-metadata">

**Author:** ![Thundercat](https://avatars.discourse-cdn.com/v4/letter/t/dbc845/32.png) [@Thundercat](https://discourse.processing.org/u/Thundercat)\
**Post date:** [July 13, 2024, 8:35pm UTC](https://discourse.processing.org/t/g4p-close-window-vs-hide-window/44761/3 "2024-07-13T20:35:11Z")

</div>

Hi Peter, indeed your solution works by changing that one line of code to CLOSE\_WINDOW. And your code is also cleaner; thank you for that.

I had tried that before and yes it works - but then subsequent opens of the window render the button dead (as well as any controls that could have been added). This you explained is expected behavior with the CLOSE\_WINDOW method, in the previous post (thank you for that).

I realize I am pushing against the philosophy and design of the situation here, so I don’t know if there’s a solution then.

Because I want to be able to show/hide the windows, so that subsequent reopens of the windows allow all the controls to remain operational, if I use the CLOSE\_WINDOW method then the controls are all dead. Which is what I need to avoid. That’s why I was using the HIDE\_WINDOW method.

Is there any other way to trap for the close “X” OS button other than the CLOSE\_WINDOW method? I realize even typing this that it sounds foolish.

If I could just get the window controls to remain viable after a user clicks the “X” (and then reopens the window) that would be amazing.

Alternately, If I were to totally “dispose” of the windows (not sure how), could I recreate them each time with the same name, or they would not ever work again?

Again this goes back to the attempt at messaging, which you told me to stop coding everything else and focus on it, which I’m doing now.

I don’t think the GPanels are going to cut it because they are so different from regular OS messaging boxes, although they are cool. I suppose I could make them work, but again, I’m trying to create an app that looks similar to expected OS apps as much as possible.

Thank you for your time - sincerely - thank you so much for the incredible amount of time you’ve spent helping me here, regardless the outcome.

I so appreciate you.

All the best,

Mike

---

<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:** [July 14, 2024, 9:29am UTC](https://discourse.processing.org/t/g4p-close-window-vs-hide-window/44761/4 "2024-07-14T09:29:03Z")

</div>

Some things to make clear first

1. CLOSE\_WINDOW, HIDE\_WINDOW and KEEP\_OPEN are _ **not** _ methods, they are simple integer constants used as flags.
2. the `setActionOnClose(...)` method indicates which of the actions from (1) should be attempted when
  - the OS’s close button (X for Windows; red circle for osx) is clicked
  - the G4P library method `window.close()` method is called.

3. The G4P library method `window.forceClose()` ignores the flag and closes the window respectively.

> [@Thundercat](#):
>
> If I could just get the window controls to remain viable after a user clicks the “X” (and then reopens the window) that would be amazing.

Once a window is closed that’s it, all the controls are closed as well. There is nothing you can do but recreate the window from scratch. If you look at your `showGWindow` method the solution becomes clear.

The window is created if the window reference is `null`, so changing the reference to `null` when the window closes will solve your problem. So two step

1. Create a close handler method with `addOnCloseHandler`
2. In the on-close-handler method specified in (1) add a statement to nullify the window reference.

I have changed the sketch code in my last post to simplify testing what I have side in this post.

```auto
// This is the method specified in the call to
// addOnCloseHandler(method_name)
public void windowCloseAction(GWindow source) {
  println("windowCloseAction called!");
  window = null;
}

```

---

<div class="post-metadata">

**Author:** ![Thundercat](https://avatars.discourse-cdn.com/v4/letter/t/dbc845/32.png) [@Thundercat](https://discourse.processing.org/u/Thundercat)\
**Post date:** [July 14, 2024, 12:17pm UTC](https://discourse.processing.org/t/g4p-close-window-vs-hide-window/44761/5 "2024-07-14T12:17:47Z")

</div>

Peter I am so grateful for your time and expertise - honestly I can’t thank you enough 🥰

I’m still working my way through your updated example, but do get a null pointer error when clicking the Close Window button:

```auto
################ EXCEPTION IN EVENT HANDLER ################
An error occured during execution of the eventhandler:
CLASS: sketch_240714a METHOD: btnCloseWindow_Click
	Caused by java.lang.NullPointerException: Cannot invoke "g4p_controls.GWindow.close()" because "this.window" is null
	sketch_240714a.btnCloseWindow_Click(sketch_240714a.java:97)
	java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	java.base/java.lang.reflect.Method.invoke(Method.java:568)
	g4p_controls.GAbstractControl.fireEvent(Unknown Source)
	g4p_controls.GButton.mouseEvent(Unknown Source)
	g4p_controls.GWindowImpl.mouseEvent(Unknown Source)
	jdk.internal.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
	java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	java.base/java.lang.reflect.Method.invoke(Method.java:568)
	processing.core.PApplet$RegisteredMethods.handle(PApplet.java:1309)
	processing.core.PApplet.handleMethods(PApplet.java:1456)
	processing.core.PApplet.handleMouseEvent(PApplet.java:2368)
	processing.core.PApplet.dequeueEvents(PApplet.java:2261)
	processing.core.PApplet.handleDraw(PApplet.java:2104)
	processing.awt.PSurfaceAWT$9.callDraw(PSurfaceAWT.java:1386)
	processing.core.PSurfaceNone$AnimationThread.run(PSurfaceNone.java:356)
##############################################################

```

In any case I’m going to spend more time with your example and again thank you so much 👏 💓 🤩

EDIT: I just changed the action on the btnCloseWindow:

```auto
public void btnCloseWindow_Click(GButton source, GEvent event) {
  println("Close window button clicked");
  if (window != null) window.close();
}

```

No null pointer error now.

Thank you again so much!

---

<div class="post-metadata">

**Author:** ![Thundercat](https://avatars.discourse-cdn.com/v4/letter/t/dbc845/32.png) [@Thundercat](https://discourse.processing.org/u/Thundercat)\
**Post date:** [July 14, 2024, 12:21pm UTC](https://discourse.processing.org/t/g4p-close-window-vs-hide-window/44761/6 "2024-07-14T12:21:36Z")

</div>

By the way are there any memory concerns with this method - will this become a resource hog with using this for lots of windows?

Also, is there any way to add the `window.addOnCloseHandler(this, "windowCloseAction");` to the main sketch window as well? That way I could trap for the whole sketch being closed with the “X” as well…

Thanks again! You’re so kind.

Mike

---

<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:** [July 14, 2024, 1:12pm UTC](https://discourse.processing.org/t/g4p-close-window-vs-hide-window/44761/7 "2024-07-14T13:12:37Z")

</div>

> [@Thundercat](#):
>
> EDIT: I just changed the action on the btnCloseWindow:

Attempting to close a window that no longer exists. Well spotted 😄

> [@Thundercat](#):
>
> are there any memory concerns with this method - will this become a resource hog with using this for lots of windows?

Not if you are careful. Consider an application that has two global GWindow references e.g.

```auto
GWindow w1;
GWindow w2;

```

Now both of these are initialized to `null` by Java. If you now create a window like this  
` w1 = GWindow.getWindow(this, "Title", 400, 300, 300, 120, JAVA2D);`

`w1` is no longer `null` and the memory for the window is kept and managed by Java.

Now if at some stage you use `w1.forceClose();` G4P nulls all internal references to the window so the only reference is `w1`. While there is an active reference Java will continue to keep the memory available, If after closing the window we do `w1 = null;` there is no longer an active reference to the window so Java’s garbage collector will release the memory back to the system heap for later reuse.  
Now consider the following statements

```auto
w2 = w1;
w1.forceClose();
w1 = null;

```

Although we have told G4P we no longer want this window Java will keep the memory because we still have an active reference to it i.e. `w2`. This is called a _memory leak_

To relapse the memory we need to nullify the `w2` reference. i.e. `w2 = null;`

This means you have to be careful with object refernces.

---

<div class="post-metadata">

**Author:** ![Thundercat](https://avatars.discourse-cdn.com/v4/letter/t/dbc845/32.png) [@Thundercat](https://discourse.processing.org/u/Thundercat)\
**Post date:** [July 14, 2024, 2:47pm UTC](https://discourse.processing.org/t/g4p-close-window-vs-hide-window/44761/8 "2024-07-14T14:47:51Z")

</div>

What most it be like to be so incredibly brilliant?

Thank you so much for sharing!

Also, is there any way to add the window.addOnCloseHandler(this, “windowCloseAction”); to the main sketch window as well? That way I could trap for the whole sketch being closed with the “X” as well…

---

<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:** [July 14, 2024, 3:31pm UTC](https://discourse.processing.org/t/g4p-close-window-vs-hide-window/44761/9 "2024-07-14T15:31:57Z")

</div>

> [@Thundercat](#):
>
> Also, is there any way to add the window.addOnCloseHandler(this, “windowCloseAction”); to the main sketch window as well?

AFAIK no butyou can use the `exit()` method in the main sketch to perform close down actions when the window is closed.

```auto
// Executed when the application closes down
public void exit(){
  // perform any close down actions

  // the last line must call the parent exit() method
  super.exit();
}

```

I am confident there is a way to get rid of the X button and even create borderless apps but you have to be careful because some of the techniques are OS specific. If you want to try this then use the search on [Processing’s home page](https://processing.org/) rather tan search this forum directly. You generally get better results that way.

If you have no joy then create a new topic about how to get rid of the close button. Since this is a Processing thing don’t mention G4P because it will just muddy the waters.

---

<div class="post-metadata">

**Author:** ![Thundercat](https://avatars.discourse-cdn.com/v4/letter/t/dbc845/32.png) [@Thundercat](https://discourse.processing.org/u/Thundercat)\
**Post date:** [July 15, 2024, 2:47pm UTC](https://discourse.processing.org/t/g4p-close-window-vs-hide-window/44761/10 "2024-07-15T14:47:05Z")

</div>

I appreciate this very much.

What I’ve noticed and from the documentation is this is only for a couple last minute variable updates type of thing - it quits after the draw() method finishes it’s current cycle.

I know I’m asking too much - and this is now beyond the scope of G4P for sure so I may post this as a general thread here - but it would be fantastic to simply have a way to simply detect when a person clicks the “x” - and the do whatever processes I wanted after.

The reason in this case is because there are files to save, filenames to ask the user to provide, etc, and very little of this works correctly calling from exit(). Sketch ends up quitting before the rest of the “closing” processes I want to provide have run.

Thank you again Peter; you are an absolute treasure.

mike
