问题描述
我有一个简单的JavaFX GUI,它在单击按钮时触发后台任务.该任务使用其最新的进度消息连续更新TextArea.我已在下面演示了如何解决此问题.当任务遇到错误,并且需要用户决定如何进行时,就会出现此问题.我的目标是通过用户选择是"或否"的警报来做出此决定.尽管如此,我仍然无法实现此功能.到目前为止,这是我尝试过的事情:
I have a simple JavaFX GUI that fires a background task on button click. This task continuously updates a TextArea with its latest progress messages. I have demonstrated how I solved this below. The issue arises when the task runs into an error, and requires a decision from the user on how to proceed. My goal is to have this decision made via an Alert, with the user choosing Yes or No. I've been unable to achieve this functionality, though. Here is what I have attempted so far:
- 在JavaFX主线程中创建一个Alert,将其传递给脚本,然后调用showAndWait.这导致出现错误,指示我不在JavaFX线程中.
- UpdateMessage()等.作为任务扩展脚本,我一直遇到NullPointerException.
- 从脚本创建新的JavaFX实例.
谢谢您的帮助!
使用EventHandler创建按钮:
Button creation with EventHandler:
private Button createButton() {
Button btn = new Button();
btn.setText("Run");
btn.setPrefWidth(100);
EventHandler<ActionEvent> buildWindow = new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
TextArea output = buildCenterTextArea();
Task task = new Task<Void>() {
@Override public Void call() {
callScript(output); // Calls script
return null;
}
};
new Thread(task).start();
}
};
btn.setOnAction(buildWindow);
return btn;
}
private void buildCenterTextArea() {
// Builds a text area which the script updates with status
TextArea output = new TextArea();
output.setEditable(false);
this.borderpane.setCenter(output);
return output
}
在我的脚本中,我通过执行以下操作来更新文本:
In my script, I update the text by doing the following:
output.setText(statusText+ "\n" + newStatus);
推荐答案
后台线程可以一直忙于等待.这意味着您可以创建一个 CompletableFuture
,使用 Platform.runLater
创建警报,并使用showAndWait显示警报,然后用结果填充未来.紧接着在后台线程上调用之后,使用 Future.get
等待结果.
The background thread can be kept busy waiting. This means you can create a CompletableFuture
, use Platform.runLater
to create an alert and displaying it using showAndWait and after that filling the future with the results. Just after this call on the background thread wait for the result using Future.get
.
下面的示例生成0到9(含)之间的随机数,并将0-8打印到 TextArea
. 9
是一个模拟错误,会询问用户是否应该继续执行任务.
The following example generates random numbers between 0 and 9 (inclusive) and prints 0-8 to the TextArea
. 9
is a simulated error and the user is asked, if the task should be continued.
@Override
public void start(Stage stage) throws IOException {
TextArea ta = new TextArea();
Thread thread = new Thread(() -> {
Random rand = new Random();
while (true) {
int i = rand.nextInt(10);
if (i == 9) {
CompletableFuture<ButtonType> future = new CompletableFuture<>();
// ask for user input
Platform.runLater(() -> {
Alert alert = new Alert(AlertType.CONFIRMATION);
alert.setContentText("An error occured. Continue?");
future.complete(alert.showAndWait().orElse(ButtonType.CANCEL)); // publish result
});
try {
if (future.get() == ButtonType.CANCEL) { // wait for user input on background thread
break;
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
break;
}
} else {
Platform.runLater(() ->ta.appendText(Integer.toString(i) + "\n"));
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
}
});
thread.setDaemon(true);
thread.start();
Scene scene = new Scene(new VBox(ta));
stage.setScene(scene);
stage.show();
}
这篇关于JavaFX:根据Task提示用户,并传回结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!