Plate.exécution et tâches en JavaFX

j'ai fait quelques recherches à ce sujet mais je suis encore très confus pour dire le moins.

est-ce que quelqu'un peut me donner un exemple concret de quand utiliser Task et quand utiliser Platform.runLater(Runnable); ? Quelle est exactement la différence? Est-il une règle d'or pour quand utiliser l'un de ces?

corrigez-moi aussi si je me trompe, mais ces deux" objets " ne sont-ils pas une façon de créer un autre thread à l'intérieur du thread principal dans une interface graphique (utilisée pour mettre à jour l'interface graphique)?

66
demandé sur RAnders00 2012-12-09 07:25:20

4 réponses

utiliser Platform.runLater(...) pour des opérations simples et rapides et Task pour des opérations complexes et grandes .

exemple: Pourquoi ne pas utiliser Platform.runLater(...) pour les longs calculs (tiré de la référence ci-dessous).

problème: Fil de fond qui ne compte que de 0 à 1 million et mettre à jour la barre de progression dans L'UI.

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

c'est un hideux morceau de code, un crime contre la nature (et la programmation en général). D'abord, vous perdrez des cellules cérébrales juste en regardant à ce double nid de Runnables. Deuxièmement, il va marais de la file d'attente d'événements avec petits Runnables - a millions d'entre eux en fait. Clairement, nous avions besoin D'une API pour faciliter l'écriture de background travailleurs qui communiquent ensuite avec L'IU.

Code utilisant la tâche:

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

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

référence: Travailleur Filetage en JavaFX 2.0

82
répondu invariant 2017-06-23 13:22:12
  • Platform.runLater : si vous avez besoin de mettre à jour un composant GUI à partir d'un thread non-GUI, vous pouvez l'utiliser pour mettre votre mise à jour dans une file d'attente et il sera manipulé par le thread GUI dès que possible.
  • Task implémente l'interface Worker qui est utilisée lorsque vous avez besoin d'exécuter une tâche longue en dehors du thread GUI (pour éviter de geler votre application) mais que vous avez encore besoin d'interagir avec l'interface GUI à un certain stade.

If vous êtes familier avec le Swing, le premier est équivalent à SwingUtilities.invokeLater et le second à la notion de SwingWorker .

le javadoc de la tâche donne de nombreux exemples qui devraient clarifier comment ils peuvent être utilisés. Vous pouvez également vous référer à le tutoriel sur la concurrence .

48
répondu assylias 2016-12-29 15:47:19

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);
        }
    });
}
9
répondu Caglar Sekmen 2016-01-23 14:52:35

l'Une des raisons pour utiliser un explicite Plate-forme.runLater () pourrait être que vous liiez une propriété de l'ui à une propriété de service (résultat). Ainsi, si vous mettez à jour la propriété bound service, vous devez le faire via runLater ():

en UI thread aussi connu sous le nom de JavaFX application thread:

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

dans la mise en œuvre des Services en arrière-plan (travailleurs):

...
Platform.runLater(() -> result.add("Element " + finalI));
...
2
répondu Alexander Pietsch 2015-07-17 09:55:24