setVisible()-Aufrufe werden zu spät umgesetzt

Status
Nicht offen für weitere Antworten.

Tissi

Mitglied
Hallo!

Ich hab folgendes Problem:
Es geht um ein kleines Quizspiel und am Ende sollen die Spieler nach Punkten sortiert werden und, mit dem letzten Platz beginnend, nacheinander angezeigt werden. Dazu folgende Methode:
Code:
	public void evaluate() {
		this.btn_evaluate.setVisible(false);
		this.pnl_questionoverview.setVisible(false);
		this.game.evaluate(); // beendet das Spiel und sortiert die Spieler
		this.pnl_players.setVisible(false);
		this.pnl_evaluation.setVisible(true);
		this.pnl_evaluation.showEvaluation(this.game.getPlayers());
		this.btn_exit.setVisible(true);
	}
Code:
	public void showEvaluation(Player[] players) {
		for (int i = 0; i < this.lbls_place.length; i++) {
			this.lbls_place[i].setVisible(false);
		}
		
		int place = 0;
		for (int i = 0; i < players.length; i++) {
			if (i == 0 || players[i].getScore() < players[i-1].getScore()) {
				place++;
			}
			this.lbls_place[i].setText(place + ". " + players[i].getName() + " (" + players[i].getScore() + ")");
		}
		
		final int timeout = 1000;
		long time = System.currentTimeMillis();
		while (System.currentTimeMillis() - timeout < time);
		for (int i = players.length - 1; i >= 0; i--) {
			this.lbls_place[i].setVisible(true);
			if (i > 0 && players[i].getScore() < players[i-1].getScore()) {
				time = System.currentTimeMillis();
				while (System.currentTimeMillis() - timeout < time);
			}
		}
	}

Jetzt folgendes Problem:
Die ersten vier setVisible()-Aufrufe in evaluate() sind nicht sofort auf dem Bildschirm sichtbar. Erst nachdem showEvaluation() durch ist, werden die Komponenten ein- bzw. ausgeblendet. Dadurch ist mit einigen Sekunden Verzögerung (aus showEvaluation()) die gesamte Auswertung auf einmal zu sehen.

Meine Frage also: Warum??? Ich verstehs einfach nicht.
 

hdi

Top Contributor
[HIGHLIGHT="Java"]public void showEvaluation(Player[] players) {
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run(){
// der eigentliche Code dieser Methode
}
}
}[/HIGHLIGHT]

Im Übrigen nennt man das hier:

[HIGHLIGHT="Java"]while (System.currentTimeMillis() - timeout < time);[/HIGHLIGHT]

"Busy Waiting", und das zieht deine CPU auf 100%. Ersetze diese Schleife einfach durch:

[HIGHLIGHT="Java"]Thread.sleep(timeout);[/HIGHLIGHT]
 

Tissi

Mitglied
Erstmal vielen Dank für die superschnelle Hilfe. Damit funktioniert's.

Leider ist mir immernoch nicht klar, warum mein Code nicht funktioniert hat. Merkt sich da irgendein Objekt die repaint-Anweisungen zwischendurch und führt nachher alle zusammen aus oder was passiert da?
 

hdi

Top Contributor
Naja das Problem liegt darin dass Java alle Swing-Events in einem sog. "Event Dispatch Thread" behandelt. Also zB läuft jedes repaint() darauf.
Dieser EDT verstehst sich nich so gut mit anderen Threads.

Der Code in meinem Bsp erstellt einen neuen Thread, und legt diesen Thread in eine Warteschlange, die genau dieser EDT abarbeitet.
D.h. jetzt bearbeitet der EDT die Methode, und damit kann er auch mit dem repaint()
ordentlich umgehen.

Das geht eben (meistens) nicht einfach so.

Generell kannste dir merken: Wenn du irgendwo Berechnungen durchführst, und gleichzeitig etwas mit Swing-Komponenten tust (zB repaint()), sollten diese Berechnungen auf den EDT gelegt werden.
 

Ebenius

Top Contributor
Naja das Problem liegt darin dass Java alle Swing-Events in einem sog. "Event Dispatch Thread" behandelt. Also zB läuft jedes repaint() darauf.
Dieser EDT verstehst sich nich so gut mit anderen Threads.

