为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

BIG阳 2023-10-12 16:49:18
我试图在 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();        }    }
查看完整描述

1 回答

?
江户川乱折腾

TA贡献1851条经验 获得超5个赞

您必须调用JavaFX 应用程序线程FileChooser#showXXXDialog上的方法。如果您发现任务失败,您将看到一条消息,说明您尝试在错误的线程上执行操作。此外,您不需要后台任务来提示用户输入文件。IllegalStateException


Task下面是提示用户输入文本文件、读取 a 中的文本文件并将结果放入 a 中的示例ListView。


App.java


package 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 {


  @Override

  public void start(Stage primaryStage) throws IOException {

    Scene scene = new Scene(FXMLLoader.load(getClass().getResource("/App.fxml")));

    primaryStage.setScene(scene);

    primaryStage.setTitle("FileChooser Example");

    primaryStage.show();

  }


}

应用程序.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"

      prefHeight="400" alignment="CENTER" fx:controller="com.example.Controller">

    <padding>

        <Insets topRightBottomLeft="5"/>

    </padding>

    <Button text="Open File..." onAction="#handleOpenFile"/>

    <Separator/>

    <ListView fx:id="listView" VBox.vgrow="ALWAYS"/>

</VBox>

Controller.java


package 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 {


  private final Executor executor = Executors.newSingleThreadExecutor(r -> {

    Thread t = new Thread(r, "controller-thread");

    t.setDaemon(true);

    return t;

  });


  @FXML private ListView<String> listView;


  @FXML

  private void handleOpenFile(ActionEvent event) {

    event.consume();


    FileChooser chooser = new FileChooser();

    chooser.getExtensionFilters()

        .add(new ExtensionFilter("Text Files", "*.txt", "*.json", "*.xml", "*.html", "*.java"));


    File file = chooser.showOpenDialog(listView.getScene().getWindow());

    if (file != null) {

      ReadFileTask task = new ReadFileTask(file.toPath());

      task.setOnSucceeded(wse -> listView.setItems(FXCollections.observableList(task.getValue())));

      task.setOnFailed(wse -> task.getException().printStackTrace());

      executor.execute(task);

    }

  }


  private static class ReadFileTask extends Task<List<String>> {


    private final Path file;


    private ReadFileTask(Path file) {

      this.file = Objects.requireNonNull(file);

    }


    @Override

    protected List<String> call() throws Exception {

      return Files.readAllLines(file);

    }


  }


}



查看完整回答
反对 回复 2023-10-12
  • 1 回答
  • 0 关注
  • 62 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信