ProgressBar newRunnable (schon wieder!)

Status
Nicht offen für weitere Antworten.

sohell

Mitglied
Ich hab ein problem mit meiner ProgressBar, die nicht schrittweise angezeigt wird.
ich habs schon mit newRunnable gemacht aber irgendwie springt er sofort auf 100%. was könnte hier das problem sein?

Code:
jProgressBar1.setStringPainted(true);

    static public void increaseProgressBarValue() {

              SwingUtilities.invokeLater(new Runnable() {
                        public void run() {
                            jProgressBar1.setValue(jProgressBar1.getValue()+1);
                        }
              });
    }
 

javimka

Top Contributor
Wie wird denn deine JPrograssBar initialisiert? Ist es möglich, dass das max nur 1 ist und deshalb gleich 100% angezeigt wird, wenn du den um 1 erhöhst? Oder rufst du increaseProgressBarValue() vielleicht innerhalb einer Schleife auf und sie geht zwar schrittweise von 0 nach 100%, aber trozdem so schnell, dass es gar nicht sichtbar ist?
Nebenbei ist es eher seltsam, dass increaseProgressBarValue static ist. Vielleicht wäre es eine Überlegung werd, das ganze etwas mehr Objekt-orientiert zu designen.
 

sohell

Mitglied
increaseProgressBarValue wird von schleifen und aber auch außerhalb von schleifen aufgerufen. das es einfach nicht sichtbar ist, weil while schleife zu schnell ist, könnte nicht möglich sein ist aber nicht auszuschließen.
ich lese zeilen und schreibe eine datei mit dem gelesenen und geänderten textinhalt ca. vier mal. die datei hat ca. 200 zeilen.
also vier mal lesen und ändern einer datei welche ca. 200 zeilen hat. die methode die liest und schreibt (wird erst nach click eines buttons ausgeführt, der wiederum einen neuen panel anzeigen lässt). der panel wird durch cordlayout angezeigt, wenn der user auf panel 4 auf weiter klickt dann wird panel 5 angezeigt und die methode der schreib und leseoperationen ausgeführt. Ich hab den wechsel von panel 4 auf panel 5 sogar vor den leseoperationen gestellt.

ich hab jetzt auch die aufrufe minimiert und er bleibt bei 49% stehen.

nein maximal value von progressbar ist 100 und wird viele schritte vor der eigentlichen datei-auslesung und beschreibung initialisiert.
 

javimka

Top Contributor
das es einfach nicht sichtbar ist, weil while schleife zu schnell ist, könnte nicht möglich sein ist aber nicht auszuschließen.
Was denn jetzt, ja oder nein? Setzt halt mal ein sleep in deine while Schleifen hinein:
[Java]
try {
Thread.sleep(100); // Warte eine Zehntel Sekunde
} catch (Exception e) { e.printStackTrace(); }
[/Java]

Ist es sonst möglich, dass deine while-Schleife im Event dispatching thread (EDT) abläuft? Dann würde nämmlich deine JPrograssBar nie neu gezeichnet, bis die while-Schleife zu Ende ist. Und erst dann würden alle 100 Runnables, die du in die Event-Queue gesteckt, ablaufen und den Wert sofort auf 100 setzen.
Füge mal folgendes vor deiner while-Schleife ein:
[Java]
System.out.println("Ausführender Thread: "+Thread.currentThread().getName());
[/code]
Wenn dann steht: "Ausführender Thread: AWT-EventQueue-0", dann ist es tatsächlich der EDT.

Ansonsten kann ich dir ohne Source Code auch nicht weiterhelfen. Woher soll ich wissen, was deine Panel 4 und 5 in ihrere Freizeit so machen? ;)
 

sohell

Mitglied
es wird eine ausgabe erzeugt und zwar mehrmals mit demselben namen: (und zwar weil ich es in die methode increaseProgressBarValue gesetzt hab, welche innerhalb der lese und schreib methode von einer anderen klasse aufgerufen wird).

