GUI "friert ein"

Status
Nicht offen für weitere Antworten.

boesi

Aktives Mitglied
moin

Ich hab ein etwas größeres Programm, bei dem die Oberfläche mit Swing realisiert ist. Manchmal (eigentlich sehr selten, aber trotzdem nervig) friert scheinbar die Oberfläche ein. Das bedeutet das Anwendungsfenster wird nicht neugezeichnet und auf Maus/Tastatur wird nicht reagiert.

Wenn ich ein anderes Programm in den Vordergrund hol und dann wieder die Java-Anwendung, wird das Fenster mit dem aktuellen Inhalt neugezeichnet - das heisst die eigentliche Anwendung läuft "normal" weiter.

Die Oberfläche reagiert aber erst wieder normal, wenn ich das Fenster minimiere und wieder maximiere.

Prinzipiell hätte ich ja irgendeinen der (selbst programmierten) Threads im Verdacht, die Anwendung zu blockieren - aber wieso wird dann das Fenster neugezeichnet, wenn ich's wieder in der Vordergrund hol? Und wieso hört die Blockade auf, wenn ich das Fenster minimiere?


Vielen Dank schon mal für Eure Hilfe
cu boesi

[edit:] Das Programm läuft normalerweise immer maximiert, falls das eine Rolle spielt. Es gibt 2 verschiedene JFrames, von denen immer nur eins sichtbar ist. Die Blockade ist aber schon bei beiden Fenstern aufgetreten.
 

Wildcard

Top Contributor
Ich würde sagen du synchronisierst nicht immer mit dem Event Dispatcher und hast deshalb mit 'threading issues' zu kämpfen.
 

boesi

Aktives Mitglied
Wildcard hat gesagt.:
Ich würde sagen du synchronisierst nicht immer mit dem Event Dispatcher und hast deshalb mit 'threading issues' zu kämpfen.
Das klingt schon mal gut - hast du auch einen Weg, wie man mit derartigen Problemen vernüftig umgeht?

Ich hab mir jetzt ein global verfügbares ReentrantLock definiert und ruf nun dessen lock/unlock-Methode am Anfang/Ende jeder Methode auf, die im Kontext eines separaten Threads ausgeführt wird und auf GUI-Elemente zugreift. Ist das eine gute Strategie? Kann das so überhaupt funktionieren?

Gibs irgendwelche Automatismen / Plugins für Eclipse / ... um Quellen für solche Probleme zu finden?

Das Problem tritt halt so selten auf, dass ich eine Lösung nur schlecht testen kann. Und der Debugger ist bei sowas auch keine sonderlich große Hilfe.


cu boesi
 

byte

Top Contributor
boesi hat gesagt.:
Ich hab mir jetzt ein global verfügbares ReentrantLock definiert und ruf nun dessen lock/unlock-Methode am Anfang/Ende jeder Methode auf, die im Kontext eines separaten Threads ausgeführt wird und auf GUI-Elemente zugreift. Ist das eine gute Strategie? Kann das so überhaupt funktionieren?
Dafür gibt es SwingUtilities.invokeLater()!
 

Wildcard

Top Contributor
boesi hat gesagt.:
Ich hab mir jetzt ein global verfügbares ReentrantLock definiert und ruf nun dessen lock/unlock-Methode am Anfang/Ende jeder Methode auf, die im Kontext eines separaten Threads ausgeführt wird und auf GUI-Elemente zugreift. Ist das eine gute Strategie? Kann das so überhaupt funktionieren?
Argh! Bloß nicht :lol:
Was die GUI manipuliert, muss vom Dispatch Thread ausgeführt werden, also wie byto schon schreibt SwingUtilities#invokeLater und invokeAndWait
 

boesi

Aktives Mitglied
byto hat gesagt.:
Dafür gibt es SwingUtilities.invokeLater()!
Wenn ich also den Code hier habe ...
Code:
class MyThread extends Thread {
  public void run() {
    ...
    gui.method(para1, ...);
  }
}
... dann änder ich den wie folgt ab ...
Code:
class NotifyThread extends Thread {
  para1, ...
  public NotifyThread(para1, ...) {
    this.para1 = para1;
  }
  public void run() {
    gui.method(this.para1, ...);
  }
}
class MyThread extends Thread {
  public void run() {
    ...
    SwingUtilities.invokeLater(new NotifyThread(para1, ...));
  }
}
tfa hat gesagt.:
Wenn der Job länger dauert, google mal nach "Swingworker".
Die Tutorials und Doku dazu stehen auf meiner Leseliste auf jeden Fall ziemlich weit oben. Im Moment gehts aber nicht um "länger dauernde Jobs", sondern um Single-Shot-Timer und Hintergrund-Threads, die ständig laufen und gelegentlich das GUI über neue Daten informieren - wobei das speichern der Daten aber unabhängig vom Gui ist.
 

boesi

Aktives Mitglied
Hmpf grummel jetzt hab ich in sämtlichen Threads invokeLater eingesetzt und das Programm bleibt trotzdem gelegentlich stehen. Ich hab sogar das Gefühl das es jetzt mehr Probleme gibt als vorher - aber ich glaub das täuscht.
 

boesi

Aktives Mitglied
boesi hat gesagt.:
Hmpf grummel jetzt hab ich in sämtlichen Threads invokeLater eingesetzt und das Programm bleibt trotzdem gelegentlich stehen. Ich hab sogar das Gefühl das es jetzt mehr Probleme gibt als vorher - aber ich glaub das täuscht.
Da hab ich doch glatt mit dem Debugger einen (bzw gleich 9 auf einmal) TimerTask "wiedergefunden", den ich glatt vergessen hatte ... Na mal sehen, wie's weitergeht ...
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen


Oben