我可以一次更新我的TableView项目而不阻塞UI线程吗?
我有两种方法。第一个检索另一个类中搜索方法的结果列表。我可以一次更新我的TableView项目而不阻塞UI线程吗?
/* 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中,因为它是在实时被处理。例如,我不想在第一种方法中处理并返回整个列表QMITSearchUtil.execute()
,而是想每次更新返回的每个结果的UI。这如何实现?我尝试了几种方法,例如使用Platform.runLater()
黑客,但没有成功......
我发现了我的问题的答案。我首先定义ObservableList我的TableView:
ObservableList<QMITResult> dataPriority = FXCollections.observableArrayList();
然后,我传递到运行的后台线程的方法:
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线程。他们每次来一个。
这是我的问题的答案。我只是在努力工作而已。 – santafebound
好的。我以为你正在更新你的问题。抱歉! – Sedrick
那么,答案是不正确的。您正在从后台线程更新UI,这是JavaFX线程规则所不允许的。您需要在'Platform.runLater(...)'中将调用包装为'dataPriority.add(qmitResultNode)'。 –
您可以通过在后台线程中检索结果并将其添加到Platform.runLater()中的表中来进行此操作(假设不会频繁地调用Platform.runLater(...) 。你为什么将'Platform.runLater(...)'作为黑客?这基本上就是它所设计的。 –
我会尝试检索我所做的并显示我所尝试的内容。 – santafebound
'populateTable(qmitResultsList,tableView)':这看起来像你正在更新支持'ObservableList'的列表而不是'ObservableList'本身,导致没有通知被'ObservableList'触发,这意味着'TableView'获胜't'看到“任何改变(除非你永远不修改列表,只更新已经在列表中的元素)... – fabian