Swing Eine Sekunde warten (Timer)

Pfaeff

Aktives Mitglied
Hallo,

Ich habe eine Anwendung, die bestimmte Berechnungen durchführt und die Zwischenschritte auf einer Gui ausgibt.
Ich möchte zwischen den einzelnen Aktionen eine gewisse Pause haben. Ich habe das bisher wie folgt versucht:

Java:
		Timer timer = new Timer();
		timer.schedule(new TimerTask() {
		    public void run() {
		    	doSomething();
		    }
		}, 1000);
Das klappt die meiste Zeit wunderbar. Allerdings glaube ich, dass diese Methode dann in einem Hintergrund-Thread ausgeführt wird und dann mit anderen Methoden interferiert. Ich habe eine Konsolenausgabe gebaut und festgestellt, dass es passiert, dass "doSomething" während einer anderen Methode aufgerufen wird. Das ist natürlich fatal.

Jetzt suche ich nach einer geeigneten Lösung. Wenn ich den Code durch Thread.sleep(1000); ersetze, wird die Gui nicht mehr neugezeichnet. Was ist also die beste Lösung?

Vielen Dank.
 
Für sowas ist der SwingWorker geeignet. Hier kannst du in seiner berechnenden Methode durchaus ein
Code:
Thread.sleep()
einbauen. Der Worker läuft selbst als Thread, daher lässt er die GUI nicht einfrieren. Natürlich liegt es dennoch in deiner Verantwortung, für Zugriffssicherheit zu sorgen.
 
Also wenn das doSomething im GUI Thread ausgeführt werden soll gibt es da diverse Möglichkeiten.

Für Swing z.B. kannst du SwingUtilities.invokeAndWait aufrufen, dann führt der Gui Thread das aus.
Java:
 SwingUtilities.invokeLater(new Runnable(){
         public void run() { 
            // Hier aufgeführter Code wird erst nach dem GUI-Update ausgeführt.
         }
      });

Bei SWT gehts glaub so:
Java:
 display.asyncExec(new Runnable() {
                   public void run() {
   
                 	
                   
               });

Bin mir nicht sicher ob es das ist was du brauchst.
 
die anderen Aktionen müssen auch alle in diesen Timer rein, hinter das doSometing()
Das könnte etwas komplizierter werden, da an der Sache noch viele andere Klassen dranhängen.
Ich hab schon versucht die kompletten Klassen in einen Thread auszulagern, aber dann hatte ich das Problem mit dem Gui-Freeze.
Ich benutze ein MVC-Pattern und die Verzögerung befindet sich momentan (leider) in Model. Meine Idee war nun, Model und Controller einen eigenen (gemeinsamen) Thread zu geben. Aber irgendwie gefällt mir die Lösung nicht.
 
> die kompletten Klassen in einen Thread auszulagern, aber dann hatte ich das Problem mit dem Gui-Freeze.

klingt komisch, separate Threads wie auch der Timer helfen doch gerade gegen den Freeze,


du hast gewisse Aktionen die sich überlappen dürfen, das einfachste wäre dazu sie alle in eine normale kontrollierte Reihenfolge zu stecken,
gegebenenfalls in einem Thread parallel zur GUI, sonst komplett normal hintereinander

die Alternative dazu bei mehreren Threads die sich gegenseitig überfahren ist die Synchronisation auf ein gemeinsames Objekt
Galileo Computing :: Java ist auch eine Insel (8. Auflage) – 11.5 Synchronisation über kritische Abschnitte
 
Würde nicht reichen, alle Methoden anderer Klassen, die diese Klasse aus ihrem Thread aufruft, synchronized zu machen? Das wären dann nicht allzu viele. Oder müsste ich diese Methoden locken?
 
wenn alle Methoden auf einunddasselbe Objekt zugreifen, was recht typisch ist bei Problemen eben genau damit ist,
ja dann kann man Methoden synchronized deklarieren, das sollte helfen
 

Zurück
Oben