JProgressBar wird nicht aktualisiert

henpara

Bekanntes Mitglied
Hallo zusammen,

Kurzbeschreibung: im Konstruktor einer Klasse, die JFrame erweitert wird eine JProgressBar auf die ContentPane raufgehauen und das Minimum der JProgressBar auf 0 gesetzt.

Wenn im Programm nun ein Button geklickt wird, soll, je nach Einstellung das Maximum der JProgressBar gesetzt werden, das funktioniert auch.

Anschließend werden 2 threads gestartet, wobei einer den gewohnten Arbeitsablauf ausführt und der andere im Sekundenintervallen die JProgressBar updaten soll, also deren Value / Sekunde um 1 erhöhen.

Ich hab das jetzt so umgesetzt:
Java:
class TimerThread extends Thread {
		int max;
		TimerThread(int i) { // hier wird pb.getMaximum() übergeben.
			max=i;
		}
		public void run() {
			while (getPb().getValue() < max) {//getPb gibt einem die Progressbar zurück
				int val = getPb().getValue();
				System.out.println(go.Go.mtxf.pb.getValue() + " " +        go.Go.mtxf.pb.getMaximum()); // go.Go.mtxf ist das Frame und pb die ProgressBar
				try {
					Thread.sleep(1000); // eine Sekunde warten
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				go.Go.mtxf.pb.setValue(++val); // Progressbar Wert um 1 erhöhen
				go.Go.mtxf.pb.repaint(); // neu zeichnen, damit der Fortschritt auch angezeigt wird
			}

		}
	}

nur leider bleibt auf dem Frame die ProgressBar immer wie sie ist. die Werte werden zwar korrekt ausgegeben, also das Max ist richtig gesetzt, der Wert erhöht sich korrekt alle Sekunde um eins, aber Aktualisierung auf dem Frame? Fehlanzeige.

Nun meine Frage: Hat jemand eine idee warum?
In einem Tutorial - Beispiel hat es gereicht: " progressBar.setValue(++val);"
den Befehl zu schalten und die Bar hat sich auch auf dem Frame korrekt aktualisiert. Warum klappt das bei mir nicht?

Mfg
 
Java:
void cmdCalculate_ActionPerformed() {
		setActStudy();
		if (getActStudy().equals("K")){
			pb.setMaximum(1200);
		} else if (getActStudy().equals("H") || getActStudy().equals("L")) {
			pb.setMaximum(120);
		} else 
			pb.setMaximum(120);
// hier wird das Arbeiten gesetzt.
		AbarbeitenThread at = new AbarbeitenThread(); 
// dieser Thread führt die "calculate-methoden" aus
		at.start();
// thread wird gestartet.
		TimerThread tt = new TimerThread(pb.getMaximum());
//dieser thread soll die progressbar updaten (atm nur richtwerte, wie lange je nach einstellung der //arbeitsdurchgang dauert
		tt.start();
//thread wird gestartet
		try {
			at.join();
			tt.join(); // warten bis beide threads fertig sind
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			System.out.println("Warten auf Threads fehlgeschlagen!");
			e.printStackTrace();
		}
		writeToLogBox("Sie können das Programm jetzt schließen oder die Updates einspielen!");
		writeToLogBox(System.getProperty("line.separator"));
		pnlUpdates.setVisible(true); //hat nix mit der Frage hier zu tun.
	}

Also zunächst is das mein Allererster Test mit Threads. Mein Vorgänger hat komplett ohne gearbeitet, was darauf hinausläuft, daß man das Programm nicht jederzeit verlassen kann.

Im ersten Schritt wollte ich jetzt eig. "nur" mal neben den normalen Arbeitsschritten eine ProgressBar laufen haben.
Wie ich schon erwähnt habe, stimmen die ValueZahlen der ProgressBar, es "macht also prinzipiell" das, was ich will. NUR wird die GUI nicht geupdatet, und das obwhol im Beispielprogramm NUR über das setValue() die Progressbar auch sofort aktualisiert wird.
 
das 'warten bis beide threads fertig sind' ist genau das Problem,
solange der ActionListener nicht fertig ist ist die GUI blockiert, weder wird irgendwas neugezeichnet noch funktionieren Buttons usw.

deine End-Aktion muss entweder in einen der beiden Thread oder in einen dritten der auf die anderen beiden wartet
 
das 'warten bis beide threads fertig sind' ist genau das Problem,
solange der ActionListener nicht fertig ist ist die GUI blockiert, weder wird irgendwas neugezeichnet noch funktionieren Buttons usw.

deine End-Aktion muss entweder in einen der beiden Thread oder in einen dritten der auf die anderen beiden wartet

ok, danke erstmal für den hinweis. kannst du auch kurz erläutern, was du genau mit
solange der ActionListener nicht fertig ist ist die GUI blockiert
meinst?

wieso ist die GUI blockiert?
 
die GUI ist kein Zauberkasten, sondern da gibt es genau einen Thread, der (vereinfacht) ab und zu in irgendwelchen Zustandsvariablen nachschaut, ob ein User-Ereignis wie ein Mausklick kommt oder ob ein repaint() gewünscht ist und dann paint/Listener ausführt,
wenn dieser Thread beschäftigt ist, auf deine anderen Threads zu warten oder lange Berechnungen in einer ActionPerformed ausführt, kann nix anderes mehr stattfinden
 
ok, hab mich ein wenig in die klasse swingworker eingelesen und mir eine Klasse erstellt, die swingworker extendet. dort hab ich dann 2 threads, die in der doinbackground methode erstellt und gestartet werden und in einem thread, wo ich die zeit messe, wird dann über SwingUtilities.invokeLater();
die gui geupdatet.
es funktioniert, ich bin happy 😉

mfg
 

Zurück
Oben