Thread.sleep überspringt "scheinbar"Aufgaben

CT9288

Mitglied
Hallo Ihr lieben, ich bin mal wieder mit einem neuen Problem hier:

Ich habe über Netbeans eine kleine Applikation erstellt, in der man drei JLables hat, zwei zeigen eine Farbe an, das Dritte den Namen einer der Farben. Wenn man nun auf die Farbe klickt, dessen Namen oben steht, erhält man ein Smile, wenn man versagt einen traurigen Smile. Danach werden die Farben wieder gemischt, ein neuer Name erscheint. Soweit funktioniert das gut, aber:
ich wollte den Smile für ca. eine Sekunde stehen lassen und danach erst neu mischen lassen. Das habe ich mit dem Thread.sleep versucht, aber auch mit TimeUnit.MILLISECONDS.sleep, jeweils immer so 1000 Millisekunden. Das Ergebnis war letzten Endes, dass zwar die Farben wieder und wieder neu gemischt wurden, aber die Smiles nicht mehr angezeigt wurden. Wie könnte man das beheben? Gibt es noch andere nütziche Arten den Ablauf zu verzögern? Gruß Timo.


Java:
private void jL2ColorsAMouseClicked(java.awt.event.MouseEvent evt) {                                       
        //Check ob Bild mit Titel übereinstimmt, nummern werden verglichen
        if(ranNum1 == getRanNum){
            image1 = new ImageIcon(getClass().getResource("happy.png"));
            jL2ColorsA.setIcon(image1);
            try {
                //Jetzt wird kurz gewartet bevor die neuen Bilder kommen
                TimeUnit.MILLISECONDS.sleep(1000);
            } catch (InterruptedException ex) {
                Logger.getLogger(toddler.class.getName()).log(Level.SEVERE, null, ex);
            }
            //Jetzt werden wieder neue Bilder und alles geladen

Das ist im Grunde die Stelle um die es geht. Wenn ich dieses oder Thread.sleep komplett weglasse, kommt auch kein Smile (ich gehe jetzt einfach mal davon aus, dass bei beiden Fällen der Smile zwar gezeigt wird, aber so schnell, dass man es nicht sehen kann, weil das Programm direkt weiter macht).
 

Anhänge

  • app.png
    app.png
    33,5 KB · Aufrufe: 30
  • app2.png
    app2.png
    23,5 KB · Aufrufe: 25
K

kneitzel

Gast
Also Dein Problem liegt hier im Verständnis: Du agierst im UIThread und der hat auch die Aufgabe, die Fenster neu zu malen wenn notwendig.

Was also passiert ist: Du veränderst die UI, so dass ein Event generiert wird, dass die Applikation sich neu malen soll.
Nun sperrst du aber den UI Thread, daher kann die Applikation nicht die geänderte UI darstellen.
Nun kommen weitere Änderungen der UI ...
Jetzt endlich gibst Du den UI Thread frei - und alle Änderungen werden dargestellt, da der UI Thread nun endlich die Fenster neu malen kann.

Also bitte merken: Niemals ein sleep oder so im UI Thread!
Wenn Du lang laufende Aktionen hast, dann glieder diese in einen eigenen Thread aus.

Es gibt hierzu eine Dokumentation / Lehreinheit von Oracle: https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html

Da wird dann auch der SwingWorker erläutert incl. der Detail, wie (Zwischen-)Ergebnisse zurück gegeben werden. (so Oberflächen sind auch etwas eigen, von welchem Thread Elemente verändert werden, daher gibt es da da auch spezielle Möglichkeiten...)

Anstatt das in einen eigenen Thread (incl. sleep) auszulagen, kannst Du auch einen Timer verwenden, der dann nach eine bestimmten Zeit aktiv wird:
https://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html
 

Neue Themen


Oben