JavaFX SwingWorker Equivalent?

有没有一个JavaFX等同于Java SwingWorker类?

我知道JavaFX任务,但有了它,你只能发布字符串消息或进度。我只想在GUI线程中调用一个方法,就像我对SwingWorker所做的那样(通过发布任意类型的消息)。

以下是我的意思的一个例子:

class PrimeNumbersTask extends
         SwingWorker<List<Integer>, Integer> {
     PrimeNumbersTask(JTextArea textArea, int numbersToFind) {
         //initialize
     }

      @Override
     public List<Integer> doInBackground() {
         while (! enough && ! isCancelled()) {
                 number = nextPrimeNumber();
                 publish(number);
                 setProgress(100 * numbers.size() / numbersToFind);
             }
         }
         return numbers;
     }

      @Override
     protected void process(List<Integer> chunks) {
         for (int number : chunks) {
             textArea.append(number + "\n"); // HERE: execute in GUI thread
         }
     }
 }

溶液

非常感谢您的回答。我正在寻找的解决方案是使用Platform.runLater(Runnable guiUpdater)。


答案 1

我会重写你的如下:SwingWorker

class PrimeNumbersTask extends Task<List<Integer>> {
    PrimeNumbersTask(TextArea textArea, int numbersToFind) {
        // initialize
    }

    @Override
    protected List<Integer> call() throws Exception {
        while (!enough && !isCancelled()) {
            number = nextPrimeNumber();
            updateMessage(Integer.toString(number));
            updateProgress(numbers.size(), numbersToFind);
        }
        return numbers;
    }
}

用法:

TextArea textArea = new TextArea();
PrimeNumbersTask task = new PrimeNumbersTask(numbersToFind);
task.messageProperty().addListener((w, o, n)->textArea.appendText(n + "\n"));
new Thread(task).start(); // which would actually start task on a new thread 

解释:

是的,我们没有像JavaFX中那样的方法,但是在您的情况下使用就足够了,因为我们可以将侦听器注册到此属性,并在每次更新消息时追加一个新行。publish()SwingWorkerupdateMessage()

如果这还不够,您可以随时使用 Platform.runLater() 来计划 GUI 更新。如果您正在执行太多 GUI 更新,并且 GUI 线程速度变慢,则可以使用以下成语:限制 javafx GUI 更新


答案 2

除了只能传递字符串的方法之外,还有一种可以传递整个对象的方法,因此我相信您可以以类似的方式使用它。此方法在任务文档的“返回部分结果的任务”部分中进行了介绍。另一种方法是其他答案中提到的方法。updateMessageupdateValuePlatform.runLater()

请注意,这些方法之间的一个重要区别是,第一种方法是合并结果,这意味着对于多个频繁的 updateValue 调用,可能会省略一些方法,以防止 FLOOD FX 线程泛滥。

另一方面,Platform.runLater方法将发送所有中期结果,但由于如果您有高频更新,则有淹没FX线程的危险,因此可能需要一些额外的努力来手动避免它,就像@eckig在他的答案中建议的那样,这指向限制javafx gui更新


推荐