Платформа.runLater и задача в JavaFX



Я делал некоторые исследования по этому поводу, но я все еще очень смущен, чтобы не сказать больше.



кто может дать мне конкретный пример, когда использовать Task и когда использовать Platform.runLater(Runnable);? Какая разница? Есть ли золотое правило, когда использовать любой из них?



также поправьте меня, если я ошибаюсь, но не являются ли эти два "объекта" способом создания другого потока внутри основного потока в GUI (используется для обновления GUI)?

847   4  

4 ответов:

использовать Platform.runLater(...) для быстрых и простых операций и Task для сложных и больших операций .

пример: почему мы не можем использовать Platform.runLater(...) для длинных вычислений (взятых из приведенной ниже ссылки).

проблема: фоновый поток, который просто подсчитывает от 0 до 1 миллиона и обновляет индикатор выполнения ПОЛЬЗОВАТЕЛЬСКИЙ ИНТЕРФЕЙС.

код с помощью 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, чтобы упростить написание фона работники которые после этого связывают назад с пользовательский интерфейс.

код с помощью задачи:

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 (чтобы избежать замораживания вашего приложения), но все же нужно взаимодействовать с графическим интерфейсом на каком-то этапе.

если вы знакомы с качели, первый эквивалентно SwingUtilities.invokeLater и последнее к понятию SwingWorker.

The javadoc задачи дает много примеров, которые должны прояснить, как они могут быть использованы. Вы также можете обратиться к учебник по параллелизмом.

теперь его можно изменить на лямбда-версию

@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.runLater () может быть, что вы привязали свойство в пользовательском интерфейсе к свойству service (result). Поэтому, если вы обновите свойство связанного сервиса, вы должны сделать это через runLater ():

в потоке пользовательского интерфейса, также известном как поток приложения JavaFX:

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

в реализации службы (фоновый работник):

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

Comments

    Ничего не найдено.