Joe Taylor
Joe Taylor

Reputation: 181

Running a function the background Javafx

I'm still pretty new to java and I am stuck for why this happens, when I click a button I have created the program crashes until the action is complete (SendPost();), the problem with this is that the function sends a post request and parses the response which takes around 10 seconds so the GUI crashes is unusable until the SendPost() has finished. I need it to run in the background somehow so it doesn't keep crashing when I add a timer.

here is my code for the button

            EventHandler<ActionEvent> login = new EventHandler<ActionEvent>() { 
            @Override public void handle(ActionEvent event) { 
                SendPost();


            }       
        };

Upvotes: 1

Views: 2281

Answers (1)

Erik Vesteraas
Erik Vesteraas

Reputation: 4735

What is happening to your program is that the call you are doing is blocking the JavaFX thread while it is working. When this happens your interface stops responding to input, making it seem like your program has hung/crashed.

As has been commented you could simply start a new plain Thread to do what you need, as the important part is moving the work to another thread, keeping the application thread responsive. In this case you could simply do it like this:

Thread th = new Thread(() -> {
    sendPost();
});
th.setDaemon(true);
th.start();

Later however, you might want to look into the Task class, which gives a lot more options for background tasks in JavaFX and is very pleasant to work with. Here is an example program using it:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.geometry.*;
import javafx.stage.*;
import javafx.event.*;
import javafx.concurrent.*;
import java.util.concurrent.*;

public class HelloTask extends Application {
    Button button;
    ProgressBar progress;

    @Override
    public void start(Stage stage) {
        GridPane grid = new GridPane();
        grid.setAlignment(Pos.CENTER);
        grid.setHgap(10);
        grid.setVgap(10);
        grid.setPadding(new Insets(25, 25, 25, 25));

        button = new Button("Click me!");
        button.setOnAction(this::handleClick);
        grid.add(button, 0, 0);

        progress = new ProgressBar();
        progress.setProgress(0);
        grid.add(progress, 0, 1);

        Scene scene = new Scene(grid);

        stage.setTitle("Hello Task!");
        stage.setScene(scene);
        stage.show();
    }

    ExecutorService executor = Executors.newCachedThreadPool();

    @Override
    public void stop() {
        executor.shutdown();
    }

    public void handleClick(ActionEvent event) {
        Task<String> task = new Task<String>() {
            @Override
            protected String call() {
                updateValue("Working...");

                for (int i = 0; i < 10; i++) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        return "Interrupted!";
                    }
                    updateProgress(i + 1, 10);
                }
                return "Done!";
            }
        };
        progress.progressProperty().bind(task.progressProperty());
        button.textProperty().bind(task.valueProperty());

        executor.submit(task);
    }
}

Upvotes: 5

Related Questions