Ausgabe in system.out.println: "Ausführender Thread: AWT-EventQueue-0"

ich habe eine pause mal hinzugefügt. aber naja nicht mein gewünschter erfolg. denn dann tut er nur einmal ne pause machen.

also das mit den EDT's habe ich schon mal gelesen, dass er die progressbar nur dann repainted wenn er bei 100% ist (also schon fertig ist).

achso ja: in der freizeit tun panel4 und panel5 eier schaukeln :lol:
ernsthaft: also das wäre jetzt zu viel code. ist ja eigentlich egal was die machen. aber wichtig: wenn ich ein sleep hineinsetze wird panel5 angezeigt und dann die progressbar sichtbar später erhöht. das zeigt, dass die lese und schreib methoden hier uninteressant sind.
 
Zuletzt bearbeitet:

javimka

Top Contributor
Ok, ich weiss, was das Problem ist: Deine while-Methode wird vom EDT abgearbeitet und so wird jedes Zeichnen geblock, bis diese while-Schleife zu Ende ist.

Zuerst die Theorie:
Der EDT ist verantwortlich für alles, was auf den GUIs gezeichnet wird. Er und nur er zeichnet jede Komponente. Wenn der EDT irgendwo beschäftigt ist, z.B. in einer Schleife ond einer Thread.sleep, dann ist die gesamte GUI eingefroren. Das Swing Konzept funktioniert folgendermassen: Es existiert eine Event-Queue, in die "Aufträge" gespeichert werden. Der EDT macht nun nichts anderes als diese Liste systematisch abzuarbeiten. Solche Aufträge sind z.B. das Zeichnen einer JPanel oder eines JButtons oder auch nur das teilweise Neuzeichnen einer JProgressBar, wenn sich der Wert geändert hat. Ausserdem werden alle möglichen "Events" in diese Liste gespeichert. z.B. wenn du auf einen Button klickst, der einen ActionListener angehängt hat, dann wird ein ActionEvent in die Liste aufgenommen und vom EDT ausgeführt, sobald er zu diesem Element gekommen ist.
Es gibt übrigens nur einen EDT, nicht "die EDTs" ;)

So ist es in Moment:
Ich gehe davon aus, dass deine while Schleife startet, sobald du den Button geklickt hast. Wahrscheinlich hast du dem Button einen ActionListener angehängt. Es wird also ein ActionEvent in die Event-Queue gespeichert und irgendwann kommt der EDT und führt die actionPerformed-Methode aus. Und da drin steht sicher deine while-Schleife. D.h. der EDT ist jetzt in dieser Schleife und kann nichts mehr neuzeichnen, insbesondere nicht deine JProgressBar. Unterdessen werden aber mit SwingUtilities.invokeLater viele neue Events in die Queue aufgenommen. Wenn der EDT dann endlich fertig ist mit der while-Schleife nimmt er sich die nächsten Elemente aus der Liste, nämlich alle deine Kommandos, den Wert der JProgressBar zu erhöhen und wenn er alle durch hat, dann erst zeichnet er die JProgressBar endlich neu. Und dann ist der Wert natürlich 100. Er zeichnet die ProgressBar deshalb erst zum Schluss, weil durch das erhöhen des Wertes in der JProgressBar ein repaint() aufgerufen wird, das ganz einfach auch einen "Zeichen-Auftrag" zu hinterst in die Queue legt, also hinter all den Wert-Erhöhungen.

Jetzt musst du es folgendermassen ändern:
Geh in den ActionListener, den du dem Button angehängt hast und betrachte die actionPerformed() Methode. Anstatt hier in die while-Schleife einzutreten, startest du einen neuen Thread, der das macht. Mit folgendem Code:
Java:
public void actionPerformed(ActionEvent event) {
  new Thread() {
    public void run() {
      // deine while-Schleife und alles andere, das dazugehört
    }
  }.start();
}
Nun läuft deine while-Schleife in einem separatem Thread und der EDT hat Zeit, deine JProgressBar ständig anzupassen und neu zu zeichnen :D

