Swing invokeLater nötig beim GUI erstellen?

Bile Demon

Bekanntes Mitglied
Hallo,

ich habe mal wieder eine kleine Frage, die hoffentlich recht schnell beantwortet ist.
Schon eine ganze Weile schaue ich im Netz nach einer Antwort, finde aber leider nichts konkretes zu meiner Frage.

In vielen Beispielen zu Swing wird eine GUI in der main-Methode so erstellt:

Java:
SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        createAndShowGUI();
    }
});

invokeLater soll ja vor allem dann benutzt werden, wenn man die GUI aus einem anderen Thread als dem EDT aktualisieren will. Aber wieso ist sowas schon beim Erstellen der GUI nötig?

Ich frage schon deshalb, weil ich bisher immer folgendermaßen meine Programme aufgebaut habe:

Java:
public static void main(String[] args){
    TestJFrame tjf = new TestJFrame();
    tjf.setVisible(true);
    doOtherStuff();
    // etc.
}

Hatte bisher nie Probleme damit. Die GUI lief fleißig nebenher, so wie sie sollte.
 
S

SlaterB

Gast
Why InvokeLater (Swing / AWT / SWT / JFace forum at JavaRanch)
javax.swing (Java Platform SE 6)

im Detail lesen bin ich nie der fleißigste,
eine Vermutung von mir: während die GUI aktiviert wird, flattern erste Events wie das erste Zeichnen ein,
wenn der main-Thread die GUI startet, kann der AWT-Thread das schon machen,
gleichzeitig, während vielleicht noch Initialisierungen laufen,

das muss keinen Fehler geben, aber kann, besonders bei größeren Programmen,
passiert alles im AWT-Thread, ist der saubere Ablauf garantiert
 

Bile Demon

Bekanntes Mitglied
Alles klar, damit kann ich schonmal was anfangen.

Hinter den Links steht unter anderem das hier:
Exceptions to the rule: An application's GUI can often be constructed and shown in the main thread.

Java:
public class MyApplication {
    public static void main(String[] args) {
       JFrame f = new JFrame("Labels");
       // Add components to
       // the frame here...
       f.pack();
       f.show();
       // Don't do any more GUI work here...
   }
}

Das Erstellen der GUI scheint die einzige Ausnahme zu sein, wo invokeLater nicht unbedingt nötig ist. Bei jeder folgenden Änderung der GUI von außen muss man es weiterhin verwenden.

Trifft das auch dann zu, wenn ich keine Methode aufrufe, aber z.B. eine einfache Variable verändere? Also eine Änderung, die nur indirekt oder gar keine Auswirkung auf die Optik der GUI hat? Muss das dann auch im AWT-Thread passieren?
 

Kr0e

Gesperrter Benutzer
Hm, also fast alle Statusvariablen sind weder volatile noch synchronized. Daher sollte invokeLater immer benutzt werden.

Klar, beim Erstellen der Gui ist das nicht nötig, da kein Thread bislang dieses Objekt kennt und in sofern keine Visibilityprobleme oder Synchronizedprobleme auftreten sollten.


PS: Der AWT Thread ist genauso ein Thread wie jeder andere. Es gelten die gleichen Regeln... Synchronisierung (Eben halt invokeLater!) ist immer dann nötig, wenn 2 Thread simultan auf DAten zugreifen. Da der AWT Thread ständig drauf zugreift ist jede Änderung von außen eine Verletzung dieser Regel. Grundsätzlich würde ich invokeLater benutzen.... Es gibt auch viele Methoden die das selbst intern überprüfen.. Nach dem Motto "Ist der Thread, der das gerade ausführt ein AWT Thread ? Ja? -> Führe es aus - Nein ? -> Füg es in die Queue und führe es später im AWT Thread aus.". Generell sind wohl so Dinge wie setVisible intern bereits synchronisiert... Aber ich würde zur Sicherheit von Anfang an sauberen Code schreiben. Natürlich kannst du in Callbackmethoden (ActionListener, KeyListener, etc) direkt die Methoden aufrufen (Die Callbackmethoden werden in AWT Threads gestartet).
 
Zuletzt bearbeitet:
S

SlaterB

Gast
> Klar, beim Erstellen der Gui ist das nicht nötig

ums Erstellen geht es doch gerade..,
mich überrascht diese offizielle Exception etwas, zeigt umso mehr dass ich hier nicht mit gesicherten Wissen glänze,

