2010-10-07 15 views
16

Eine dämliche Frage, aber ich kann das nicht zum Laufen bringen: Ich habe einen langwierigen Prozess in einer Swing-Anwendung, der einige Minuten dauern kann. Ich möchte dem Benutzer während dieses Vorgangs einen Fortschrittsdialog anzeigen. Ich möchte auch verhindern, dass der Benutzer weitere Aktionen ausführt, z. B. einen Knopf drücken, während der Prozess läuft.Non-blocking modal Swing-Fortschrittsdialog

Wenn ich den Prozess auf dem EDT mache, verhindert dies offensichtlich den Endanwender, irgendetwas zu tun, während der Prozess weitergeht. Da der EDT jedoch gerade mit der Verarbeitung beschäftigt ist, kommt er nie dazu, den Inhalt des Dialogs zu rendern, daher erhalte ich nur den Umriss des Dialogs.

Aber wenn ich den Prozess in einem Worker-Thread ausführen, kann der Endbenutzer auf Schaltflächen klicken und den EDT dazu veranlassen, den Status zu manipulieren, dass der Worker ebenfalls zur gleichen Zeit manipuliert, mit Bad Zeug als Konsequenz. Wenn ich den Dialog modal mache, passiert das nicht, aber modal in Swing bedeutet auch blockiert, so dass der Moment setVisible(true) aufrufen, blockiert der Thread für immer.

Meine aktuelle "Lösung" besteht darin, einen Worker-Thread zu verwenden und dann einen separaten Thread zu spawnen, dessen einziger Zweck darin besteht, die blockierende Natur von setVisible zu absorbieren. Sicherlich muss es eine bessere Lösung geben!

Wie bekomme ich einen Dialog, der den Benutzer daran hindert, mit dem Rest des Systems zu interagieren (modal), aber den Thread, der ihn sichtbar macht, nicht blockiert?

+0

Siehe auch: http://stackoverflow.com/questions/3954120/swing-modal-dialog-refuses-to-close-sometimes – Zarkonnen

Antwort

15

Sie sollten die GlassPane verwenden, um zu verhindern, dass der Benutzer interagiert. Das Gute daran ist, dass es modal für den Benutzer und nicht für Ihr Programm ist, damit Ihr Thread nicht blockiert wird.

Die gute Nachricht ist, dass Sie es auch für coole GUI-Effekte wie Schattierung der GUI-Teil beschäftigt verwenden können und mit denen der Benutzer nicht interagieren kann. Sie können auch ein beschäftigtes GIF-Bild in der GlassPane anzeigen.

Links: -

  1. Official tutorial on GlassPane
  2. Some helpful tutorials
  3. Another tut
  4. Oreilly's Swing Hacks ist ausgezeichnet.
0

Sie müssen etwas falsch machen. Versuchen Sie das Tutorial auf How to Use Progress Bars. Wenn Sie verstehen, wie dieser Code funktioniert, sollte er Ihnen die Richtung geben, in der Sie die erforderliche Funktion erreichen.

Beachten Sie, dass Fortschrittsbalken in der Regel modal sind.

+0

Der Code im Tutorial nicht modale Fortschrittsbalken/Dialoge erzeugt. Ich kann immer noch die GUI manipulieren, während der Prozess im SwingWorker läuft. – Zarkonnen

+0

@Zarkonnen Ich nehme an, Sie beziehen sich auf die ProgressMonitor-Demos. Versuchen Sie stattdessen eine JProgressBar in einem modalen Dialog. –

+0

Haben Sie es getan. Wenn Sie die Demo jedoch ausführen, können Sie das Hauptfenster weiterhin bearbeiten, während der Fortschrittsmonitor angezeigt wird. Wenn ich den Fortschrittsmonitor ersetze, hört er auf zu arbeiten, da der EDT erneut festsitzt und darauf wartet, dass setVisible zurückkehrt. – Zarkonnen