Hoffe, du nimmst es mir nicht übel, dass ich den EDT so vermenschlicht hab ;)
 

sohell

Mitglied
gelöst. scheint mal! denn jetzt meine ich das die while schleife sehr schnell abgearbeitet wird. und man sieht die progressBar ab 60% bis 100% hoch gehen, weil der wechsel von panel4 zu panel5 wohl länger dauert.

ich hab da so ein paar variable sleep timer rein gesetzt damit das nach was aussieht.
wer hätte gedacht das so komplizierte schreib und lese arbeiten von einem dualcore prozessor so schnell abgearbeitet werden...

noch eine frage: man nehme an: mehrere verschachtelte hierarchisch aufgebaute funktionen-->
oberste Ebene (1) Funktion 1
zweite Ebene (1.1) Funktion 1.1
zweite Ebene (1.2) Funktion 1.2
dritte Ebene (1.2.1) Funktion 1.2.1

wenn ich jetzt einen neuen Thread auf Ebene 1 Lege sind dann die Funktionen darunter auch auf demselben Thread?

Denn bei mir liegt so ein fall vor! sollte ich dann jede funktion in einen neuen Thread liegen, um die progressbar zum zeichnen zu bringen und nicht auf endgültige endwerte (i.s.v. value) zu warten?
Du hast es super erklärt und nix auseinander gerissen! :toll:


erstelle ich einen neuen Thread für eine funktion
 

javimka

Top Contributor
Freut mich, dass es klappt. Naja, nur damit es "nach etwas aussieht", müsstest du das ganze ja nicht verlangsamen ;)

Zu deiner Frage:
Wenn du von einer Funktion eins() aus eine weitere Funktion zwei() aufrufst, also eine Ebene eintauchst, dann wird kein neuer Thread gestartet, sondern das läuft im selben weiter. Threads laufen ja alle parallel, würde bei einem Funktionsaufruf zwei() ein neuer Thread starten, würde der alte Thread mit der Funktion eins() weiter machen, obwohl zwei() noch gar nicht abgarbeitet wurde. Das würde natürlich nicht funktionieren.
Neue Threads entstehen nur, wenn das explizit geschrieben wird, z.B. so wie ich es oben geschrieben habe.

In einem Programm laufen nicht so viele Threads. Mal sicher einer, der mit der main-Methode beginnt und dann je nachdem noch weitere. Wenn du Swing verwendest, werden etwa 5 weitere Threads gestartet, wobei du kaum einen anderen, als den EDT berücksichtigen musst. Die JVM selber braucht auch noch einige Threads, bei mir sind das 9, auf anderen Plattformen, könnte das anders sein.
 

hdi

Top Contributor
Ich hab mal schnell eine kleine Demo gemacht, die veranschaulicht, wovon javimka redet.
Er hat's zwar sehr gut erklärt aber was zum Ankucken ist immer toll, und mir war grad langweilig xD

Den Code kannst du einfach kopieren und starten.

