JavaFX:根据任务提示用户,并传回结果?
我有一个简单的JavaFXGUI,可以在点击按钮时触发后台任务。此任务使用最新的进度消息持续更新TextArea。我已经在下面演示了如何解决这个问题。当任务遇到错误时会出现问题,需要用户决定如何继续。我的目标是通过警报做出这个决定,用户选择是或否。不过,我一直无法实现这个功能。以下是我迄今为止所做的尝试:JavaFX:根据任务提示用户,并传回结果?,java,javafx,Java,Javafx,我有一个简单的JavaFXGUI,可以在点击按钮时触发后台任务。此任务使用最新的进度消息持续更新TextArea。我已经在下面演示了如何解决这个问题。当任务遇到错误时会出现问题,需要用户决定如何继续。我的目标是通过警报做出这个决定,用户选择是或否。不过,我一直无法实现这个功能。以下是我迄今为止所做的尝试: 在JavaFX主线程中创建警报,将其传递给脚本,然后调用showAndWait。这导致了一个错误,表明我不在JavaFX线程中 UpdateMessage()等。将脚本扩展为任务时,我不断遇
- 在JavaFX主线程中创建警报,将其传递给脚本,然后调用showAndWait。这导致了一个错误,表明我不在JavaFX线程中
- UpdateMessage()等。将脚本扩展为任务时,我不断遇到NullPointerException
- 从脚本创建新的JavaFX实例
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
}
后台线程可以一直忙着等待。这意味着您可以创建一个
CompletableFuture
,使用Platform.runLater
创建一个警报,并使用show和wait显示它,然后用结果填充future。在后台线程上进行此调用之后,使用Future.get
等待结果
以下示例生成0到9(含)之间的随机数,并将0-8打印到文本区域<代码>9
是一个模拟错误,会询问用户是否应继续执行任务
@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();
}
@覆盖
public void start(Stage)引发IOException{
TextArea ta=新TextArea();
线程=新线程(()->{
Random rand=新的Random();
while(true){
int i=兰特·耐克斯汀(10);
如果(i==9){
CompletableFuture=新的CompletableFuture();
//请求用户输入
Platform.runLater(()->{
警报警报=新警报(警报类型.确认);
alert.setContentText(“发生错误。是否继续?”);
future.complete(alert.showAndWait().orElse(ButtonType.CANCEL));//发布结果
});
试一试{
如果(future.get()==ButtonType.CANCEL){//在后台线程上等待用户输入
打破
}
}捕获(中断异常|执行异常e){
e、 printStackTrace();
打破
}
}否则{
Platform.runLater(()->ta.appendText(Integer.toString(i)+“\n”);
试一试{
睡眠(500);
}捕捉(中断异常e){
e、 printStackTrace();
打破
}
}
}
});
setDaemon(true);
thread.start();
场景=新场景(新VBox(ta));
舞台场景;
stage.show();
}
这里可能会有帮助:后台线程可以一直忙着等待。这意味着您可以创建一个CompletableFuture
,使用Platform.runLater
创建一个警报,并使用show和wait
显示它,然后用结果填充future。在后台线程上进行此调用之后,使用Future.get
等待结果。。。
@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();
}