Plataforma.runLater y Tarea en JavaFX


He estado haciendo algunas investigaciones sobre esto, pero todavía estoy muy confundido por decir lo menos.

¿Puede alguien darme un ejemplo concreto de cuándo usar Task y cuándo usar Platform.runLater(Runnable);? ¿Cuál es exactamente la diferencia? ¿Hay una regla de oro para cuándo usar cualquiera de estos?

También corrígeme si me equivoco, pero ¿no son estos dos "Objetos" una forma de crear otro hilo dentro del hilo principal en una GUI (utilizada para actualizar la GUI)?

Author: RAnders00, 2012-12-09

4 answers

Use Platform.runLater(...) para operaciones rápidas y simples y Task para operaciones complejas y grandes .

Ejemplo: ¿Por qué no podemos usar Platform.runLater(...) para cálculos largos (Tomados de la siguiente referencia)?

Problema: Hilo de fondo que solo cuenta de 0 a 1 millón y actualizar 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 programación en general). Primero, perderás células cerebrales con solo mirar en este doble anidamiento de Runnables. En segundo lugar, va a inundar la cola de eventos con poco Runnables - un millón de ellos de hecho. Claramente, necesitábamos alguna API para que fuera más fácil escribir en segundo plano trabajadores que luego se comunican con la interfaz de usuario.

Código usando Tarea :

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();

Sufre de ninguno de los defectos exhibidos en el código anterior

Referencia: Worker Threading en JavaFX 2.0

 82
Author: invariant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-23 13:22:12
  • Platform.runLater: Si necesita actualizar un componente GUI de un subproceso no 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 la interfaz Worker que se usa cuando necesita ejecutar una tarea larga fuera del subproceso de la GUI (para evitar congelar su aplicación) pero aún necesita interactuar con la GUI en algún momento.

Si estás familiarizado con el Swing, el primero es equivalente a SwingUtilities.invokeLater y el segundo al concepto de SwingWorker.

El javadoc de Task da muchos ejemplos que deberían aclarar cómo se pueden usar. También puede consultar el tutorial sobre concurrencia.

 48
Author: assylias,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-29 15:47:19

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);
        }
    });
}
 9
Author: Caglar Sekmen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-23 14:52:35

Una razón para usar una plataforma explicite.runLater () podría ser que vinculó una propiedad en la interfaz de usuario a una propiedad de servicio (resultado). Así que si actualizas la propiedad bound service, tienes que hacerlo a través de runLater ():

En el subproceso de interfaz de usuario también conocido como el subproceso de aplicación JavaFX:

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

En la implementación del servicio (background worker):

...
Platform.runLater(() -> result.add("Element " + finalI));
...
 2
Author: Alexander Pietsch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-17 09:55:24