Willkommen in der wundervollen Welt des blockierten Ereignis -Versands (und Verstoß gegen den ersten Thread)
Grundsätzlich ist Swing eine einzelne Thread -Umgebung, alle Updates und Modifikationen an der Benutzeroberfläche werden voraussichtlich im Kontext des Ereignis -Versand -Threads (auch bekannt als EDT) ausgeführt.
Die EDT ist unter anderem für die Bearbeitung von Repaint -Anfragen verantwortlich. Wenn Sie diesen Thread aus irgendeinem Grund blockieren (beispielsweise mit einer lang laufenden Schleife oder einem Blockierungs -IO), verhindert er, dass die EDT neue Farbanforderungen verarbeitet, so hat.
Der Grund, warum Sie einen Unterschied zwischen dem Laufen sehen könnten Timer
Direkt und die Verwendung in Ihrer GUI, weil die Bewerbung begonnen wird, wird sie im Inneren ausgeführt, was allgemein bekannt ist, der "Haupt" -Thread.
Wenn Sie zum ersten Mal einen Swing -Container der obersten Ebene erstellen, wird der EDT gestartet (was ein separater Thread ist), was bedeutet, dass die Benutzeroberfläche in seinem eigenen Thread angezeigt wird. Die Anwendung wird jedoch weiterhin im "Haupt" -Thread ausgeführt, wobei Ihr Ihre Erläuterungen ermöglicht, sodass Sie Ihrem Thread ermöglichen. iterate
Methode, um unabhängig vom EDT zu laufen.
Wenn Sie jedoch versuchen, es aus Ihrer GUI auszuführen, läuft alles im Kontext des EDT, was dazu führt, dass es blockiert wird.
Schauen Sie sich zunächst an
Um das Problem basierend auf Ihrem Beispielcode zu beheben, würde ich vorschlagen, a zu verwenden SwingWorker
. Auf diese Weise können Sie Ihre "Langzeitaufgabe" in einem Hintergrund -Thread ausführen, bietet jedoch eine Reihe von Methoden, mit denen Sie Ihre Updates wieder an die EDT synchronisieren können. Dies ist sehr wichtig, da Sie niemals versuchen sollten, die Benutzeroberfläche zu aktualisieren oder ihren Status von einem anderen Thread zu ändern, der EDT.
Sich ansehen Arbeiterfäden und Swingworker für mehr Details
Und bei Bedarf einige Beispiele ...