How to Remove the Close Button with G4P

Hello all,

I am using G4P to create an application and I would like to either remove completely or simply grey out the gui close button. I know how to stop the window from closing when the close button is pressed, but I would like to remove it completely so the user of the application won’t see it as an option.

Capture

Is it possible to grey it out so it can’t be pressed like the maximize button seen above?

Thank you,
Grayson

1 Like

Are you talking about the main sketch window or secondary windows created by G4P?

Hi Quark,

I am talking about secondary windows created by G4P. I have several secondary windows that I “close” (hide) with GButton functions and I would like to make the gui less confusing for the user by either removing or greying out the close button in the corner of the window.

Sorry for the delay in getting back to you.

I made a mistake here since it doesn’t matter which window it is.

The window close button(X) is provided by Java or OpenGL. For instance if you are using the default renderer (JAVA2D) then the window class is javax.swing.JFrame, it you are using OpenGL (P2D, P3D0 then the window class is GLWindow.

So the problem is whether or not these classes allow for the removal of the window close button. If they don’t then there is nothing G4P can do about it.

I am using JAVA2D as the renderer. I found this link, which talks about how to remove the menu buttons recursively. I can try to implement this in my program, but now I’m faced with how to treat a GWindow as a JFrame. Is it as simple as casting it to be a JFrame?

1 Like

You can ‘undecorate’ a JFrame easy enough but it removes the entire border so you can’t drag it with the mouse to a new screen location.

Further down in the forum Michael Dunn posted about how to recursively loop through the frame’s components and you can remove buttons that way. Below is his method for removing the buttons of the JFrame without completely undecorating it.

My mistake I didn’t read the whole post. To do that you need to get a reference to the JFrame. This sketch shows how to do that for the main display and for G4P secondary windows.

import g4p_controls.*;
import javax.swing.*;

JFrame frame;

void setup() {
  size(200, 200);
  // Get frame for main window
  frame = (JFrame) ((processing.awt.PSurfaceAWT.SmoothCanvas) 
    surface.getNative()).getFrame();
  println(frame);
  // Get frame for a GWindow using JAVA2D
  GWindow window = GWindow.getWindow(this, "Second Window", 20, 20, 320, 240, JAVA2D);
  frame = (JFrame) ((processing.awt.PSurfaceAWT.SmoothCanvas) 
    window.getSurface().getNative()).getFrame();
  println(frame);
}
1 Like

Here is a sketch I made to try and remove buttons.

import g4p_controls.*;
import javax.swing.*;
import java.awt.*;

JFrame frame;

void setup() {
  size(200, 200);
  
  
  // Get frame for a GWindow using JAVA2D
  GWindow window = GWindow.getWindow(this, "Second Window", 20, 20, 320, 240, JAVA2D);
  frame = (JFrame) ((processing.awt.PSurfaceAWT.SmoothCanvas) 
    window.getSurface().getNative()).getFrame();


  //remove buttons
  JFrame frame;
  frame = (JFrame) ((processing.awt.PSurfaceAWT.SmoothCanvas) 
    window.getSurface().getNative()).getFrame();
  removeButtonsFromWindow(frame);

  //frame.setUndecorated(true);
}

//remove buttons from JFrame
void removeButtonsFromWindow(Component comp) {
  println(comp);
  if (comp instanceof Button) {
    int todo; //TODO only remove the exit button.
    comp.getParent().remove(comp);
  }
  if (comp instanceof Container) {
    Component[] comps = ((Container) comp).getComponents();
    for (int i = 0; i < comps.length; i++) {
      removeButtonsFromWindow(comps[i]);
    }
  }
}

and here is the output:

javax.swing.JFrame[frame0,20,20,326x268,layout=java.awt.BorderLayout,title=GWindowAWT,normal,defaultCloseOperation=HIDE_ON_CLOSE,rootPane=javax.swing.JRootPane[,3,25,320x240,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true]
javax.swing.JRootPane[,3,25,320x240,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777673,maximumSize=,minimumSize=,preferredSize=]
javax.swing.JPanel[null.glassPane,0,0,320x240,hidden,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777217,maximumSize=,minimumSize=,preferredSize=]
javax.swing.JLayeredPane[null.layeredPane,0,0,320x240,alignmentX=0.0,alignmentY=0.0,border=,flags=0,maximumSize=,minimumSize=,preferredSize=,optimizedDrawingPossible=true]
javax.swing.JPanel[null.contentPane,0,0,320x240,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=]
processing.awt.PSurfaceAWT$SmoothCanvas[canvas0,0,0,320x240]

The recursive method for reaching all of the components is not finding the buttons on the window.
I also tried to set the window to be undecorated and this was the output error I was given:

IllegalComponentStateException: The frame is displayable.

Do you know why the buttons aren’t being found or why setUndecorated(true) isn’t working as expected?

The post that I am basing the recursive function to find the buttons off of is from 12 years ago. I suppose the structure of the swing components could be different now and isn’t allowing for a deeper recursive search to be made.

1 Like

Had a look at the source code for JFrame and parent classes can’t see anything to help. It might be part of the JVM.

The setUndecorated(true) can only be used after the frame is created but before it is first displayed.

1 Like

Ok, Ill keep trying different things to figure out how to do it. Thank you for your help! I’ll post on here with a solution if/when I find one.

Hi GoToLoop,

Thanks for the link. I read through it and I don’t think it is quite what I’m looking for. From what I understood that thread shows how to disable the event listener associated with the close button, but the button is still there and can still be clicked. This is how my current setup is with the G4P windows. I am trying to completely remove the close button in the top right corner of the sketch so that the user can’t view it as an option.

Watching … I’d like to be able to do this.