How to close a JavaFX application on window close?
Asked Answered
E

13

92

In Swing you can simply use setDefaultCloseOperation() to shut down the entire application when the window is closed.

However in JavaFX I can't find an equivalent. I have multiple windows open and I want to close the entire application if a window is closed. What is the way to do that in JavaFX?

Edit:

I understand that I can override setOnCloseRequest() to perform some operation on window close. The question is what operation should be performed to terminate the entire application?

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

The stop() method defined in Application class does nothing.

Elegist answered 28/8, 2012 at 6:10 Comment(0)
A
108

The application automatically stops when the last Stage is closed. At this moment, the stop() method of your Application class is called, so you don't need an equivalent to setDefaultCloseOperation()

If you want to stop the application before that, you can call Platform.exit(), for example in your onCloseRequest call.

You can have all these information on the javadoc page of Application : http://docs.oracle.com/javafx/2/api/javafx/application/Application.html

Abreact answered 28/8, 2012 at 6:50 Comment(2)
For reference (as mentioned in the linked javadoc page): The application is only stopped automatically if the implicitExit attribute on Platform is set to true.Ratline
FWIW stopping the stage will not terminate the app if the stage was never shown.Disappoint
S
85

Some of the provided answers did not work for me (javaw.exe still running after closing the window) or, eclipse showed an exception after the application was closed.

On the other hand, this works perfectly:

primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
    @Override
    public void handle(WindowEvent t) {
        Platform.exit();
        System.exit(0);
    }
});
Soothsay answered 20/7, 2015 at 14:25 Comment(5)
Were you doing something multi threaded? Seems to me that it's not shutting down (for me) when using ExecutorService (which might be intended behavior, I haven't checked the docs yet).Hippie
For me, adding the System.exit(0); was the only thing that made the process terminate after the main window closed.Kyat
If you like it short, this works in Java 8: theStage.setOnCloseRequest(e -> System.exit(0));Neurogenic
If you start your own ExecutorService (i.e. a thread pool), as @Hippie did, then you need to explicitly shut it down (if the threads a non-daemon). You can do this in the #stop() method of your application class, if you want. However, JavaFX does not, on its own, manage ExecutorService instances (or any other thread-creating concurrency utility).Housefather
By adding System.exit(0) a lot of my code in the stop method wasn't able to complete and produced all sorts of errors. Platform.exit() is all you actually need.Blowpipe
C
30

For reference, here is a minimal implementation using 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...
}
Crean answered 8/5, 2015 at 9:50 Comment(0)
L
25
stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
    @Override
    public void handle(WindowEvent event) {
        Platform.exit();
        System.exit(0);
    }
});
Lettering answered 9/6, 2015 at 5:49 Comment(4)
I just want to point out that in this case the stop() method won't be called at all (at least with JavaFX 8 on windows) because System.exit() closes everything too early. In this case you might just call System.exit() only. But if you want to do something in the stop() method, I would recommend calling Platform.exit() here and System.exit(0) at the end of the stop() method if needed.Lou
Some bad syntax here. You're missing a closing ')'Greathouse
@Lou yep, Platform.exit() is all you really need. The System.exit() does not actually occur after the "plaform exits". It happens at the same time. Most if not all of the code in the stop() method doesn't complete. There is no point in putting System.exit() in here.Blowpipe
I guess you could also wrap the System.exit in a Platform.runLaterHimation
S
4

Instead of playing around with onCloseRequest handlers or window events, I prefer calling Platform.setImplicitExit(true) the beginning of the application.

According to JavaDocs:

"If this attribute is true, the JavaFX runtime will implicitly shutdown when the last window is closed; the JavaFX launcher will call the Application.stop() method and terminate the JavaFX application thread."

Example:

@Override
void start(Stage primaryStage) {
    Platform.setImplicitExit(true)
    ...
    // create stage and scene
}
Schismatic answered 31/5, 2019 at 3:57 Comment(1)
Nice, but at least in FX 12 it is enable by default. The default value is true.Rimbaud
H
3

Did you try this..setOnCloseRequest

setOnCloseRequest(EventHandler<WindowEvent> value)   

There is one example

Haland answered 28/8, 2012 at 6:19 Comment(1)
it is best than stop() method?Cornell
D
3

Using Java 8 this worked for me:

@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);
    });
}
Diet answered 11/10, 2016 at 21:23 Comment(0)
O
1

For me only following is working:

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();
    }
});
Obliquity answered 6/4, 2018 at 6:12 Comment(0)
U
0

This seemed to work for me:

EventHandler<ActionEvent> quitHandler = quitEvent -> {

        System.exit(0);

    };
    // Set the handler on the Start/Resume button
    quit.setOnAction(quitHandler);
Upward answered 11/4, 2017 at 15:35 Comment(0)
C
0

Try

 System.exit(0);

this should terminate thread main and end the main program

Catawba answered 8/5, 2017 at 11:23 Comment(0)
J
0

getContentPane.remove(jfxPanel);

try it (:

Ji answered 29/5, 2018 at 16:50 Comment(0)
C
-1

in action button try this : stage.close();


exemple:

Stage stage =new Stage();

BorderPane root=new BorderPane();

Scene scene=new Scene();

Button b= new Button("name button");

       b.setOnAction(new EventHandler<ActionEvent>() {
   
       @Override
        public void handle(ActionEvent event) {

                 stage.close();
               
            }
            });

root.getChildren().add(b);

stage.setTitle("");

stage.setScene(scene);

stage.show();

Conferva answered 8/5, 2021 at 11:36 Comment(1)
Please try to clean up the code so readers can follow it. Some of the code is formatted as code, but the rest is not; please format all of the code as code and, if there is a break between sections, make this clear.Gibson
H
-2

You MUST override the "stop()" method in your Application instance to make it works. If you have overridden even empty "stop()" then the application shuts down gracefully after the last stage is closed (actually the last stage must be the primary stage to make it works completely as in supposed to be). No any additional Platform.exit or setOnCloseRequest calls are need in such case.

Heffernan answered 6/6, 2017 at 14:26 Comment(1)
please supply a working example - didn't work for meJoniejonina

© 2022 - 2024 — McMap. All rights reserved.