Wie schließe ich eine JavaFX-Anwendung beim Schließen eines Fensters?


77

In Swing können Sie einfach setDefaultCloseOperation()die gesamte Anwendung herunterfahren, wenn das Fenster geschlossen wird.

In JavaFX kann ich jedoch kein Äquivalent finden. Ich habe mehrere Fenster geöffnet und möchte die gesamte Anwendung schließen, wenn ein Fenster geschlossen wird. Wie geht das in JavaFX?

Bearbeiten:

Ich verstehe, dass ich überschreiben kann setOnCloseRequest(), um eine Operation beim Schließen des Fensters auszuführen. Die Frage ist, welche Operation ausgeführt werden sollte, um die gesamte Anwendung zu beenden.

stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
    @Override
    public void handle(WindowEvent event) {
        stop();
    }
});

Die stop()in Applicationclass definierte Methode führt nichts aus.

Antworten:


87

Die Anwendung stoppt automatisch, wenn die letzte Stagegeschlossen wird. In diesem Moment wird die stop()Methode Ihrer ApplicationKlasse aufgerufen, sodass Sie kein Äquivalent zu benötigensetDefaultCloseOperation()

Wenn Sie die Anwendung vorher stoppen möchten, können Sie Platform.exit()beispielsweise in Ihrem onCloseRequestAnruf anrufen.

Sie können alle diese Informationen über die javadoc Seite haben von Application: http://docs.oracle.com/javafx/2/api/javafx/application/Application.html


5
Als Referenz (wie auf der verknüpften Javadoc-Seite erwähnt): Die Anwendung wird nur automatisch gestoppt, wenn das implicitExitAttribut on auf gesetzt Platformist true.
Rahel Lüthy

58

Einige der bereitgestellten Antworten funktionierten bei mir nicht (javaw.exe wird nach dem Schließen des Fensters noch ausgeführt) oder Eclipse zeigte nach dem Schließen der Anwendung eine Ausnahme.

Auf der anderen Seite funktioniert das perfekt:

primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
    @Override
    public void handle(WindowEvent t) {
        Platform.exit();
        System.exit(0);
    }
});

Hast du etwas mit mehreren Threads gemacht? Mir scheint, dass es (für mich) bei Verwendung von ExecutorService nicht heruntergefahren wird (was möglicherweise beabsichtigt ist, ich habe die Dokumente noch nicht überprüft).
Manius

1
Für mich war das Hinzufügen von das System.exit(0);einzige, was dazu führte, dass der Prozess nach dem Schließen des Hauptfensters beendet wurde.
Johannes

1
Wenn Sie es kurz mögen, funktioniert dies in Java 8: theStage.setOnCloseRequest (e -> System.exit (0));
Jaco Van Niekerk

1
Wenn Sie ExecutorServicewie @Manius einen eigenen (dh einen Thread-Pool) starten, müssen Sie diesen explizit herunterfahren (wenn der Thread ein Nicht-Daemon ist). Sie können dies in der #stop()Methode Ihrer Anwendungsklasse tun , wenn Sie möchten. JavaFX verwaltet jedoch keine ExecutorServiceInstanzen (oder andere Thread-erstellende Parallelitätsdienstprogramme).
Slaw

26

Als Referenz ist hier eine minimale Implementierung mit Java 8:

@Override
public void start(Stage mainStage) throws Exception {

    Scene scene = new Scene(new Region());
    mainStage.setWidth(640);
    mainStage.setHeight(480);
    mainStage.setScene(scene);

    //this makes all stages close and the app exit when the main stage is closed
    mainStage.setOnCloseRequest(e -> Platform.exit());

    //add real stuff to the scene...
    //open secondary stages... etc...
}

20
stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
    @Override
    public void handle(WindowEvent event) {
        Platform.exit();
        System.exit(0);
    }
});

Ich möchte nur darauf hinweisen, dass in diesem Fall die stop () -Methode überhaupt nicht aufgerufen wird (zumindest mit JavaFX 8 unter Windows), da System.exit () alles zu früh schließt. In diesem Fall können Sie nur System.exit () aufrufen. Wenn Sie jedoch etwas in der stop () -Methode tun möchten, würde ich empfehlen, Platform.exit () hier und System.exit (0) am Ende der stop () -Methode aufzurufen, falls erforderlich.
morgen

Einige schlechte Syntax hier. Ihnen fehlt ein Abschluss ')'
Nibb


3

Mit Java 8 hat das bei mir funktioniert:

@Override
public void start(Stage stage) {
    Scene scene = new Scene(new Region());
    stage.setScene(scene);

    /* ... OTHER STUFF ... */

    stage.setOnCloseRequest(e -> {
        Platform.exit();
        System.exit(0);
    });
}

2

Anstatt mit onCloseRequest-Handlern oder Fensterereignissen herumzuspielen, rufe ich lieber Platform.setImplicitExit(true)den Anfang der Anwendung auf.

Laut JavaDocs:

"Wenn dieses Attribut wahr ist, wird die JavaFX-Laufzeit implizit heruntergefahren, wenn das letzte Fenster geschlossen wird. Der JavaFX-Launcher ruft die Application.stop () -Methode auf und beendet den JavaFX-Anwendungsthread."

Beispiel:

@Override
void start(Stage primaryStage) {
    Platform.setImplicitExit(true)
    ...
    // create stage and scene
}

1
Schön, aber zumindest in FX 12 ist es standardmäßig aktiviert. The default value is true.
Benjamin Peter

1

Für mich funktioniert nur folgendes:

primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
    @Override
    public void handle(WindowEvent event) {

        Platform.exit();

        Thread start = new Thread(new Runnable() {
            @Override
            public void run() {
                //TODO Auto-generated method stub
                system.exit(0);     
            }
        });

        start.start();
    }
});

0

Das schien für mich zu funktionieren:

EventHandler<ActionEvent> quitHandler = quitEvent -> {

        System.exit(0);

    };
    // Set the handler on the Start/Resume button
    quit.setOnAction(quitHandler);

0

Versuchen

 System.exit(0);

Dies sollte Thread main beenden und das Hauptprogramm beenden



-2

Sie MÜSSEN die Methode "stop ()" in Ihrer Anwendungsinstanz überschreiben, damit sie funktioniert. Wenn Sie sogar leeres "stop ()" überschrieben haben, wird die Anwendung ordnungsgemäß geschlossen, nachdem die letzte Stufe geschlossen wurde (tatsächlich muss die letzte Stufe die primäre Stufe sein, damit sie vollständig wie vorgesehen funktioniert). In diesem Fall sind keine zusätzlichen Platform.exit- oder setOnCloseRequest-Aufrufe erforderlich.


Bitte geben Sie ein funktionierendes Beispiel an - hat bei mir nicht funktioniert
Wolfgang Fahl
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.