web-dev-qa-db-fra.com

Empêcher/annuler la fermeture de l’étape primaire dans JavaFX 2.2

Comme le titre l'indique, ma question est la suivante: comment puis-je empêcher/annuler la fermeture de la phase principale de JavaFX 2.2? J'ai effectué des recherches sur Google et les deux liens suivants semblaient résoudre le problème:

J'ai essayé les méthodes expliquées par ces deux liens, mais malheureusement pour moi, aucune d'entre elles ne fonctionne. Alors, sans plus tarder, voici ce que j'avais fait.

Premièrement, j'ai essayé d'attacher une OnCloseRequest à la primaryStage comme suit.

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

Lorsque canExit() renvoie false, j'ai essayé d'empêcher que l'événement ne se propage davantage et que je quitte l'application en appelantevent.consume(). Mais la scène est en train de se fermer/se cacher et j'ai reçu les messages d'erreur suivants sur la fenêtre de sortie de Netbeans. Il continue à venir à plusieurs reprises jusqu'à ce que je force de fermer l'application de 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

Ayant goûté à l'échec lors de cette tentative, j'ai changé OnCloseRequest en OnHiding avec l'espoir de réussir.

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

Même si, dans cette tentative, j’ai eu le goût de l’échec, je pense avoir fait quelques progrès. Il n'y a pas de message d'erreur cette fois et il n'est pas nécessaire de forcer la fermeture de l'application à partir de Netbeans.

Ensuite, j'ai découvert quelque méthode magique nommée setImplicitExit() dans la classe Platform. Pensant que c’était ce qui me manquait, j’ai essayé Platform.setImplicitExit(false); avec les deux méthodes suivantes:

  1. OnCloseRequest version

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

    Aucune différence, la scène est fermée/cachée et le même message d'erreur est répété.

  2. OnHiding version

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

    En commençant par une note positive, l'application n'est pas complétée comme auparavant. Mais, la note négative est que la scène est toujours fermée/cachée.

Maintenant, je suis à court d’armes/d’équipements dans mon arsenal pour le résoudre, et je suis donc ici pour demander l’aide de vos héros et de vos champions. Alors, comment puis-je résoudre ce problème ou qu'est-ce que j'ai mal fait ou qu'est-ce qui me manque?

22
Jomoos

J'ai utilisé le code suivant dans mon application et cela fonctionne parfaitement,

Platform.setImplicitExit(false);

primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
    @Override
    public void handle(WindowEvent event) {
        event.consume();
    }
});
25
Shreyas Dave

Je pense que vous avez mal interprété le onCloseRequest(). Si vous consommez l'événement, vous annulez la fermeture! Donc, cela fonctionne l'autre pourquoi rond, si canExit() retourne false vous consommez l'événement

2
tomsontom

Je pense que c'est un bogue avec JavaFX pour Linux. J'ai rencontré le même problème sur Javafx 2.2.21-b11. En fonction du contexte, les erreurs GTK peuvent ou non être présentes, mais le fait de consommer l'événement de demande de fermeture n'a pas empêché la fermeture de la fenêtre (le processus continue néanmoins de s'exécuter). La même application sur Windows s'est comportée comme je le pensais. Au mieux, nous avons une différence de comportement entre les plates-formes. 

J'ai déposé un rapport de bogue, vous pouvez y voter si vous le souhaitez: https://javafx-jira.kenai.com/browse/RT-33295

Voici la source de mon application de test

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);
    }
}
2
kylejmcintyre

Cela a fonctionné pour moi

                stage.setOnCloseRequest(new EventHandler<WindowEvent>() {  
                    @Override
                    public void handle(WindowEvent event) {
                        AlertHelper addMore = new AlertHelper("Exit application? Any unsaved data will be lost", "Attention", "Confirmation Required");
                        boolean actionNeeded = addMore.populatePopup();
                        if (actionNeeded) {
                            System.exit(0);
                        } else {
                            event.consume();
                        }

                    }
                });
0