2016-08-30 4 views
0

Ich bin wirklich Anfänger mit javaFX und wahrscheinlich vermisse ich etwas, aber hier mein Problem: Ich sollte einige Änderungen in meiner GUI-Anwendung nacheinander zeigen.Verzögerung hinzufügen nach Platform.runLater runnable

Mein Code sieht wie folgt aus (jede Methode führt eine Änderung der gui, aber das Endergebnis wird durch die letzte Methode natürlich angegeben):

public void updateGui() 
{ 
    Platform.runLater(() -> { 
     doFirstStuff(); 
     doSecondStuff(); 
     doThirdStuff(); 
    }); 
} 

Es wäre, wenn zwischen der Ausführung von jedem nett sein Methode gab es eine kleine Verzögerung (1,2 oder vielleicht 3 Sekunden), um dem Benutzer Zeit zu geben, um zu sehen, was in der Anwendung passiert ist.

war mein Versuch setzen:

Thread.sleep(1000); 

nach jedem Methodenaufruf, aber da das Gewinde der JavaFX Anwendung Faden ist, ist das Ergebnis schrecklich.

andere Lösung, die jetzt in meinem Kopf kommt ist:

() -> { 
    Platform.runLater(() -> { 
     doFirstStuff(); 
    }); 
    Thread.sleep(1000); 
}); 

und in updateGui() senden Sie die Aufgabe in einem newSingleThreadExecutor() und warten:

jede Methode in einem anderen mit einem Runnable wie dieser Thread ausführen für die Beendigung jeder Aufgabe. Aber ich weiß nicht, es scheint keine gute Lösung zu sein.

Was ist der beste Weg, um mein Ziel zu erreichen?

Antwort

4

Der einfachste Weg ist nur Timeline ein verwenden:

public void updateGui() { 
    final KeyFrame kf1 = new KeyFrame(Duration.seconds(0), e -> doFirstStuff()); 
    final KeyFrame kf2 = new KeyFrame(Duration.seconds(1), e -> doSecondStuff()); 
    final KeyFrame kf3 = new KeyFrame(Duration.seconds(2), e -> doThirdStuff()); 
    final Timeline timeline = new Timeline(kf1, kf2, kf3); 
    Platform.runLater(timeline::play); 
} 

ich hier davon aus, dass updateGui() auf einem Hintergrund-Thread aufgerufen wird (sonst nur Platform.runLater(...) entfernen und timeline.play() direkt aufrufen).

Wenn Sie wirklich mit Fäden die Hände schmutzig erhalten möchten, können Sie die gleichen (mehr oder weniger) erreichen könnte mit

public void updateGui() { 

    Thread thread = new Thread(() -> { 
     try { 
      Platform.runLater(() -> doFirstStuff()); 
      Thread.sleep(1000); 
      Platform.runLater(() -> doSecondStuff()); 
      Thread.sleep(1000); 
      Platform.runLater(() -> doThirdStuff()); 
     } catch (InterrupedException exc) { 
      // should not be able to get here... 
      throw new Error("Unexpected interruption"); 
     } 
    }; 
    thread.start(); 
} 

aber ich denke, für Fälle wie diese, die Timeline (oder anderen Teilen die Animations-API) sind viel sauberer (und verwenden weniger Ressourcen, da sie keinen neuen Thread erstellen).

+0

Wie funktioniert das? 'Platform.runLater (timeline :: play); } 'erste Mal gesehen .. – GOXR3PLUS

+1

@ GoXr3Plus Es ist eine [Methodenreferenz] (https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html). Es entspricht "Platform.runLater() -> timeline.play())". Da die Signatur von 'timeline.play()' (no params, kein Rückgabewert) mit der Signatur der abstrakten Methode in 'Runnable' übereinstimmt, können Sie einfach eine Methodenreferenz anstelle der Implementierung von' Runnable.run übergeben() '. –

+0

Danke! Genau das, was ich brauchte! Ich habe beide und sogar meine 'newSingleThreadExecutor()' Lösung versucht, alles funktioniert gut für meinen Zweck, aber ich denke, 'Timeline' Weg ist das beste für diese Art von Problemen. Ja, ich rufe 'updateGui()' von einem Hintergrund-Thread (vielleicht hätte ich angeben sollen, tut mir leid). Letzte Sache: Warum der "final" Modifikator auf 'KeyFrames' und' Timeline'? –

Verwandte Themen