[...]

Generell kannste dir merken: Wenn du irgendwo Berechnungen durchführst, und gleichzeitig etwas mit Swing-Komponenten tust (zB repaint()), sollten diese Berechnungen auf den EDT gelegt werden.
Aua. Das ist so ziemlich gesamtheitlich verkehrt. Das von Dir beschriebene wäre ja Voodoo... :cool:

  • repaint() ist eine Methode; sie läuft natürlich in dem Thread der sie aufruft.
  • repaint() ist explizit dafür da, in jedem Thread aufrufbar zu sein.
  • repaint() zeichnet eine Komponente nicht neu, sondern legt einen PaintEvent in die EventQueue! (vereinfacht dargestellt. RepaintManager und dirtyRegions interessieren jetzt mal einfach nicht)
  • Der EDT macht nix anderes als die EventQueue zu pollen und -- wenn Events drin liegen -- alle Events in der selben Reihenfolge abzuarbeiten in der sie in die Queue geworfen wurden (Klar. Queue sagt das schon: FIFO).
  • Berechnungen -- sofern sie nicht trivial sind -- werden explizit in einem anderen Thread gemacht; macht man sie im EDT (also zum Beispiel in der actionPerformed(...)-Methode eines ActionListeners) hängt während der Berechnung die GUI mit allen Konsequenzen (kein zeichnen beim Fenster vergrößern / verkleinern; der Progress-Bar updated sich nicht; und all der Rest eben).
  • Veränderungen an AWT-/Swing-Komponenten muss man aber synchron zum EDT machen. Das bedeutet: Die längere Berechnung macht man in einem separaten Thread (gut geeignet immer die SwingWorker-Klasse) und die Veränderungen der GUI lässt man dann im EDT machen. Entweder über die done()-Methode des SwingWorkers oder über SwingUtilities.invokeLater(...) oder SwingUtilities.invokeAndWait(...) (letztere Methode sehr selten).
Ebenius
 

hdi

Top Contributor
repaint() zeichnet eine Komponente nicht neu, sondern legt einen PaintEvent in die EventQueue!
Ja, das entkräftet doch irgendwie die anderen beiden Aussagen, die du über repaint() machst. Also, ist schon korrekt, aber wenn ich sage repaint() läuft auf dem EDT, dann stimmt das doch, oder? Egal vonwelchem Thread ich das aufrufe. Also...mir repaint mein ich das Malen an sich, also ich meine davon redet man, wenn man sagt "ich mach repaint". Man will, dass gezeichnet wird, egal "wer" das jetzt tut.

Der EDT macht nix anderes als die EventQueue zu pollen und -- wenn Events drin liegen -- alle Events in der selben Reihenfolge abzuarbeiten in der sie in die Queue geworfen wurden (Klar. Queue sagt das schon: FIFO).
Jo, ich glaub darüber hab ich nix gegenteiliges gesagt, oder überhaupt was gesagt

Berechnungen -- sofern sie nicht trivial sind -- werden explizit in einem anderen Thread gemacht
Stimmt, eigentlich weiss ich das auch. Hatte wohl irgendwie nicht nachgedacht vorhin als ich das geschrieben habe, bzw. was anderes gedacht als geschrieben. Ich meinte nur man soll das trennen, also Swing-Sachen auf die EventQueue legen. War natürlich total falsch wie ich es geschrieben hab, da hast du vollkommen Recht

SwingUtilities.invokeLater(...) oder SwingUtilities.invokeAndWait(...) (letztere Methode sehr selten).
Ich glaub ich hab das schon 3 mal gefragt, falls mir das jemals jmd schon gesagt hat, entschuldige. Aber was ist genau der Unterschied zwischen den 2 Methoden?
 

Ebenius

Top Contributor
Ja, das entkräftet doch irgendwie die anderen beiden Aussagen, die du über repaint() machst. Also, ist schon korrekt, aber wenn ich sage repaint() läuft auf dem EDT, dann stimmt das doch, oder? Egal vonwelchem Thread ich das aufrufe. Also...mir repaint mein ich das Malen an sich, also ich meine davon redet man, wenn man sagt "ich mach repaint". Man will, dass gezeichnet wird, egal "wer" das jetzt tut.
Da Du "repaint()" mit Klammern geschrieben hast, bleibt dem Leser doch nix anderes übrig als zu glauben, Du meintest die Methode.

