单击按钮时 JavaFX 在新线程上运行任务

我试图在 JavaFX 中单击按钮时检索 XLS 文件并将其加载到 TableView 中。我正在使用 Task 类和 ExecutorService 来启动新线程。我需要阅读器类可重用,但 FileChooser 没有显示。


这是我尝试编写一些并发代码。我想知道我做错了什么以及如何改进我的代码,因为一切都是事件驱动的?


控制器类代码


public void retrieveCustomersFromXLS() {

        try {

            loader.setOnSucceeded(workerStateEvent -> {

                File file = null;

                try {

                    file = loader.get();

                } catch (Exception e) {

                    e.printStackTrace();

                }

                if (file != null && file.exists()) {

                    reader.setWorkingFile(file);

                    executor.submit(reader);

                }

            });

            reader.setOnSucceeded(workerStateEvent1 -> {

                Object[][] XLSFile = new Object[0][];

                try {

                    XLSFile = reader.get();

                } catch (Exception e) {

                    e.printStackTrace();

                }

                if (XLSFile != null) {

                    tableInterface.setEntries(XLSFile);

                    tableInterface.setEntryType("customers");

                    executor.submit(tableInterface);

                }

            });

            executor.submit(loader);

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

BIG阳
浏览 63回答 1
1回答

江户川乱折腾

您必须调用JavaFX 应用程序线程FileChooser#showXXXDialog上的方法。如果您发现任务失败,您将看到一条消息,说明您尝试在错误的线程上执行操作。此外,您不需要后台任务来提示用户输入文件。IllegalStateExceptionTask下面是提示用户输入文本文件、读取 a 中的文本文件并将结果放入 a 中的示例ListView。App.javapackage com.example;import java.io.IOException;import javafx.application.Application;import javafx.fxml.FXMLLoader;import javafx.scene.Scene;import javafx.stage.Stage;public class App extends Application {&nbsp; @Override&nbsp; public void start(Stage primaryStage) throws IOException {&nbsp; &nbsp; Scene scene = new Scene(FXMLLoader.load(getClass().getResource("/App.fxml")));&nbsp; &nbsp; primaryStage.setScene(scene);&nbsp; &nbsp; primaryStage.setTitle("FileChooser Example");&nbsp; &nbsp; primaryStage.show();&nbsp; }}应用程序.fxml<?xml version="1.0" encoding="UTF-8"?><?import javafx.geometry.Insets?><?import javafx.scene.control.Button?><?import javafx.scene.control.ListView?><?import javafx.scene.control.Separator?><?import javafx.scene.layout.VBox?><VBox xmlns="http://javafx.com/javafx/13" xmlns:fx="http://javafx.com/fxml/1" spacing="5" prefWidth="600"&nbsp; &nbsp; &nbsp; prefHeight="400" alignment="CENTER" fx:controller="com.example.Controller">&nbsp; &nbsp; <padding>&nbsp; &nbsp; &nbsp; &nbsp; <Insets topRightBottomLeft="5"/>&nbsp; &nbsp; </padding>&nbsp; &nbsp; <Button text="Open File..." onAction="#handleOpenFile"/>&nbsp; &nbsp; <Separator/>&nbsp; &nbsp; <ListView fx:id="listView" VBox.vgrow="ALWAYS"/></VBox>Controller.javapackage com.example;import java.io.File;import java.nio.file.Files;import java.nio.file.Path;import java.util.List;import java.util.Objects;import java.util.concurrent.Executor;import java.util.concurrent.Executors;import javafx.collections.FXCollections;import javafx.concurrent.Task;import javafx.event.ActionEvent;import javafx.fxml.FXML;import javafx.scene.control.ListView;import javafx.stage.FileChooser;import javafx.stage.FileChooser.ExtensionFilter;public class Controller {&nbsp; private final Executor executor = Executors.newSingleThreadExecutor(r -> {&nbsp; &nbsp; Thread t = new Thread(r, "controller-thread");&nbsp; &nbsp; t.setDaemon(true);&nbsp; &nbsp; return t;&nbsp; });&nbsp; @FXML private ListView<String> listView;&nbsp; @FXML&nbsp; private void handleOpenFile(ActionEvent event) {&nbsp; &nbsp; event.consume();&nbsp; &nbsp; FileChooser chooser = new FileChooser();&nbsp; &nbsp; chooser.getExtensionFilters()&nbsp; &nbsp; &nbsp; &nbsp; .add(new ExtensionFilter("Text Files", "*.txt", "*.json", "*.xml", "*.html", "*.java"));&nbsp; &nbsp; File file = chooser.showOpenDialog(listView.getScene().getWindow());&nbsp; &nbsp; if (file != null) {&nbsp; &nbsp; &nbsp; ReadFileTask task = new ReadFileTask(file.toPath());&nbsp; &nbsp; &nbsp; task.setOnSucceeded(wse -> listView.setItems(FXCollections.observableList(task.getValue())));&nbsp; &nbsp; &nbsp; task.setOnFailed(wse -> task.getException().printStackTrace());&nbsp; &nbsp; &nbsp; executor.execute(task);&nbsp; &nbsp; }&nbsp; }&nbsp; private static class ReadFileTask extends Task<List<String>> {&nbsp; &nbsp; private final Path file;&nbsp; &nbsp; private ReadFileTask(Path file) {&nbsp; &nbsp; &nbsp; this.file = Objects.requireNonNull(file);&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; protected List<String> call() throws Exception {&nbsp; &nbsp; &nbsp; return Files.readAllLines(file);&nbsp; &nbsp; }&nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java