Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent/Cancel closing of primary stage in JavaFX 2.2

Tags:

java

javafx-2

As the title says, my question is, how can I prevent/cancel closing of primary stage in JavaFX 2.2? I have done some research on Google, and the following two links seemed to address the issue:

  • Prevent or cancel exit JavaFX 2
  • Thread: JavaFX 2.0 Stage onClose event

I tried the methods explained by those two links, but sadly for me, none of them works. So, without further ado, here is what I had done.

Firstly, I tried to attach an OnCloseRequest to the primaryStage as follows.

primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {     @Override     public void handle(WindowEvent event) {         if (!canExit()) {             event.consume();             primaryStage.show(); // I tried without this line also.         }     } }); 

When canExit() returns false, I tried to prevent the event from propagating further and cause to exit the app by callingevent.consume(). But the stage is getting closed/hidden and I got the following error messages on Netbeans output window. It keeps coming repeatedly until I force close the app from Netbeans.

(java:6731): Gtk-CRITICAL **: IA__gtk_widget_get_visible: assertion `GTK_IS_WIDGET (widget)' failed  (java:6731): Gtk-CRITICAL **: IA__gtk_widget_get_visible: assertion `GTK_IS_WIDGET (widget)' failed  (java:6731): Gtk-CRITICAL **: IA__gtk_widget_get_visible: assertion `GTK_IS_WIDGET (widget)' failed 

Having tasted failure in this attempt, I changed OnCloseRequest to OnHiding with the expectation of success.

primaryStage.setOnHiding(new EventHandler<WindowEvent>() {     @Override     public void handle(WindowEvent event) {         if (!canExit()) {             event.consume();             primaryStage.show(); // I tried without this line also.         }     } }); 

Although, I tasted failure in this attempt too, I think I have made some progress. There is no error messages this time, and no need to force close the application from Netbeans.

Then I read about some magic method named setImplicitExit() in the Platform class. Thinking that this is what I was missing, I tried Platform.setImplicitExit(false); with both of the two methods as follows:

  1. OnCloseRequest version

    Platform.setImplicitExit(false);  primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {     if (!canExit()) {         // ...     } else {         Platform.exit();     } }); 

    No difference, the stage gets closed/hidden, and the same error message comes repeatedly.

  2. OnHiding version

    Platform.setImplicitExit(false);  primaryStage.setOnHiding(new EventHandler<WindowEvent>() {     if (!canExit()) {         // ...     } else {         Platform.exit();     } }); 

    Beginning on a positive note, the application doesn't get exited as earlier. But, the negative note is that the stage is still getting closed/hidden.

Now, I am out of weapons/equipments in my armoury to solve it, and so I am here to request the help of you heroes and champions. So, How can I solve this problem or what have I done wrong or what am I missing?

like image 945
Jomoos Avatar asked Jun 08 '13 21:06

Jomoos


Video Answer


2 Answers

I have used following code in my application and it works perfectly,

Platform.setImplicitExit(false);  primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {     @Override     public void handle(WindowEvent event) {         event.consume();     } }); 
like image 157
Shreyas Dave Avatar answered Sep 21 '22 22:09

Shreyas Dave


I think this is a bug with JavaFX for Linux. I ran in to the same problem on Javafx 2.2.21-b11. Depending on the context the GTK errors may or may not be present, but either way consuming the close request event didn't prevent the window from closing (yet the process continues to run). The same app on Windows behaved as I would expect. So at best we have a difference in behavior across platforms.

I filed a bug report you can upvote if you'd like: https://javafx-jira.kenai.com/browse/RT-33295

Here's the source of my test app

import javafx.application.Application; import javafx.event.EventHandler; import javafx.stage.Stage; import javafx.stage.WindowEvent;  public class Boom extends Application {     @Override     public void start(final Stage primary)  {         System.out.println(com.sun.javafx.runtime.VersionInfo.getRuntimeVersion());         primary.setOnCloseRequest(new EventHandler<WindowEvent>() {             @Override             public void handle(WindowEvent e) {                 e.consume();             }         });         primary.show();     }      public static void main(String[] args) {         launch(args);     } } 
like image 26
kylejmcintyre Avatar answered Sep 20 '22 22:09

kylejmcintyre