Úselo Platform.runLater(...)
para operaciones rápidas y simples y Task
para operaciones complejas y grandes.
Ejemplo: ¿Por qué no podemos usarlo Platform.runLater(...)
para cálculos largos? (Tomado de la referencia a continuación).
Problema: hilo en segundo plano que solo cuenta de 0 a 1 millón y actualiza la barra de progreso en la interfaz de usuario.
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 es un horrible trozo de código, un crimen contra la naturaleza (y la programación en general). Primero, perderá células cerebrales con solo mirar este doble anidamiento de Runnables. En segundo lugar, inundará la cola de eventos con pequeños Runnables, de hecho, un millón de ellos. Claramente, necesitábamos alguna API para facilitar la escritura de trabajadores en segundo plano que luego se comunican con la interfaz de usuario.
Código usando 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();
no tiene ninguno de los defectos exhibidos en el código anterior
Referencia:
Worker Threading en JavaFX 2.0
Platform.runLater
: Si necesita actualizar un componente GUI desde un subproceso que no es GUI, puede usarlo para poner su actualización en una cola y será manejada por el subproceso GUI tan pronto como sea posible.Task
implementa laWorker
interfaz que se usa cuando necesita ejecutar una tarea larga fuera del hilo de la GUI (para evitar congelar su aplicación) pero aún necesita interactuar con la GUI en algún momento.Si está familiarizado con Swing, el primero equivale
SwingUtilities.invokeLater
y el segundo al concepto deSwingWorker
.El javadoc de Task da muchos ejemplos que deberían aclarar cómo se pueden usar. También puede consultar el tutorial sobre simultaneidad .
fuente
Platform.runLater(new Runnable() {public void run() {updateYourGuiHere();}});
Ahora se puede cambiar a la versión 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); } }); }
fuente
Platform.runLater(() -> progressBar.setProgress(X/Y));
Una razón para usar un Platform.runLater () explícito podría ser que vinculó una propiedad en la interfaz de usuario a una propiedad de servicio (resultado). Entonces, si actualiza la propiedad del servicio vinculado, debe hacerlo a través de runLater ():
En el hilo de la interfaz de usuario también conocido como hilo de la aplicación JavaFX:
en la implementación del servicio (trabajador en segundo plano):
... Platform.runLater(() -> result.add("Element " + finalI)); ...
fuente