Use Platform.runLater(...)
para operações rápidas e simples e Task
para operações complexas e grandes.
Exemplo: Por que não podemos usar Platform.runLater(...)
para cálculos longos (retirado da referência abaixo).
Problema: thread em segundo plano que conta apenas de 0 a 1 milhão e atualiza a barra de progresso na IU.
Código usando 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();
Este é um pedaço de código horrível, um crime contra a natureza (e a programação em geral). Primeiro, você perderá células cerebrais apenas olhando para este aninhamento duplo de Runnables. Em segundo lugar, vai inundar a fila de eventos com pequenos Runnables - um milhão deles na verdade. Claramente, precisávamos de alguma API para tornar mais fácil escrever workers em segundo plano que então se comunicam de volta com a UI.
Código usando tarefa:
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();
não sofre de nenhuma das falhas exibidas no código anterior
Referência:
Worker Threading em JavaFX 2.0
Platform.runLater
: Se você precisar atualizar um componente GUI de um thread não GUI, você pode usar isso para colocar sua atualização em uma fila e ela será tratada pelo thread GUI o mais rápido possível.Task
implementa aWorker
interface que é usada quando você precisa executar uma tarefa longa fora do thread da GUI (para evitar o congelamento de seu aplicativo), mas ainda precisa interagir com a GUI em algum estágio.Se você está familiarizado com o Swing, o primeiro é equivalente ao
SwingUtilities.invokeLater
e o último ao conceito deSwingWorker
.O javadoc de Task fornece muitos exemplos que devem esclarecer como eles podem ser usados. Você também pode consultar o tutorial sobre simultaneidade .
fonte
Platform.runLater(new Runnable() {public void run() {updateYourGuiHere();}});
Agora pode ser alterado para a versão lambda
@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); } }); }
fonte
Platform.runLater(() -> progressBar.setProgress(X/Y));
Um motivo para usar um Platform.runLater () explícito pode ser que você vinculou uma propriedade na interface do usuário a uma propriedade de serviço (resultado). Portanto, se você atualizar a propriedade do serviço vinculado, terá que fazer isso via runLater ():
No thread de IU também conhecido como thread de aplicativo JavaFX:
na implementação do serviço (trabalhador em segundo plano):
... Platform.runLater(() -> result.add("Element " + finalI)); ...
fonte