代码之家  ›  专栏  ›  技术社区  ›  Starnec

Anticapte FileHooser关闭以中止正在运行的任务

  •  -3
  • Starnec  · 技术社区  · 5 月前

    在一个独特的 thread ,新鲜的 task 启动a file dialogue 通过a FileChooser 反对 节约 数据在 擅长 JSON 格式。

    这个 getFileSavingDialogue 方法通过以下方式启动文件选择器的保存对话框 Platform.runLater UI thread 因为这是一个UI操作

    此函数仅返回用户在单击后选择的文件 save button 对话。为了促进这一点 AtomicReference fileRef 使用。循环将一直持续到fileRef选择并引用文件为止。

    private File getFileSavingDialogue() {
            AtomicReference<File> fileRef = new AtomicReference<>();
    
            Platform.runLater(() -> {
                FileChooser fileChooser = new FileChooser();
                fileChooser.setTitle("Save publications");
                FileChooser.ExtensionFilter extFilter;
    
                if (Objects.equals(savingOption, "excel")) {
                    extFilter = new FileChooser.ExtensionFilter("Excel (*.csv)", "*.csv");
                    fileChooser.setInitialFileName("result.csv");
                } else {
                    extFilter = new FileChooser.ExtensionFilter("JSON file", "*.json");
                    fileChooser.setInitialFileName("result.json");
                }
                fileChooser.getExtensionFilters().add(extFilter);
    
                fileRef.set(fileChooser.showSaveDialog(parentWindow));
            });
    
            while (fileRef.get() == null) {
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    System.out.println(e.getMessage());
                }
            }
    
            return fileRef.get();
        }
    

    这是Task的调用方法:

    @Override
        protected Void call() {
            FINAL_PATH = getFileSavingDialogue().getAbsolutePath();
    
            try {
                Thread.sleep(3000);
    
                if (savingOption.equals("excel"))
                    if (saveToExcel())
                        System.out.println("Writing Excel file was successful");
                    else if (savingOption.equals("json"))
                        if (saveToJSON())
                            System.out.println("Writing JSON file was successful");
    
            } catch (InterruptedException e) {
                System.out.println(e.getMessage());
            }
            return null;
        }
    

    这是启动保存过程的按钮的事件处理程序:

     saveButton.setOnAction(event -> {
                saveButton.setDisable(true);
                backButton.setDisable(true);
    
                SavePublications saveDataTask = new SavePublications(rootNode.getScene().getWindow(), result);
    
                if (currentOption.equals("excel"))
                    saveDataTask.setSavingOption("excel");
                else
                    saveDataTask.setSavingOption("json");
    
                saveDataTask.setOnSucceeded(e -> {
                    saveButton.setDisable(false);
                    backButton.setDisable(false);
                });
    
                saveDataTask.setOnCancelled(e -> {
                    saveButton.setDisable(false);
                    backButton.setDisable(false);
                });
    
                new Thread(saveDataTask).start();
            });
    

    我的问题是,如果用户关闭该对话窗口 saveButton backButton 视图中的将被禁用,并且永远不会再次启用,因为 任务已启动,永远不会完成或被取消。

    我如何检测对话窗口是否已关闭并再次启用按钮?

    1 回复  |  直到 5 月前
        1
  •  4
  •   SedJ601    5 月前

    我认为你需要以不同的方式构建事物。看看这个例子和帮助。

    它使用FileHooser获取要保存到的文件。从那里,根据文件类型运行两个任务之一。

    package org.example;
    
    import javafx.application.Application;
    import javafx.concurrent.Task;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.control.ProgressBar;
    import javafx.scene.layout.VBox;
    import javafx.stage.FileChooser;
    import javafx.stage.FileChooser.ExtensionFilter;
    import javafx.stage.Stage;
    import java.io.File;
    import java.io.IOException;
    import java.nio.charset.StandardCharsets;
    import java.nio.file.Files;
    
    
    public class App extends Application {
        File saveFile;
        Task<Void> saveToFileTask;
    
        public static void main(String[] args) {
            launch(args);
        }
    
        public void start(Stage primaryStage) {
            primaryStage.setTitle("JavaFX WebView Example");
            Button btnSave = new Button("Save");
            Button btnCancel = new Button("Cancel");
            btnCancel.setDisable(true);
            ProgressBar progressBar = new ProgressBar();
            progressBar.setVisible(false);
    
            btnSave.setOnAction(actionEvent -> {
                saveFile = saveToFile(primaryStage);
                if(saveFile != null)
                {
                    btnSave.setDisable(true);
                    btnCancel.setDisable(false);
                    progressBar.setVisible(true);
                    if(saveFile.getName().endsWith(".csv"))
                    {
                        saveToFileTask = writeCsvFile(saveFile);
                    }
                    else
                    {
                        saveToFileTask = writeTsvFile(saveFile);
                    }
    
                    saveToFileTask.setOnSucceeded(onSucceeded -> {
                        btnSave.setDisable(false);
                        btnCancel.setDisable(true);
                        progressBar.setVisible(false);
                    });
                    saveToFileTask.setOnCancelled(onCancelled -> {
                        btnSave.setDisable(false);
                        btnCancel.setDisable(true);
                        progressBar.setVisible(false);
                    });
                    progressBar.progressProperty().bind(saveToFileTask.progressProperty());
                    Thread thread = new Thread(saveToFileTask);
                    thread.setDaemon(true);
                    thread.start();
                }
            });
    
            btnCancel.setOnAction(onAction -> {
                saveToFileTask.cancel();
            });
    
    
            VBox root = new VBox(btnSave, btnCancel, progressBar);
            Scene scene = new Scene(root, 960, 600);
    
            primaryStage.setScene(scene);
            primaryStage.show();
    
        }
    
        public File saveToFile(Stage stage)
        {
            FileChooser fileChooser = new FileChooser();
            fileChooser.setTitle("Save");
            fileChooser.getExtensionFilters().addAll(new ExtensionFilter("CSV file", "*.csv"), new ExtensionFilter("TSV file", "*.tsv"));
    
            return fileChooser.showSaveDialog(stage);
        }
    
        public Task<Void> writeCsvFile(File file)
        {
            Task<Void> writeToCsvFile = new Task<Void>() {
                @Override
                protected Void call(){
                    StringBuilder stringBuilder = new StringBuilder();
    
                    //Do do this! Use a library!
                    for(int i = 1; i <= 100; i++)
                    {
                        stringBuilder.append(i).append(",");
                        if(i % 10 == 0)
                        {
                            stringBuilder.append(System.lineSeparator());
                        }
                        //help simulate a long task!
                        try
                        {
                            Thread.sleep(50);
                        }
                        catch (InterruptedException e)
                        {
                            throw new RuntimeException(e);
                        }
    
                        updateProgress(i, 100);
                    }
    
                    try
                    {
                        System.out.println(stringBuilder.toString());
                        Files.write(file.toPath(), stringBuilder.toString().getBytes(StandardCharsets.UTF_8));
                    }
                    catch (IOException e)
                    {
                        throw new RuntimeException(e);
                    }
    
                    return null;
                }
            };
    
            return writeToCsvFile;
        }
    
        public Task<Void> writeTsvFile(File file)
        {
            Task<Void> writeToTsvFile = new Task<Void>() {
                @Override
                protected Void call(){
                    StringBuilder stringBuilder = new StringBuilder();
    
                    //Do do this! Use a library!
                    for(int i = 1; i <= 100; i++)
                    {
                        stringBuilder.append(i).append("\t");
                        if(i % 10 == 0)
                        {
                            stringBuilder.append(System.lineSeparator());
                        }
                        //help simulate a long task!
                        try
                        {
                            Thread.sleep(50);
                        }
                        catch (InterruptedException e)
                        {
                            throw new RuntimeException(e);
                        }
    
                        updateProgress(i, 100);
                    }
    
                    try
                    {
                        System.out.println(stringBuilder.toString());
                        Files.write(file.toPath(), stringBuilder.toString().getBytes(StandardCharsets.UTF_8));
                    }
                    catch (IOException e)
                    {
                        throw new RuntimeException(e);
                    }
    
                    return null;
                }
            };
    
            return writeToTsvFile;
        }
    }