Technically, the setVisible call is unsafe because the components have already been realized by the pack call. However, because the program doesn't already have a visible GUI, it's exceedingly unlikely that a paint request will occur before setVisible returns.
klingt aber auch nicht sehr vertrauenswürdig

edit:
also dass ein Fehler bei kleinen Programmen in robuster JVM (Linux, OpenJDK usw. vertraue ich nicht ganz so sehr) praktisch nie auftritt kann ich selbst bestätigen,
ich verzichte auch immer auf invokeLater in Testprogrammen,
aber das ist ja kein Grund das offiziell gutzuheißen

-----


Befehle nach setVisible(true) stehen selbstverständlich ganz außer Frage, wenn sie mit der GUI zusammenhängen,
'indirekt' wäre im Detail zu klären, klingt vorerst harmlos
 
Zuletzt bearbeitet von einem Moderator:

Bile Demon

Bekanntes Mitglied
Bestens. Dann gewöhne ich mir künftig einfach das invokeLater beim GUI instanziieren an.

Zum Thema "indirekt":
Bei invokeLater denke ich an so offensichtliche Änderungen wie JButtons ein- oder ausblenden durch einen anderen Thread. Da wäre mir klar, dass man das dem EDT überlassen sollte.

Was ist aber wenn ich _von außen_ z.B. in einem JPanel eine Boolean-Variable setze, die darüber entscheidet, ob in paintComponent() auf dem JPanel ein bestimmter Bereich gezeichnet wird oder eben nicht. Das wäre so meine Definition von indirekt. Müsste ich dieses Setzen der Variable dann auch via invokeLater an den EDT übergeben, oder ist das in Ordnung?
 
S

SlaterB

Gast
bei einem boolean/ sonstiger recht atomarer Wechsel, z.B. einer Farbe,
könnte das Problem bestehen, dass das paint darauf mitten im Zeichenvorgang reagiert,
die untere Hälfte mit neuer Farbe malt oder neue Koordinaten, während die obere fertige Hälte noch alte Einstellungen zeigt,
(wenn man weiß wie sich die Daten auswirken, dann vielleicht weniger kritisch)

wird gar eine Liste von Daten um ein Element erweitert kann es zur klassischen ConcurrentModificationException kommen,
das Paradebeispiel für Synchronisation,

das klingt also für mich ziemlich direkt, normalerweise ein Fall für invokeLater,
der Wahrscheinkeit nach aber entsprechend nicht unbedingt,
besonders wenn man selber gut kontrolliert dass erst danach ein repaint() drankommt
 

Marco13

Top Contributor
Praktisch alle Swing-Beispiele verwenden invokeLater. Laut Threads and Swing wäre es beim Erstellen eigentlich meistens nicht notwendig (außer wenn man z.B. irgendwo
pack();
setVisible(true);
macht), aber ich habe schon L&Fs gesehen, die mit einer Exception abekachelt sind, wenn man das Erstellen ohne invokeLater macht. (Ich meine sogar, das Nimbus dafür anfällig wäre, aber habe natürlich keinen 100% reproduzierbaren Testfall dafür).

Also: Mit den 3 Zeilen mehr, die das ganze in invokeLater wickeln, ist man auf der sicheren Seite.
 

Bile Demon

Bekanntes Mitglied
Uff, an sowas habe ich gar nicht gedacht. Da bieten (scheinbar) fehlerfrei laufende Programme wohl doch mehr Fehlerpotenzial als ich für möglich gehalten habe.

Das klingt fast so als müsste ich doch mal das eine oder andere alte Programm von mir auf solche Unpässlichkeiten hin überprüfen und korrigieren.

Vielen Dank für die Kommentare. Damit wäre das Thema für mich erledigt.
 

Kr0e

Gesperrter Benutzer
Vlt hast du deine alten Programme auf Singlecore Rechnern laufen gelassen :p ? Die physikalische Prozessoranzahl ist hier extremst entscheidend. Ich hab zu diesem Thema letztens ziemlich intensiv gegooglet.

Multithreading hat generell 3 Probleme: 1. Ordering, 2. Visibility, 3. Atomacity.

1. und 2. fallen bei Singlecore nicht auf. Visibility ist ein Problem, dass durch mehrere CPU Caches entsteht (letztens qualvoll durch meinen Info2 Prof. erfahren :D). Ordering ist ebenfalls ein Problem, dass erst bei WIRKLICHER Parallelität auftaucht (mehrere physikalische Prozessoren).

