Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaFX show dialogue after thread task is completed

I need to show dialogue window

 Stage dialog = new Stage();
            dialog.initStyle(StageStyle.UTILITY);
            Scene scene = new Scene(new Group(new Text(25, 25, "All is done!")));
            dialog.setScene(scene);
            dialog.showAndWait();   

after my thread completes the task

Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                   doSomeStuff();
                }

            });

I've tried

Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                doSomeStuff();
            }

        });
        t.start();
        t.join();
        Stage dialog = new Stage();
        dialog.initStyle(StageStyle.UTILITY);
        Scene scene = new Scene(new Group(new Text(25, 25, "All is done!")));
        dialog.setScene(scene);
        dialog.showAndWait();
    }

but this app is not responsing until doSomeStuff() is finished

like image 217
Margarita Spasskaya Avatar asked Sep 25 '15 00:09

Margarita Spasskaya


1 Answers

t.join() is a blocking call, so it will block the FX Application thread until the background thread completes. This will prevent the UI from being repainted, or from responding to user input.

The easiest way to do what you want is to use a Task:

Task<Void> task = new Task<Void>() {
    @Override
    public Void call() throws Exception {
        doSomeStuff();
        return null ;
    }
};
task.setOnSucceeded(e -> {
    Stage dialog = new Stage();
    dialog.initStyle(StageStyle.UTILITY);
    Scene scene = new Scene(new Group(new Text(25, 25, "All is done!")));
    dialog.setScene(scene);
    dialog.showAndWait();
});
new Thread(task).start();

A low-level (i.e. without using the high-level API JavaFX provides) approach is to schedule the display of the dialog on the FX Application thread, from the background thread:

Thread t = new Thread(() -> {
    doSomeStuff();
    Platform.runLater(() -> {
        Stage dialog = new Stage();
        dialog.initStyle(StageStyle.UTILITY);
        Scene scene = new Scene(new Group(new Text(25, 25, "All is done!")));
        dialog.setScene(scene);
        dialog.showAndWait();
    });
});
t.start();

I strongly recommend using the first approach.

like image 116
James_D Avatar answered Nov 06 '22 18:11

James_D