Disable close button in Processing

1.4k views Asked by At

Is there a way to disable the window's close button in Processing, during a certain event?

Here is a snippet of the code:

frame.addWindowListener(new WindowAdapter()
  {
    public void windowClosing(WindowEvent we)
    {
      if (youWin == 0) // condition that is supposed to keep the application opened
      {
        JOptionPane.showMessageDialog(frame,"You can't exit until you finish this game. OK?");
        // keep applet opened
      }
    }
  }
);

EDIT: I want to do it without using JFrames.

1

There are 1 answers

0
Kevin Workman On BEST ANSWER

Edit: This answer is for Processing 2. It won't work with newer versions of Processing.

I want to do it without using JFrames.

Too bad. You're already using a JFrame, you just don't know it.

Processing will create a JFrame for you, even though it's stored in a Frame variable. If you don't believe me, check out line 453 of PSurfaceAWT.

That means you can use JFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); to tell the frame to, well, do nothing when you click the X button. This disables the low-level listeners that automatically close the JFrame.

import javax.swing.JFrame;
void setup() {
  ((JFrame)frame).setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
}
void draw() {
  background(0);
  ellipse(mouseX, mouseY, 10, 10);
}

That's only half the battle though. Processing also has its own listener that detects when the user clicks the X button, on top of the low-level listener. This listener calls the exit() function, which closes the sketch anyway.

To get around that, you have to override the exit() function. (You could also remove the listener that Processing adds, but this is easier imho.)

import javax.swing.JFrame;
void setup() {
  ((JFrame)frame).setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
}
void exit() {
  println("not exiting");
}
void draw() {
  background(0);
  ellipse(mouseX, mouseY, 10, 10);
}

Okay, we've completely removed the ability to close the frame with the X button. Now we have to add in the ability to close it when we want to. You can do this either by adding a call to super.exit() in the exit() function:

void exit() {
  if(reallyExit){
    super.exit();
  }
}

Calling super.exit() will close the sketch for you. It's up to you how you set the reallyExit variable.

Another approach would be to add a WindowListner to the JFrame that handles the closing event:

void setup() {

  ((JFrame)frame).setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

  frame.addWindowListener(new java.awt.event.WindowAdapter() {
    public void windowClosing(java.awt.event.WindowEvent we) {
      if (reallyExit) {
        frame.dispose();
      }
    }
  }
  );
}

Here's a full example that uses both approaches. You only need either a call to frame.dispose() or a call to super.exit() though. It's really up to personal preference.

import javax.swing.JFrame;

void setup() {

  ((JFrame)frame).setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

  frame.addWindowListener(new java.awt.event.WindowAdapter() {
    public void windowClosing(java.awt.event.WindowEvent we) {
      if (mouseX < 10) {
        frame.dispose();
      }
    }
  }
  );
}

void exit() {
  if(mouseX <10){
    super.exit();
  }
}


void draw() {
  background(0);
  ellipse(mouseX, mouseY, 10, 10);
}