3. Atomarität ist tatsächlich bei allen primitiven typen und Referezen (außer long, double) gegeben. Allerdings sollte man aufpassen, was genau atomar ist und was nicht. Atomar sind nur setten/getten. Inkrementieren ist keine atomare Operation. Dafür gibts die Atomic*... Typen von Java .. öhm 6 ?

Ich finde, dass das MThreading wirklich eines der komplexesten Probleme ist, vorallem wenn man jenseits von synchronized agiert und LockFree Pattern benutzen will!
 

Bile Demon

Bekanntes Mitglied
Tatsächlich waren da am Anfang noch Singlecore-Rechner am Werk, aber nicht ausschließlich. Meine Programme werden ohnehin nie so aufwändig, dass ich echte Parallelität mit Locks bräuchte. Wird Zeit, dass so ein Fall mal eintritt ;)

Ich habe eben in einem meiner Projekte das Erstellen der GUI via invokeLater dem AWT-Thread überlassen. Prompt gab es eine NPE, weil ich direkt im Anschluss von außen auf Komponenten der GUI zugreifen wollte, der AWT-Thread mit dem Aufbauen der GUI aber noch gar nicht fertig war. Vorher ging das natürlich problemlos weil nicht parallel.

Als Workaround habe ich zuerst eine Wartezeit von 100 ms eingebaut - danach lief es wieder wie gewohnt. Dann ist mir eingefallen, dass es ja noch invokeAndWait gibt. Jetzt weiß ich endlich wofür das da ist :D
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Swing GUI wird nach invokeLater() langsam AWT, Swing, JavaFX & SWT 19
B Frame hängt sich auf trotz invokeLater AWT, Swing, JavaFX & SWT 1
Ollek Swing SwingUtilities invokeLater und invokeAndWait AWT, Swing, JavaFX & SWT 4
X Swing GUI-Änderungen mit invokeLater AWT, Swing, JavaFX & SWT 4
W Swing SwingUtilities.invokeLater wie konsequent anwenden? AWT, Swing, JavaFX & SWT 3
Dit_ SwingUtilities.invokeLater und Modaler JDialog AWT, Swing, JavaFX & SWT 11
Dit_ Frage zum Thema SwingUtilities.invokeLater AWT, Swing, JavaFX & SWT 5
H invokeLater Problem AWT, Swing, JavaFX & SWT 8
I Swing Wann invokeLater() verwenden? AWT, Swing, JavaFX & SWT 7
G Frage zu SwingUtilities.invokeLater AWT, Swing, JavaFX & SWT 16
E einfache Frage zu invokeLater() AWT, Swing, JavaFX & SWT 4
G Frage zu SwingUtilities.invokeLater AWT, Swing, JavaFX & SWT 9
G Schachtelung bei invokeLater AWT, Swing, JavaFX & SWT 4
B SwingUtilities.invokeLater() AWT, Swing, JavaFX & SWT 12
F invokeLater() vs synchronized(Object) AWT, Swing, JavaFX & SWT 5
T invokeLater - Wann? AWT, Swing, JavaFX & SWT 29
L invokeLater in der main-Methode AWT, Swing, JavaFX & SWT 6
D GUI in JFrame mit invokeLater verändern AWT, Swing, JavaFX & SWT 5
M GUI in Verbindung mit invokeLater() bzw. invokeAndWait() AWT, Swing, JavaFX & SWT 2
J Frame mit Button erstellen - Warum ist es nötig, Frame über Unterklasse zu erstellen? (Reg Listener) AWT, Swing, JavaFX & SWT 2
P Swing Vom BufferedImage bei paintComponent nur soviel zeichnen, wie nötig AWT, Swing, JavaFX & SWT 3
C SWT Shell update probleme - Mausbewegung nötig AWT, Swing, JavaFX & SWT 2
A setSize nötig um Elemente sichtbar zu machen? AWT, Swing, JavaFX & SWT 3
M JDialog unter win und linux unterschiedliche größe nötig? AWT, Swing, JavaFX & SWT 4
byte SWT: dispose() hier nötig? AWT, Swing, JavaFX & SWT 2
P GridBagLayout zwingend nötig? AWT, Swing, JavaFX & SWT 10
MartinNeuerlich Kann mir jemand, der einen Mac mit einem m1 oder m2-Chip hat, eine POM geben mit der Javafx-Fullscreen beim Mac mit m-Chip funktioniert? AWT, Swing, JavaFX & SWT 1
berserkerdq2 Wie greife ich auf ein Element zu, welches ich beim Scenebuilder erstellt habe AWT, Swing, JavaFX & SWT 10
H AWT Dialog Größe ändern - Schwarzer Inhalt beim groß ziehen AWT, Swing, JavaFX & SWT 1
L jComboBox Actionlistener wird beim erstmaligen Befüllen getriggert AWT, Swing, JavaFX & SWT 7
B Output GUI funktioniert nur beim ersten Mal richtig. AWT, Swing, JavaFX & SWT 4
A JavaFX exportierte Jar ohne beim starten die Libs hinzufügen? AWT, Swing, JavaFX & SWT 2
TheWhiteShadow JavaFX ListView Problem beim Entfernen von Elementen AWT, Swing, JavaFX & SWT 1
S Fehler beim Öffnen weiterer FXML AWT, Swing, JavaFX & SWT 11
I Probleme beim Drucken auf einen PDF-Drucker AWT, Swing, JavaFX & SWT 8
G Gui updated beim zweiten Aufruf nicht mehr AWT, Swing, JavaFX & SWT 15
K JavaFX Resizing-Problem beim BorderLayout (Center Component) beim Arbeiten mit mehreren FXMLs AWT, Swing, JavaFX & SWT 2
W Nullpointer Exception beim übertragen von Daten von Scene zu Scene AWT, Swing, JavaFX & SWT 6
missy72 JavaFX Wiederholen einer IF-Abfrage beim erneuten Öffnen einer Stage AWT, Swing, JavaFX & SWT 11
D JavaFX Probleme beim nachtäglichen hinzufügen der jfx dependency AWT, Swing, JavaFX & SWT 7
R NullPointerException beim Start des Fensters AWT, Swing, JavaFX & SWT 1
D JavaFX Label flackert beim aktualisieren AWT, Swing, JavaFX & SWT 12
J Kann mir jemand beim MediaPlayer helfen ? AWT, Swing, JavaFX & SWT 2
S JavaFx Zufallsfarbe beim Button-Klick AWT, Swing, JavaFX & SWT 22
L Swing JDialog ton beim klicken ausstellen AWT, Swing, JavaFX & SWT 1
sascha-sphw JavaFX ListCell höhe verändert sich beim ändern der Text-Farbe AWT, Swing, JavaFX & SWT 14
H Beim JFrame erstellen ein anderes schließen AWT, Swing, JavaFX & SWT 0
L Swing JLabel wird beim ändern der Schriftart immer neu gezeichnet. AWT, Swing, JavaFX & SWT 2
M AWT Kann meinen Fehler beim ActionListener nicht finden AWT, Swing, JavaFX & SWT 5
R 2D-Grafik Massive Frame Drops beim Benutzen von AffineTransformOp AWT, Swing, JavaFX & SWT 2
ruutaiokwu Swing windowStateChanged macht exakt das Gegenteil beim Verändern der Fenstergrösse AWT, Swing, JavaFX & SWT 3
J Exception beim JFrame erstellen AWT, Swing, JavaFX & SWT 6
B 2D-Grafik paintcomponent Probleme beim zeichnen AWT, Swing, JavaFX & SWT 10
D JInternalFrame wechselt Position beim ersten Click AWT, Swing, JavaFX & SWT 0
steven789hjk543 Swing Verstehe etwas beim GUI nicht AWT, Swing, JavaFX & SWT 3
L JavaFX Probleme beim Installieren JavaFX11 / JavaFX12 -- Eclipse 2019-03 AWT, Swing, JavaFX & SWT 3
H JavaFX Probleme Beim Wechseln der scene als .fxml AWT, Swing, JavaFX & SWT 7
A Fehler beim Hintergrund AWT, Swing, JavaFX & SWT 17
F JavaFX Probleme beim automatischen Konvertieren AWT, Swing, JavaFX & SWT 4
J Hilfe beim tablevies AWT, Swing, JavaFX & SWT 2
L JavaFX Fehler beim setzen von Farben AWT, Swing, JavaFX & SWT 16
T LookAndFeel LookAndFeel funktioniert nicht beim JFrame wechsel AWT, Swing, JavaFX & SWT 3
L Java FX Exception beim start AWT, Swing, JavaFX & SWT 2
L JSplitPane Divider Location beim Maximieren AWT, Swing, JavaFX & SWT 6
L JavaFX Problem beim Aufrufen einer Methode AWT, Swing, JavaFX & SWT 5
J ObservableList wirft exception beim zweiten füllen. AWT, Swing, JavaFX & SWT 4
emma_louisa JavaFX Werte beim Aufrufen des Fensters übernehmen (SceneBuilder) AWT, Swing, JavaFX & SWT 3
Tronert JavaFX Fehler beim Ändern der font-weight AWT, Swing, JavaFX & SWT 7
W Swing Hilfe beim Einbinden von Bildern in einem JFrame AWT, Swing, JavaFX & SWT 8
D Kein Icon beim JTabbedPane AWT, Swing, JavaFX & SWT 1
L JavaFX LoadException beim Laden von JavaFX Anwendung AWT, Swing, JavaFX & SWT 6
T Java FX Probleme beim befüllen eines Tableviews AWT, Swing, JavaFX & SWT 5
N Eclipse - GUI - MacBook - Buttonsichtbarkeit beim Anlegen/Erstellen AWT, Swing, JavaFX & SWT 14
S AWT Probleme beim Zeichnen AWT, Swing, JavaFX & SWT 3
T JButton wird beim vergrößern des Fensters erst sichtbar AWT, Swing, JavaFX & SWT 4
Tommy135 JavaFX JavaFX Fehler beim Scenewechsel AWT, Swing, JavaFX & SWT 23
E Swing Miserable Performance beim Ändern der Hintergrundfarbe von JLabels AWT, Swing, JavaFX & SWT 3
L Charset beim Drucken falsch AWT, Swing, JavaFX & SWT 2
MaxG. Swing Farbe von Button beim drücken ändern AWT, Swing, JavaFX & SWT 4
H JavaFX Kriege fehler beim Fenster wechseln AWT, Swing, JavaFX & SWT 7
D Swing Swing Objekte sehen im Entwurf anders aus als beim Ausführen AWT, Swing, JavaFX & SWT 3
R Swing Programm läuft nur beim Debuggen korrekt ab AWT, Swing, JavaFX & SWT 4
I 2D-Grafik Problem beim Ändern der Farbe eine 2d Objekts AWT, Swing, JavaFX & SWT 3
K Probleme beim JPasswordField AWT, Swing, JavaFX & SWT 11
W Kodierung (CharSet) beim Schreiben ändern AWT, Swing, JavaFX & SWT 1
D Swing JComboBox (DefaultComboBoxModel) überschreibt Eintrag beim erstellen AWT, Swing, JavaFX & SWT 0
T JButton überlagern sich und werden erst beim Mausscrollen sichtbar AWT, Swing, JavaFX & SWT 2
Thallius Swing "..." beim JLabel verhindern? AWT, Swing, JavaFX & SWT 3
P Scrollbalken verschwinden beim Zoomen AWT, Swing, JavaFX & SWT 4
A JavaFX DatePicker in Swing beim Start nicht sichtbar AWT, Swing, JavaFX & SWT 2
D JavaFX Probleme bei Service-Klasse beim ändern der GUI AWT, Swing, JavaFX & SWT 8
D JavaFX (WebStart) Graues Fenster beim Start AWT, Swing, JavaFX & SWT 4
K Probleme beim zeichnen mit paintComponent() AWT, Swing, JavaFX & SWT 1
O Swing JList beim Klicken in der GUI erstellen AWT, Swing, JavaFX & SWT 6
D Frame beim starten eines anderen Frames schließen AWT, Swing, JavaFX & SWT 2
R Hilfe beim ändern des Hintergrundes eines JFrames AWT, Swing, JavaFX & SWT 9
7 JavaFX Problem beim Zeichnen eines Dreiecks in einem GUI AWT, Swing, JavaFX & SWT 6
L JavaFX Verzögerung beim Laden von Daten AWT, Swing, JavaFX & SWT 6
S NullPointer Exception beim Laden von Bildern AWT, Swing, JavaFX & SWT 11
I JavaFX Speichern der eingefügten Einträge beim Neustart des Programms AWT, Swing, JavaFX & SWT 2

Ähnliche Java Themen

Neue Themen


Oben