我正在看这个问题
JavaFX show dialogue after thread task is completed,但我的问题恰恰相反.在需要从用户返回一些数据的文件追踪器或警报之后,最好的方法是什么?
这就是我现在拥有的:
Platform.runLater(()->{ File file = fileChooser.showOpenDialog(root.getScene().getwindow()); if(file == null) { return; } executorService.execute(()->{ //more code here which uses file }); });
其中executorService是先前创建的ExecutorService.我想我可以轻松地使用任务或线程或其他任何东西,但它如何被线程化无关紧要,只是因为它需要一段时间,我不希望在应用程序线程上发生它,因为它会锁定UI.
我知道这不是一个mvce,但我希望它能说明我在Platform.runLater调用中遇到的问题.
这是一个极端的例子,说明这种事情有多复杂
@FXML public void copyFiles(ActionEvent event){ //this method is on the application thread because a button or something started it // so we thread off here executorService.execute(()->{ // do some stuff // ... // get location to copy to from user // must happen on the application thread! Platform.runLater(()->{ File file = fileChooser.showOpenDialog(root.getScene().getwindow()); if(file == null) { return; } executorService.execute(()->{ // more code here which uses file // ... // oh wait,some files have the same names! // we need a user's confirmation before proceeding Platform.runLater(()->{ Alert alert = new Alert(AlertType.CONFIRMATION,"Do you want to overwrite files with the same names?",ButtonType.OK,ButtonType.CANCEL); Optional<ButtonType> choice = alert.showAndWait(); if(choice.isPresent && choice.get == ButtonType.OK){ // do something,but not on the application thread executorService.execute(()->{ // do the last of the copying // ... }); } }); }); }); }); }
解决方法
看来你的问题是需要在后台任务中间的信息,这些信息只能在JavaFX Application线程上检索. James_D给出的
answer使用
FutureTask
完美地工作.我想提供一个替代方案:
CompletableFuture
(在Java 8中添加).
public void copyFiles(ActionEvent event) { executorService.execute(() -> { // This uses CompletableFuture.supplyAsync(supplier,Executor) // need file from user File file = CompletableFuture.supplyAsync(() -> { // show FileChooser dialog and return result },Platform::runLater).join(); // runs on FX thread and waits for result if (file == null) { return; } // do some stuff // ask for confirmation boolean confirmed = CompletableFuture.supplyAsync(() -> { // show alert and return result },Platform::runLater).join(); // again,runs on FX thread and waits for result if (confirmed) { // do more stuff } }); }
FutureTask和CompletableFuture都适合您.我更喜欢CompletableFuture,因为它提供了更多选项(如果需要),而join()方法不会抛出像get()那样的已检查异常.但是,CompletableFuture是Future(就像FutureTask一样),因此您仍然可以将get()与CompletableFuture一起使用.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。