Platform.runLater et Task dans JavaFX

J’ai fait des recherches à ce sujet mais je suis toujours très confus pour le moins qu’on puisse dire.

Quelqu’un peut-il me donner un exemple concret de quand utiliser Task et quand utiliser Platform.runLater(Runnable); ? Quelle est exactement la différence? Y a-t-il une règle d’or à utiliser quand on en utilise?

Corrigez-moi également si je me trompe, mais ces deux “objects” ne sont-ils pas un moyen de créer un autre thread à l’intérieur du thread principal dans une interface graphique (utilisée pour mettre à jour l’interface graphique)?

    Utilisez Platform.runLater(...) pour des opérations simples et rapides et des Task pour des opérations complexes et volumineuses.

    • Cas d’utilisation pour Platform.runLater(...)
    • Cas d’utilisation de la Task : exemple de tâche dans l’application Ensemble

    Exemple: Pourquoi ne pouvons-nous pas utiliser Platform.runLater(...) pour des calculs longs (extraits de la référence ci-dessous).

    Problème: Le thread d’arrière-plan ne compte que de 1 à 1 million et met à jour la barre de progression dans l’interface utilisateur.

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

    Ceci est un morceau de code hideux, un crime contre nature (et la programmation en général). Tout d'abord, vous allez perdre les cellules du cerveau simplement en regardant cette double imbrication de Runnables. Deuxièmement, il va submerger la file d’événements avec des petits Runnables - un million d’entre eux en fait. De toute évidence, nous avions besoin d'une API pour faciliter l'écriture des travailleurs de fond qui communiquaient ensuite avec l'interface utilisateur.

    Code utilisant la tâche:

     Task task = new Task() { @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(); 

    il ne souffre d'aucun des défauts exposés dans le code précédent

    Référence: threading de travail dans JavaFX 2.0

    • Platform.runLater : Si vous avez besoin de mettre à jour un composant GUI depuis un thread non-GUI, vous pouvez l’utiliser pour mettre votre mise à jour dans une queue et il sera géré par le thread d’interface graphique dès que possible.
    • Task implémente l’interface de Worker utilisée lorsque vous devez exécuter une longue tâche en dehors du thread d’interface graphique (pour éviter de geler votre application) mais que vous devez toujours interagir avec l’interface graphique.

    Si vous êtes familier avec Swing, le premier est équivalent à SwingUtilities.invokeLater et le second au concept de SwingWorker .

    Le javadoc de Tâche donne de nombreux exemples qui devraient clarifier la manière dont ils peuvent être utilisés. Vous pouvez également vous référer au tutoriel sur la concurrence .

    Il peut maintenant être changé en version 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); } }); } 

    Une des raisons d’utiliser une Platform.runLater () explicite pourrait être que vous avez lié une propriété dans l’interface utilisateur à une propriété de service (résultat). Donc, si vous mettez à jour la propriété du service lié, vous devez le faire via runLater ():

    Dans le thread d’interface utilisateur, également appelé thread d’application JavaFX:

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

    dans l’implémentation du service (travailleur en arrière-plan):

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