我可以一次更新我的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()黑客,但没有成功......

+1

您可以通过在后台线程中检索结果并将其添加到Platform.runLater()中的表中来进行此操作(假设不会频繁地调用Platform.runLater(...) 。你为什么将'Platform.runLater(...)'作为黑客?这基本上就是它所设计的。 –

+0

我会尝试检索我所做的并显示我所尝试的内容。 – santafebound

+0

'populateTable(qmitResultsList,tableView)':这看起来像你正在更新支持'ObservableList'的列表而不是'ObservableList'本身,导致没有通知被'ObservableList'触发,这意味着'TableView'获胜't'看到“任何改变(除非你永远不修改列表,只更新已经在列表中的元素)... – fabian

我发现了我的问题的答案。我首先定义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线程。他们每次来一个。

+1

这是我的问题的答案。我只是在努力工作而已。 – santafebound

+0

好的。我以为你正在更新你的问题。抱歉! – Sedrick

+0

那么,答案是不正确的。您正在从后台线程更新UI,这是JavaFX线程规则所不允许的。您需要在'Platform.runLater(...)'中将调用包装为'dataPriority.add(qmitResultNode)'。 –