JavaFX SwingWorker Equivalent?

試著忘記壹切 提交于 2019-11-27 15:08:46
eckig

I would rewrite your SwingWorker as follows:

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;
    }
}

Usage:

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 

Explanation:

Yes, we do not have a publish() method as the SwingWorker does in JavaFX, but in your case using the updateMessage() is sufficient, as we can register a listener to this property and append a new line every time the message is updated.

If this is not enough, you can always use Platform.runLater() to schedule GUI updates. If you are doing too many GUI updates and the GUI Thread is being slowed down, you can use the following idiom: Throttling javafx gui updates

Marios

Apart from the updateMessage method where you can only pass strings, there is the updateValue method where you can pass a whole object, so I believe you can use that in a similar manner. This approach is described in the "A Task Which Returns Partial Results" section of the Task documentation. Another approach is the Platform.runLater() approach mentioned also in other answer.

Note that an important difference between these approaches, is that the first one is coalescing the results, which means that for multiple frequent updateValue calls some may be omitted in order to protect flooding the FX thread.

On the other hand, the Platform.runLater approach will send all the interim results, but due to the danger of flooding the FX thread if you have high frequency updates, some additional effort may be needed to manually avoid it like @eckig suggested in his answer which points to Throttling javafx gui updates

Don't ever use SwingWorker. This piece of code in the SwingWorker.java source should be enough of an argument to not use it:

private static final int MAX_WORKER_THREADS = 10;

Instead get yourself familiar with Executor and the services that come along with it.

It has nothing to do with JavaFX, it's just plain Java. However, your question was related to JavaFX. Here's an example about how to Update UI in JavaFX Application Thread using Platform.runLater().

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!