Ich glaub ich hab das schon 3 mal gefragt, falls mir das jemals jmd schon gesagt hat, entschuldige. Aber was ist genau der Unterschied zwischen den 2 Methoden?
invokeLater(...) ist wie Brief wegschicken. Brief ist raus, weiter gehts. invokeAndWait(...) geht nur von außerhalb des EDT (sonst gibt's ne Exception). Ist wie Einschreiben mit Rückantwort. Vor der Rückantwort geht's nicht weiter. Anders gesagt: Der Methodenaufruf kehrt erst zurück, wenn der EDT den Auftrag erledigt hat (also nachdem die run()-Methode des übergebenen Runnables fertig ist).

Ebenius
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Seltsame Exception bei setVisible(true) Methode in einem JFrame AWT, Swing, JavaFX & SWT 2
K Swing AWT-EventQueue-1 java.lang.NoClassDefFoundError bei setVisible(true) AWT, Swing, JavaFX & SWT 3
A Swing Buttons werden trotz setVisible nicht dargestellt AWT, Swing, JavaFX & SWT 14
S JFrame -> setVisible AWT, Swing, JavaFX & SWT 3
G Swing Setvisible problem AWT, Swing, JavaFX & SWT 1
1 Problem mit setVisible AWT, Swing, JavaFX & SWT 11
P jframe setVisible(false) wieder sichtbar machen? AWT, Swing, JavaFX & SWT 4
H Swing Keine Rückmeldung (freeze) bei setVisible(false) oder dispose() AWT, Swing, JavaFX & SWT 4
M Kein resize nach Component.setVisible() AWT, Swing, JavaFX & SWT 2
G Swing Wieso braucht man nach setVisible mal ein revalidate und mal nicht? AWT, Swing, JavaFX & SWT 8
B GlassPane setVisible(true) funktioniert nicht AWT, Swing, JavaFX & SWT 2
R Button soll nach dem er gedrückt wurde auf setVisible(false) gestellt werden. AWT, Swing, JavaFX & SWT 3
P Was tun HIDE_ON_CLOSE und setVisible() tatsächlich? AWT, Swing, JavaFX & SWT 7
V JTextField nimmt keine Eingaben an, nach nachträglichem setVisible des JWindows AWT, Swing, JavaFX & SWT 4
L Swing setVisible(false) bei GridBagLayout - wie Layoutverschiebung verhindern? AWT, Swing, JavaFX & SWT 2
L SWT Control.setVisible? AWT, Swing, JavaFX & SWT 2
hdi Swing Erstmaliges setVisible - Verständnisfrage AWT, Swing, JavaFX & SWT 5
M Swing JScrollPane und setVisible AWT, Swing, JavaFX & SWT 2
L mehere JPanels auf JFrame - setVisible() funktioniert nicht AWT, Swing, JavaFX & SWT 3
L Problem mit "setVisible" unter LINUX AWT, Swing, JavaFX & SWT 5
K JDialog - Methode nach setVisible() aufrufen AWT, Swing, JavaFX & SWT 4
B alternative zu setVisible() AWT, Swing, JavaFX & SWT 2
C JWindow.setVisible(true) dauert ewig AWT, Swing, JavaFX & SWT 7
F LayoutManager und Component.setVisible(boolean) AWT, Swing, JavaFX & SWT 2
E Hilfe - setVisible macht was es will AWT, Swing, JavaFX & SWT 7
R TextField bringt NullPointerException bei setVisible() AWT, Swing, JavaFX & SWT 12
S Ganze Fenster auf setVisible(false) setzen AWT, Swing, JavaFX & SWT 2
T Problem mit setVisible AWT, Swing, JavaFX & SWT 4
K AWT begrenzte anzahl paint aufrufe AWT, Swing, JavaFX & SWT 6
E mehrere repaint() Aufrufe - NUR eine Ausführung. Warum? AWT, Swing, JavaFX & SWT 59
A setDefaultCloseOperation soll Methode zu Progammende aufrufe AWT, Swing, JavaFX & SWT 6
M Vokabelprogram - Schleife für Liste soll schrittweise durchlaufen werden AWT, Swing, JavaFX & SWT 3
melaniemueller JavaFX Beispiel kann nicht ausgeführt werden AWT, Swing, JavaFX & SWT 4
B Mit ContentPane werden Komponenten angezeigt, mit SplitPane, JPanel nicht? AWT, Swing, JavaFX & SWT 6
J Swing Werte des JTable werden nicht angezeigt AWT, Swing, JavaFX & SWT 9
W Können Animationen in JavaFX "verschluckt" werden? AWT, Swing, JavaFX & SWT 8
M Umwandlung in den HSV-Farbraum lässt die Grafik pixelig werden AWT, Swing, JavaFX & SWT 8
H JButtons werden nicht angezeigt AWT, Swing, JavaFX & SWT 5
Lunar Swing JFrame erstellt; weitere Elemente werden nicht eingefügt/sind nicht zu sehen AWT, Swing, JavaFX & SWT 4
B JavaFX Von welcher Klasse und zu welchem Zeitpunkt werden Event-Objekte erstellt? AWT, Swing, JavaFX & SWT 3
ProggersWorld JavaFX Icons im TreeView werden nicht angezeigt AWT, Swing, JavaFX & SWT 1
E Swing Componenten werden nach Änderung des display modes verzerrt dargestellt AWT, Swing, JavaFX & SWT 8
Zrebna Problem bei Eventhandling (Value soll nach jedem erneutem Klick gelöscht werden) AWT, Swing, JavaFX & SWT 4
J e(fx)clipse funkioniert nicht / imports werden Rot gekennzeichnet AWT, Swing, JavaFX & SWT 1
ronbot77 JavaFX Rechtecke werden nicht neu gezeichnet AWT, Swing, JavaFX & SWT 8
R FXML File kann nicht hinzugefügt werden! AWT, Swing, JavaFX & SWT 2
L Komponenten eines Panels werden erst nach Klick darauf angezeigt AWT, Swing, JavaFX & SWT 13
H String teilen, damit bei JLabel keine Punkte am Ende angezeigt werden AWT, Swing, JavaFX & SWT 4
E Komponenten von JScrollPane werden nicht richtig ermittelt AWT, Swing, JavaFX & SWT 2
L Image kann nicht gefunden werden AWT, Swing, JavaFX & SWT 1
L Bilder werden in exportierter Datei nicht geladen AWT, Swing, JavaFX & SWT 6
J Bilder aus dem SceneBuilder werden in der Jar nicht dargestellt AWT, Swing, JavaFX & SWT 4
TheWhiteShadow JavaFX Bilder werden ungewollt Skaliert AWT, Swing, JavaFX & SWT 1
MoxxiManagarm JavaFX Auch ich versuche mit JavaFX warm zu werden AWT, Swing, JavaFX & SWT 9
A 2D-Grafik Zeichen werden über unabhängingen JRadioButton nicht gefüllt AWT, Swing, JavaFX & SWT 28
L Swing JPanels werden nicht angezeigt! AWT, Swing, JavaFX & SWT 7
ralfb1105 Swing SwingWorker - max 10 Threats werden gestartet !? AWT, Swing, JavaFX & SWT 5
S Fehler: Hauptklasse neon.Main konnte nicht gefunden oder geladen werden AWT, Swing, JavaFX & SWT 5
A Swing Meine JButtons werden nicht angezeigt bitte helft mir AWT, Swing, JavaFX & SWT 2
J JavaFX Elemente werden nicht zu TableView hinzugefügt AWT, Swing, JavaFX & SWT 3
SchmidiMC 2D-Grafik Grafiken werden nicht gezeichnet AWT, Swing, JavaFX & SWT 2
J Controler werden nicht inialisiert - Warum ? AWT, Swing, JavaFX & SWT 12
J TableView Daten werden nicht ausgegeben AWT, Swing, JavaFX & SWT 9
DaCrazyJavaExpert Swing Komponenten in GridBagLayout werden Falsch angeordnet AWT, Swing, JavaFX & SWT 1
N Swing JButtons werden nach repaint() doppelt dargestellt AWT, Swing, JavaFX & SWT 12
R JRE, NPAPI Java Plugins: Werden Plugins weiterhin bereit gestellt? AWT, Swing, JavaFX & SWT 5
I JAVA 8, JAVAFX und Eclipse – muss Eclipse extra eingerichtet werden? AWT, Swing, JavaFX & SWT 9
L Swing JComboBox kann nicht erstellt werden! AWT, Swing, JavaFX & SWT 2
DerMauri JavaFX Raspberry Pi meldet "Hauptklasse konnte nicht gefunden oder geladen werden" AWT, Swing, JavaFX & SWT 10
A Swing Programm funktioniert aber zwei Buttons werden angezeigt AWT, Swing, JavaFX & SWT 3
J Swing Strings werden nicht in Textfeld geschrieben AWT, Swing, JavaFX & SWT 8
J Swing Probleme mit ListSelectionListener(), Inhalte der JList werden gelöscht? AWT, Swing, JavaFX & SWT 6
MrSnake ComboBox-Einträge werden unsichtbar AWT, Swing, JavaFX & SWT 0
T JButton überlagern sich und werden erst beim Mausscrollen sichtbar AWT, Swing, JavaFX & SWT 2
X JavaFX Tooltips für XYChart-Knoten werden nicht angezeigt! AWT, Swing, JavaFX & SWT 3
P JavaFX - XCF Datei von Gimp kann nicht angezeigt werden AWT, Swing, JavaFX & SWT 3
J Meine ProgBar und ProgIndi werden nicht aktualisiert AWT, Swing, JavaFX & SWT 28
D JavaFX GUI Komponenten werden langsam bei größerer Datenmenge AWT, Swing, JavaFX & SWT 6
C AWT Textfelder werden nicht automatisch angezeigt AWT, Swing, JavaFX & SWT 2
D Buttons werden nebeneinander angeordnet AWT, Swing, JavaFX & SWT 9
C Textfeld und Label werden nicht angezeigt (Ubuntu) AWT, Swing, JavaFX & SWT 2
9 Swing Registrierte Knöpfe mit Bildern werden nicht angezeigt AWT, Swing, JavaFX & SWT 3
W Swing Farbige JPanels auf JFrame werden nicht gezeigt. Was mach ich falsch? AWT, Swing, JavaFX & SWT 7
Z Swing Swing: Elemente werden doppel/verschoben gezeichnet, sind teils unsichtbar etc... AWT, Swing, JavaFX & SWT 10
L Tooltips werden nicht mehr angezeigt AWT, Swing, JavaFX & SWT 5
R Swing Buttons werden nicht angezeigt AWT, Swing, JavaFX & SWT 4
K JTabs werden nicht angezeigt AWT, Swing, JavaFX & SWT 6
kaoZ Swing JToolBar, ImageIcon werden teilweise verdeckt AWT, Swing, JavaFX & SWT 0
S Swing Tooltips werden nicht angezeigt AWT, Swing, JavaFX & SWT 5
J JavaFX Eigene ListCell Problem(Objekte werden doppelt angezeigt) AWT, Swing, JavaFX & SWT 1
D JavaFX Mysteriöser Dropshadow hinter Tablabelschrift - Schatten kann nicht entfernt werden (FXML + CSS) AWT, Swing, JavaFX & SWT 6
I Swing Bilder werden nach Export nicht angezeigt AWT, Swing, JavaFX & SWT 1
A Swing JColorChooser's Icon will nicht getauscht werden. AWT, Swing, JavaFX & SWT 10
G JavaFX TableView - Änderungen werden nicht übernommen. AWT, Swing, JavaFX & SWT 3
A Swing Bilder werden nicht angezeigt AWT, Swing, JavaFX & SWT 3
A Swing Parameter werden bei Funktionsaufruf nicht ausgegeben AWT, Swing, JavaFX & SWT 2
R Komponenten werden erst nach maximierung des Frames sichtbar (Linux) AWT, Swing, JavaFX & SWT 5
D Image soll langsam sichtbar werden AWT, Swing, JavaFX & SWT 4
J Abbrechen muss immer einmal mehr gedrückt werden AWT, Swing, JavaFX & SWT 3
A Swing ActionListener kann nicht hinzugefügt werden AWT, Swing, JavaFX & SWT 4

Ähnliche Java Themen


Oben