Java:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class EDTDemo extends JFrame {

	public static void main(String[] args) {
		new EDTDemo().setVisible(true);
	}

	private Color c;

	public EDTDemo() {

		final JPanel p = new JPanel() {
			protected void paintComponent(java.awt.Graphics g) {
				super.paintComponent(g);
				g.setColor(c);
				g.fillRect(0, 0, getWidth(), getHeight());
			};
		};
		p.setPreferredSize(new Dimension(300, 300));

		final Random r = new Random();
		new Thread() {
			public void run() {
				// endlosschleife...
				while (true) {

					c = new Color(r.nextInt(255), r.nextInt(255), r
							.nextInt(255));

					// repaint() schickt ein Event zum EDT, dass das Panel
					// neu gezeichnet werden soll.
					p.repaint();

					try {
						Thread.sleep(50);
					} catch (InterruptedException e) {
					}
				}
			}
		}.start();

		JButton calcs = new JButton("process 5 secs on EDT");
		calcs.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				// Dieser Code wird vom EDT aufgerufen
				// Hier könnten komplexe Berechnungen stehen, die 5 Sekunden
				// dauern.
				try {
					Thread.sleep(5000);
				} catch (InterruptedException e1) {
					e1.printStackTrace();
				}
			}
		});

		add(p, BorderLayout.CENTER);
		add(calcs, BorderLayout.NORTH);

		pack();
		setLocationRelativeTo(null);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
	}
}
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
F Progressbar Farbe AWT, Swing, JavaFX & SWT 6
T Swing Reload JPanel + darin liegende ProgressBar AWT, Swing, JavaFX & SWT 9
A Swing ProgressBar über 2 parallel laufende Threads AWT, Swing, JavaFX & SWT 2
P JavaFx - Progressbar - Füllen mittels mehreren Tasks AWT, Swing, JavaFX & SWT 0
Bluedaishi JavaFX ProgressBar AWT, Swing, JavaFX & SWT 10
T Starten des Programms mit dem Progressbar AWT, Swing, JavaFX & SWT 2
L Progressbar Laufzeitveränderung AWT, Swing, JavaFX & SWT 4
1 Swing Progressbar benutzen um Fortschritt einer Methode anzuzeigen AWT, Swing, JavaFX & SWT 4
B JavaFX Textfields: Fortschritt als ProgressBar und Progressindicator AWT, Swing, JavaFX & SWT 5
MR._FIRE_Flower progressBar in ein bestehendes Programm einbauen AWT, Swing, JavaFX & SWT 3
M Wie binde ich eine JavaFX ProgressBar an eine Datei Übertragung? AWT, Swing, JavaFX & SWT 2
Z Swing Swing und die Progressbar AWT, Swing, JavaFX & SWT 1
I JavaFX Im Controller die ProgressBar mit Task updaten AWT, Swing, JavaFX & SWT 6
R LookAndFeel Wie kann man die Textfarbe der Nimbus ProgressBar nach Füllstand ändern? AWT, Swing, JavaFX & SWT 2
M JavaFX Progressbar bar und track Komponente zur Laufzeit ändern AWT, Swing, JavaFX & SWT 2
Z ProgressBar in Eclipse mit Wizard page? AWT, Swing, JavaFX & SWT 1
W Swing ProgressBar update AWT, Swing, JavaFX & SWT 4
A JavaFX Eine Task mit einer ProgressBar verbinden AWT, Swing, JavaFX & SWT 0
H Nimbus ProgressBar Colors AWT, Swing, JavaFX & SWT 9
P Swing Die ProgressBar wird nicht angezeigt AWT, Swing, JavaFX & SWT 5
B SWT Progressbar mit Textoverlay? AWT, Swing, JavaFX & SWT 3
M ProgressBar in ActionListener AWT, Swing, JavaFX & SWT 4
T Prozessstatus in Progressbar anzeigen AWT, Swing, JavaFX & SWT 5
J Swing Progressbar aktualisiert sich nicht AWT, Swing, JavaFX & SWT 17
V Persistentes Objekt laden Progressbar AWT, Swing, JavaFX & SWT 7
V Swing Progressbar Problem AWT, Swing, JavaFX & SWT 14
B ProgressBar während Berechnung AWT, Swing, JavaFX & SWT 4
Tobse LookAndFeel [Windows7] Nativ aussehnde ProgressBar AWT, Swing, JavaFX & SWT 13
J Progressbar mit einfacher Funktion AWT, Swing, JavaFX & SWT 6
D Progressbar AWT, Swing, JavaFX & SWT 5
H Zeile in DefaultTableModel hinzufügen, ProgressBar AWT, Swing, JavaFX & SWT 4
S Upload Progressbar AWT, Swing, JavaFX & SWT 3
S Dateien kopieren mit ProgressBar AWT, Swing, JavaFX & SWT 6
S Swing ProgressBar AWT, Swing, JavaFX & SWT 3
S SWT ProgressBar: Value/Selection anzeigen AWT, Swing, JavaFX & SWT 4
D SWT JFace Wizard Progressbar AWT, Swing, JavaFX & SWT 4
ModellbahnerTT Progressbar anzeigen AWT, Swing, JavaFX & SWT 5
J Progressbar aktualisierung nach file übergabe AWT, Swing, JavaFX & SWT 7
P Progressbar in java AWT, Swing, JavaFX & SWT 3
K Frage zu ProgressBar, SwingWorker etc. AWT, Swing, JavaFX & SWT 4
V ProgressBar AWT, Swing, JavaFX & SWT 5
D Suche verticale Progressbar AWT, Swing, JavaFX & SWT 2
M Bug; Swing-Worker, Progressbar und Mouse AWT, Swing, JavaFX & SWT 22
P [SWT] - ProgressBar, Prozentzahlen live anzeigen geht nicht AWT, Swing, JavaFX & SWT 13
P JTable sortiert ProgressBar nicht AWT, Swing, JavaFX & SWT 8
L Button ändert eigenes Bild und Progressbar-Value nicht AWT, Swing, JavaFX & SWT 6
B Eine Alternative zur Steuerung einer ProgressBar? AWT, Swing, JavaFX & SWT 5
N ProgressBar --> brauche Hilfe AWT, Swing, JavaFX & SWT 4
G Progressbar aktualisiert sich nicht (vernünftig). WIESO? AWT, Swing, JavaFX & SWT 2
S Anzeige einer Progressbar. AWT, Swing, JavaFX & SWT 3
M Bild laden + ProgressBar AWT, Swing, JavaFX & SWT 2
C Problem mit ProgressBar AWT, Swing, JavaFX & SWT 4
thE_29 Problem mit ProgressBar AWT, Swing, JavaFX & SWT 2
M ProgressBar in einem Thread? AWT, Swing, JavaFX & SWT 4
C ProgressBar AWT, Swing, JavaFX & SWT 4
dzim JetBrains Compose - hat das schon jemand probiert? AWT, Swing, JavaFX & SWT 3
M Java anwendung VOR vollbildspielen (schon wieder...) AWT, Swing, JavaFX & SWT 5
C Schon wieder JTable AWT, Swing, JavaFX & SWT 7
B Swing Locale wechseln, nachdem UIManager schon initialisiert ist AWT, Swing, JavaFX & SWT 5
Binary.Coder Netbeans GUI zu Eclipse (schon gegooglet und einiges ausprobiert). AWT, Swing, JavaFX & SWT 4
N JComboBox schon zum Teil aufgeklappt AWT, Swing, JavaFX & SWT 7
P schon wieder schlange AWT, Swing, JavaFX & SWT 8
J Swing - ich sehe keine Linie, andere schon AWT, Swing, JavaFX & SWT 6
GilbertGrape JTable mit Combobox-Editierung schon nach einem Klick AWT, Swing, JavaFX & SWT 7
oliver1974 Wer hat QT Jambi schon probiert? AWT, Swing, JavaFX & SWT 5
Z Und schon wieder die Linien (Problem beim überzeichnen) AWT, Swing, JavaFX & SWT 4
B Schon wieder ein Problem mit paintComponent(). AWT, Swing, JavaFX & SWT 2
M Ist Swing schon fertig? AWT, Swing, JavaFX & SWT 3
F SkinLF - GTK Icons werden nicht genutz - KDE schon - why? AWT, Swing, JavaFX & SWT 8
D Prüfen, ob Fenster bereits schon geöffnet ist AWT, Swing, JavaFX & SWT 1
K Und schon wieder JInternalFrame AWT, Swing, JavaFX & SWT 2

Ähnliche Java Themen

Neue Themen


Oben