簡體   English   中英

JavaFX中的Platform.runLater和Task

[英]Platform.runLater and Task in JavaFX

我一直在研究這個問題,但至少我還是非常困惑。

任何人都可以給我一個具體的例子,說明何時使用Task以及何時使用Platform.runLater(Runnable); 究竟有什么區別? 什么時候使用其中任何一個是否有黃金法則?

如果我錯了也不糾正我,但這兩個“對象”不是在GUI中用於更新GUI的主線程內創建另一個線程的方法嗎?

使用Platform.runLater(...)進行快速簡單的操作,使用Task進行復雜和大型操作。

示例:為什么我們不能使用Platform.runLater(...)進行長時間計算(取自下面的參考)。

問題:后台線程只需0到100萬,並在UI中更新進度條。

使用Platform.runLater(...)代碼:

final ProgressBar bar = new ProgressBar();
new Thread(new Runnable() {
    @Override public void run() {
    for (int i = 1; i <= 1000000; i++) {
        final int counter = i;
        Platform.runLater(new Runnable() {
            @Override public void run() {
                bar.setProgress(counter / 1000000.0);
            }
        });
    }
}).start();

這是一段可怕的代碼,是對自然的犯罪(以及一般的編程)。 首先,只要看看Runnables的這種雙重嵌套,你就會失去腦細胞。 其次,它將使用少量Runnables來淹沒事件隊列 - 實際上有一百萬個。 顯然,我們需要一些API來更容易編寫后台工作程序,然后與UI進行通信。

代碼使用任務:

Task task = new Task<Void>() {
    @Override public Void call() {
        static final int max = 1000000;
        for (int i = 1; i <= max; i++) {
            updateProgress(i, max);
        }
        return null;
    }
};

ProgressBar bar = new ProgressBar();
bar.progressProperty().bind(task.progressProperty());
new Thread(task).start();

它沒有上一個代碼中顯示的任何缺陷

參考: JavaFX 2.0中的工作線程

  • Platform.runLater :如果需要從非GUI線程更新GUI組件,可以使用它來將更新放入隊列中,並盡快由GUI線程處理。
  • Task實現了Worker接口,當你需要在GUI線程外部運行一個長任務(以避免凍結你的應用程序)時使用它,但仍然需要在某個階段與GUI交互。

如果您熟悉Swing,前者相當於SwingUtilities.invokeLater ,后者則相當於SwingWorker的概念。

任務javadoc提供了許多示例,應該闡明如何使用它們。 您還可以參考有關並發的教程

它現在可以更改為lambda版本

@Override
public void actionPerformed(ActionEvent e) {
    Platform.runLater(() -> {
        try {
            //an event with a button maybe
            System.out.println("button is clicked");
        } catch (IOException | COSVisitorException ex) {
            Exceptions.printStackTrace(ex);
        }
    });
}

使用explicite Platform.runLater()的一個原因可能是您將ui中的屬性綁定到service(result)屬性。 因此,如果更新綁定服務屬性,則必須通過runLater()執行此操作:

在UI線程中也稱為JavaFX Application線程:

...    
listView.itemsProperty().bind(myListService.resultProperty());
...

在服務實現(后台工作者):

...
Platform.runLater(() -> result.add("Element " + finalI));
...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM