Kleiner Gui Counter

Heiser

Grünschnabel
Hi Leute,
ich bin schon seit ein paar Stunden an einem kleinem Gui Counter zu basteln leider ohne Erfolg:(


habe einen jButton und ein jTextField .Jezt sollte man auf den Button druecken und im TextField sollten 60 Sekunden runtergezaehlt werden.

Hatte mir dazu eine kleine Methode geschreiben kalppt aber wieder mal ueberhaupt nicht.

Code:
public void zaehler()
{
int sec =60
  while (sec!= -1) {
            
                        try {
                                Thread.sleep(1000);
                        } catch (InterruptedException e) {
                        
                        }}
      jTextField1.setText(""+ sec --);
}

Wenn ich jezt im jButton diese Methode aufrufe bleibt nur der Button heangen fuer 60 Sekunden aber ins textfiled wird nichts geschrieben.
 
Eine for-Schleife wäre sicherlich schicker, hat aber einen anderen Grund und nix mit dem Problem hier zu tun.

Das Problem hier ist einfach eine falsch positionierte schließende geschweifte Klammer. Das Setzen des Textes in TextField passiert einfach nach dem Durchlauf der Schleife, das heißt man muss das Setzen eigentlich in die Schleife verschieben.
Java:
public void zaehler() {
	int sec = 60;
	while (sec != -1) {
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {}
		jTextField1.setText("" + sec--);
	}
}
 
Danke fuer die schnelle Hilfe.

Leider besteht das Problem immer noch .Sobald er anfaengt zu zaehlen sieht man die Zahlen nicht im jTextField1 ausser der Null(0) am Ende wenn er fertig ist.

Java:
public void zaehler() {
    int sec = 60;
    while (sec != -1) {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {}
        jTextField1.setText("" + sec--);
        System.out.println("" + sec--);  ////da werden die Zahlen schon alle ausgegeben:confused:
    }
}


Java:
 private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {


      zaehler();
}
 
Ups, sorry, die Klammer hatte ich übersehen.
Aber dennoch benötigst du für eine Schleife, in der wärend dem Durchlauf neu gezeichnet werden soll einen Thread.
 
Also warum das im Textfeld nicht aktualisiert wird, liegt wohl daran, dass die Gui während der Schleifenverarbeitung gefreezt ist. Ist mir aufgefallen, weil ich das Fenster nicht vernünftig schließen konnte. Mit einem Verarbeitendem Thread für die Counter-Funktionalität geht es aber ohne Probleme. Hab auch mal Verbesserungen reingetan, diese sind aber auskommentiert. Kannst natürlich eine Variante deiner nehmen und die anderen eben löschen.

Damit sieht die Methode zaehler() dann so aus:
Java:
	public void zaehler() {
		new Thread() {
			@Override
			public void run() {
				// int sec = 60;

				// while(!interrupted() && sec >= 0) {
				// try {
				// Thread.sleep(1000);
				// } catch(InterruptedException e) {
				// interrupt();
				// }
				// jTextField1.setText("" + sec--);
				// System.out.println("" + sec--); // <-- Führt zur doppelten
				// Dekrementierung
				// }

				// Besser
				// while(!interrupted() && sec-- >= 0) {
				// try {
				// Thread.sleep(1000);
				// } catch(InterruptedException e) {
				// interrupt();
				// }
				// jTextField1.setText("" + sec);
				// System.out.println("" + sec);
				// }

				// Und noch besser, damit sec nur innerhalb der Schleife
				// existiert
				for(int sec = 60; !interrupted() && sec >= 0; sec--) {
					try {
						Thread.sleep(1000);
					} catch(InterruptedException e) {
						interrupt();
					}
					jTextField1.setText("" + sec);
					System.out.println("" + sec);
				}
			}
		}.start();
	}
 
Danke Akeshihiro und Kai008 fuer eure Zeit und Muehe.


Muss mir mal die Threads etwas genauer anschauen und natuerlich die Verbesserungen von Akeshihiro :):
 
Hallo,

Code:
Thread.sleep(1000);
Das wird aber so nicht laufen.
Der Befehl gibt an, dass der Thread mindestens(!) 1 sec. wartet.
Das ist aber abhängig vom Betriebsystem. Wenn die Prio deiner Anwendung
niedrig ist und das System ausgelastet wird, wird dein Thread immer wieder
hinten angestellt. Es kann also sein, dass dein Thread 2, 3 oder 4 sec "schläft".

Ich denke, du kannst es über

Code:
System.currentTimeMillis()

versuchen.
 
Hallo,

noch eine Bemerkung am Rande: man sollte aus einem separaten Thread niemals auf die UI Komponente zugreifen. Das kann zu bösen Seiteneffekten führen. Um das Problem zu umgehen, benutzt man die statische Methode SwingUtilities.invokeLater(java.lang.Runnable). In der Dokumentation der Methode steht auch, wann sie benutzt werden soll.

Grüße
Vincent
 
Hallo,

Code:
Thread.sleep(1000);
Das wird aber so nicht laufen.
Der Befehl gibt an, dass der Thread mindestens(!) 1 sec. wartet.
[...]
Ich denke, du kannst es über

Code:
System.currentTimeMillis()

versuchen.

Naja, das wird in etwa das gleiche Problem verursachen.

Ich löse sowas immer mit der Timer Klasse, dazu ist die nämlich da :) Hier mal ein kleines lauffähiges Beispiel. Der Inhalt der main() Methode kann aber einfach in die zaehler() Methode eingebunden werden:

Java:
import java.util.Timer;
import java.util.TimerTask;

public class TimerTest {

    public static void main(final String[] args) {
        final Timer t = new Timer();
        final TimerTask task = new TimerTask() {

            int stillToWait = 10;

            @Override
            public void run() {
                // GUI AKTUALISIEREN (SPEZIELL STILLTOWAIT SETZEN UND NEU
                // ZEICHNEN)
                System.out.println(stillToWait);
                if (stillToWait-- == 0) {
                    // COUNTDOWN ABGELAUFEN!
                    t.cancel();
                }
            }
        };
        t.scheduleAtFixedRate(task, 0, 1000);
    }
}

Gruß,

RoCMe

EDIT: Java Tags sind ohne Leerzeichen gleich viel cooler ;-)
 
Zurück