0

My problem is that I can not start a new modal window in Task, it just does not go out. I do not understand how it is possible to derive not just an allert, but any modal window from Task. Translated by Google =)

Task<Void> task = new Task<Void>() {
            @Override 
            public Void call() throws ApiException,ClientException,InterruptedException {
                 int i = 0;
                 for ( i = 0; i < bufferLenght; i++){
                    try {
                    ...some code
                    }catch(ApiCaptchaException e) {
                       ...get capcha
                       captchaSid = e.getSid();
                       captchaImg = e.getImage();
                       System.out.println( captchaSid);
}

                    System.out.println(captchaSid);
                    if (captchaSid != null) {
                        System.out.println("gg");
                        Alert alert = new Alert(AlertType.INFORMATION);
                        alert.setTitle("Test Connection");
                        //here he is stuck
                        alert.setHeaderText("Results:");
                        alert.setContentText("Connect to the database successfully!");
                        alert.showAndWait();

                        System.out.println("gg3");  
                    if(i<bufferLenght-1) {
                    Thread.sleep(2000);
                    }
                }
                return null;
            }
        };

        new Thread(task).start();
fedot deon
  • 51
  • 1
  • 1
  • 8
  • You cannot create a new window in a background thread. If you capture your exceptions with, for example, `task.setOnFailed(e -> task.getException().printStackTrace());` (before `new Thread(task).start()`), you will see the exception that is happening. – James_D May 07 '18 at 12:52
  • `Window`s need to be shown on the javafx application thread. Use `Platform.runLater` for this purpose. If you need to wait for the user to close the window on the task thread, `CountDownLatch` is your friend... – fabian May 07 '18 at 13:01
  • from ApiCaptchaException I get a link to CAPTCHA and I just wanted to open a window for captcha input and continue the Task execution, because in the TASK there is a method of queries to the API, I can not run it in the main FX Aplication Thread because I can not make many requests in 1 second and need a Thread.sleep. – fedot deon May 07 '18 at 13:07
  • I used Platform.runLater in Task for new window and this is worked, but when i entered captcha in window and then close it,my program stuck in Platform.runLater and my method which must accept capcha result in task not loaded. – fedot deon May 07 '18 at 13:13
  • See https://stackoverflow.com/q/50067565/ – James_D May 07 '18 at 13:20

1 Answers1

1

You must create and show new windows on the FX Application Thread. You can schedule code to execute on the FX Application Thread by submitting it to Platform.runLater(...). If you need your background thread to wait for the user to dismiss the Alert, you can use a CompletableFuture, as in this question:

Task<Void> task = new Task<Void>() {

    @Override
    protected Void call() throws Exception {

        // ...

        CompletableFuture.runAsync(() -> {
            Alert alert = new Alert(AlertType.INFORMATION);
            alert.setTitle("Test Connection");
            alert.setHeaderText("Results:");
            alert.setContentText("Connect to the database successfully!");
            alert.showAndWait();
        }, Platform::runLater).join();

        // ...
    }
};

If your alert is returning a value which you need, use supplyAsync(...) instead and return the value from the lambda expression. You can then assign that value to the result of join():

Task<Void> task = new Task<Void>() {

    @Override
    protected Void call() throws Exception {

        // ...

        String result = CompletableFuture.supplyAsync(() -> {
            Alert alert = new Alert(AlertType.INFORMATION);
            alert.setTitle("Test Connection");
            alert.setHeaderText("Results:");
            alert.setContentText("Connect to the database successfully!");
            alert.showAndWait();
            // presumably here you want to return a string
            // depending on the alert...
            return "" ;
        }, Platform::runLater).join();

        // ...
    }
};
James_D
  • 201,275
  • 16
  • 291
  • 322