运行一个函数后台Javafx
Running a function the background Javafx
我对 java 还是很陌生,我对为什么会发生这种情况感到困惑,当我单击一个按钮时,我创建了程序崩溃,直到操作完成 (SendPost();),问题是该函数发送一个 post 请求并解析响应,这大约需要 10 秒,因此 GUI 崩溃在 SendPost() 完成之前无法使用。我需要它以某种方式在后台 运行,这样当我添加计时器时它就不会一直崩溃。
这是我的按钮代码
EventHandler<ActionEvent> login = new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent event) {
SendPost();
}
};
您的程序正在发生的事情是您正在进行的调用在 JavaFX 线程工作时阻塞了它。发生这种情况时,您的界面将停止响应输入,使您的程序看起来像是 hung/crashed.
正如所评论的那样,您可以简单地启动一个新的普通线程来执行您需要的操作,因为重要的部分是将工作转移到另一个线程,保持应用程序线程响应。在这种情况下,您可以简单地这样做:
Thread th = new Thread(() -> {
sendPost();
});
th.setDaemon(true);
th.start();
不过,稍后您可能想查看任务 class,它为 JavaFX 中的后台任务提供了更多选项,并且使用起来非常愉快。这是一个使用它的示例程序:
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);
}
}
我对 java 还是很陌生,我对为什么会发生这种情况感到困惑,当我单击一个按钮时,我创建了程序崩溃,直到操作完成 (SendPost();),问题是该函数发送一个 post 请求并解析响应,这大约需要 10 秒,因此 GUI 崩溃在 SendPost() 完成之前无法使用。我需要它以某种方式在后台 运行,这样当我添加计时器时它就不会一直崩溃。
这是我的按钮代码
EventHandler<ActionEvent> login = new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent event) {
SendPost();
}
};
您的程序正在发生的事情是您正在进行的调用在 JavaFX 线程工作时阻塞了它。发生这种情况时,您的界面将停止响应输入,使您的程序看起来像是 hung/crashed.
正如所评论的那样,您可以简单地启动一个新的普通线程来执行您需要的操作,因为重要的部分是将工作转移到另一个线程,保持应用程序线程响应。在这种情况下,您可以简单地这样做:
Thread th = new Thread(() -> {
sendPost();
});
th.setDaemon(true);
th.start();
不过,稍后您可能想查看任务 class,它为 JavaFX 中的后台任务提供了更多选项,并且使用起来非常愉快。这是一个使用它的示例程序:
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);
}
}