Development Tip

JavaFX의 Platform.runLater 및 Task

yourdevel 2020. 10. 18. 19:43
반응형

JavaFX의 Platform.runLater 및 Task


나는 이것에 대해 약간의 연구를 해왔지만 여전히 가장 적게 말하는 것은 매우 혼란 스럽습니다.

누구든지 언제 사용 Task하고 언제 사용 Platform.runLater(Runnable);하는지에 대한 구체적인 예를 줄 수 있습니까 ? 차이점은 정확히 무엇입니까? 이들 중 어느 것을 언제 사용할 지에 대한 황금률이 ​​있습니까?

내가 틀렸지 만이 두 "객체"가 GUI의 메인 스레드 내부에 또 다른 스레드를 생성하는 방법이 아닌 경우에도 수정 해주세요 (GUI 업데이트에 사용됨)?


사용하여 Platform.runLater(...)빠르고 간단하게 작업하고 Task복잡하고 큰 작업.

예 : Platform.runLater(...)긴 계산에 사용할 수없는 이유 (아래 참조 참조).

문제 : 0에서 1 백만까지 계산되는 백그라운드 스레드와 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로 이벤트 대기열을 휩쓸 것입니다. 실제로는 백만 개입니다. 분명히 우리는 백그라운드 워커를 더 쉽게 작성하고 UI와 다시 통신 할 수 있도록 API가 필요했습니다.

Task를 사용하는 코드 :

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 implements the Worker interface which is used when you need to run a long task outside the GUI thread (to avoid freezing your application) but still need to interact with the GUI at some stage.

If you are familiar with Swing, the former is equivalent to SwingUtilities.invokeLater and the latter to the concept of SwingWorker.

The javadoc of Task gives many examples which should clarify how they can be used. You can also refer to the tutorial on concurrency.


It can now be changed to lambda version

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

One reason to use an explicite Platform.runLater() could be that you bound a property in the ui to a service (result) property. So if you update the bound service property, you have to do this via runLater():

In UI thread also known as the JavaFX Application thread:

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

in Service implementation (background worker):

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

참고URL : https://stackoverflow.com/questions/13784333/platform-runlater-and-task-in-javafx

반응형