如何正确地关闭javafx Alerts / fileChooser等
发布时间:2020-12-15 08:26:01 所属栏目:Java 来源:网络整理
导读:我正在看这个问题 JavaFX show dialogue after thread task is completed,但我的问题恰恰相反.在需要从用户返回一些数据的文件追踪器或警报之后,最好的方法是什么? 这就是我现在拥有的: Platform.runLater(()-{ File file = fileChooser.showOpenDialog(ro
我正在看这个问题
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一起使用. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |