À utiliser Platform.runLater(...)
pour des opérations rapides et simples et Task
pour des opérations complexes et importantes.
Exemple: Pourquoi ne pouvons-nous pas utiliser Platform.runLater(...)
pour de longs calculs (tirés de la référence ci-dessous).
Problème: thread d'arrière-plan qui ne compte que de 0 à 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();
C'est un morceau de code hideux, un crime contre la nature (et la programmation en général). Tout d'abord, vous perdrez des cellules cérébrales rien qu'en regardant cette double imbrication de Runnables. Deuxièmement, cela va submerger la file d'attente des événements avec de petits Runnables - un million d'entre eux en fait. De toute évidence, nous avions besoin d'une API pour faciliter l'écriture de travailleurs d'arrière-plan qui communiquent ensuite avec l'interface utilisateur.
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 présentés dans le code précédent
Référence:
Worker Threading dans JavaFX 2.0
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 elle sera gérée par le thread GUI dès que possible.Task
implémente l'Worker
interface qui est utilisée lorsque vous avez besoin d'exécuter une longue tâche en dehors du thread GUI (pour éviter de geler votre application) mais que vous avez encore besoin d'interagir avec l'interface graphique à un moment donné.Si vous êtes familier avec Swing, le premier équivaut à
SwingUtilities.invokeLater
et le second au concept deSwingWorker
.Le javadoc de Task donne de nombreux exemples qui devraient clarifier comment ils peuvent être utilisés. Vous pouvez également vous référer au tutoriel sur la concurrence .
la source
Platform.runLater(new Runnable() {public void run() {updateYourGuiHere();}});
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); } }); }
la source
Platform.runLater(() -> progressBar.setProgress(X/Y));
Une raison d'utiliser une explicite Platform.runLater () 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:
dans la mise en œuvre du service (travailleur en arrière-plan):
... Platform.runLater(() -> result.add("Element " + finalI)); ...
la source