我可以一次更新我的TableView项目而不阻止UI线程吗?

时间:2017-05-30 15:46:27

标签: java javafx observable

我有两种方法。第一个从另一个类中的搜索方法中检索结果列表。

/* 2 - Retrieve list of results */
qmitResultsList = QMITSearchUtil.execute(URL, keyword);

/* 3 - Show results */
populateTable(qmitResultsList, tableView)

第二个,populateTable()通过调用:

一次性将所有项目添加到表格中
ObservableList<QMITResult> dataPriority = FXCollections.observableArrayList(
        qmitResultsList
);
tableView.setItems(dataPriority);

我的目标是在TableView实时处理时将每个新元素添加到TableView中。例如,我不想在第一个方法QMITSearchUtil.execute()中处理和返回整个列表,而是希望用返回的每个结果更新UI,一次一个。如何实现这一目标?我尝试了一些方法,例如使用Platform.runLater()黑客,但没有成功......

1 个答案:

答案 0 :(得分:0)

我发现了我的问题的答案。我首先为我的TableView定义ObservableList:

ObservableList<QMITResult> dataPriority = FXCollections.observableArrayList();

然后我将其传递给运行后台线程的execute()方法:

private void execute(String URL, String keyword, ObservableList<QMITResult> dataPriority) throws Exception {

        /* Download HTML page and create list of URLs from relevant links */
        Elements links = getLinkList(URL);

        List<QMITResult> qmitResults = new ArrayList<>();

        new Thread(() -> {
            for (Element link : links) {
                try {

                    /* Create a list of formatted URLs to loop through */
                    String linkText = link.toString();
                    String titleText = link.text();
                    String formattedLink = StringUtils.substringBetween(linkText, "<a href=\"", "\"").replace("\\", "/");

                    System.out.println(titleText);
                    System.out.println(formattedLink);

                    /* Create Word Document for each link and parse for keyword */
                    QMITResult qmitResultNode = null;
                    try {
                        qmitResultNode = parseDocument(keyword, formattedLink, titleText);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    qmitResults.add(qmitResultNode);
                    dataPriority.add(qmitResultNode);
                    Thread.sleep(200);


                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();

        tableView.setItems(dataPriority);

    }

结果是,在形成列表时,每个TableView项目都是单独发布的,而不会阻塞主UI线程。他们一次来一个。