Платформа.runLater и задача в JavaFX
Я делал некоторые исследования по этому поводу, но я все еще очень смущен, чтобы не сказать больше.
кто может дать мне конкретный пример, когда использовать Task и когда использовать Platform.runLater(Runnable);? Какая разница? Есть ли золотое правило, когда использовать любой из них?
также поправьте меня, если я ошибаюсь, но не являются ли эти два "объекта" способом создания другого потока внутри основного потока в GUI (используется для обновления GUI)?
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