fedot deon
fedot deon

Reputation: 61

Java FX new modal Window in Task

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();

Upvotes: 0

Views: 414

Answers (1)

James_D
James_D

Reputation: 209553

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();

        // ...
    }
};

Upvotes: 1

Related Questions