4 Stimmen

Java Swing-Anwendung: Wie kann man Daten vom GUI-Thread zu einem anderen Thread übertragen?

In meiner Java-Anwendung mit einer Swing-GUI möchte ich folgendes erreichen.

Es läuft ein Nicht-GUI-Thread, der einige Arbeiten ausführt. An einem bestimmten Punkt benötigt dieser Thread eine Eingabe des Benutzers, bevor er fortfahren kann. Dann möchte ich einige Änderungen an der grafischen Benutzeroberfläche vornehmen, eine bestimmte GUI-Aktion abwarten (z. B. das Drücken der Schaltfläche "OK" durch den Benutzer), die eingegebenen Daten von der grafischen Benutzeroberfläche an den Nicht-GUI-Thread weiterleiten und ihn mit der Berechnung fortfahren lassen.

Wenn ich mich umschaue, habe ich eine Menge Informationen darüber gefunden, wie man die Ausführung einer (lange laufenden) Aufgabe vom Swing-GUI-Thread auf einem anderen Thread initiiert, aber nichts zu meinem Problem.

SwingUtilites.invokeAndWait klingt so, als ob es die Aufgabe erfüllen würde, aber zunächst braucht es eine Runnable Argument anstelle eines Callable Es gibt also keine einfache Möglichkeit, ein Ergebnis zurückzugeben, und zweitens löst es nicht das Problem des Wartens auf ein bestimmtes GUI-Ereignis.

Ich weiß, dass ich meine eigene Lösung finden könnte, indem ich z. B. eine CountDownLatch Das Problem scheint mir jedoch so häufig aufzutreten, dass es eine Standardlösung geben sollte.

Meine Fragen lauten also: Ist dies wirklich ein häufiges Problem, und wenn ja, gibt es eine Lösung in der Standardbibliothek / Bibliotheken? Wenn es keine Standardlösung gibt, wie würden Sie es lösen? Wenn dieses Problem nicht häufig auftritt, warum nicht?

6voto

Bill Punkte 12254

Das Starten der GUI-Änderungen ist einfach, daher nehme ich an, dass Sie nur danach fragen, wie Sie Daten an den Worker-Thread zurückbekommen.

Erstellen Sie zunächst eine Warteschlange sperren . Der Worker-Thread soll Folgendes aufrufen take() in der Warteschlange, und sie wird blockiert. Sobald der Benutzer eine gültige Eingabe in den GUI-Bereich eingibt, wird diese in die Warteschlange mit offer() und der Worker-Thread erhält die Daten und kann fortfahren.

1voto

JProgrammer Punkte 1135

Ich denke, Sie können Folgendes verwenden ExecutorService wo Sie auch den Fortschritt Ihrer Aufgabe verfolgen können durch Zukunft Schnittstelle.

1voto

Tom Hawtin - tackline Punkte 142461

java.awt.EventQueue.invokeLater eignet sich gut für die Ausführung von Code auf dem AWT EDT. Wahrscheinlich ist es am besten, veränderbare Daten zu kopieren oder besser unveränderbare Daten zu verwenden. Sperren sind möglich, aber ein bisschen riskant.

Wenn der andere Thread eine Ereignisvermittlungsschleife ist, könnten Sie etwas wie folgt implementieren invokeLater für Ihr Thema (aber machen Sie es nicht statisch!). Verwenden Sie es wahrscheinlich hinter einer Schnittstelle, die für das Verhalten des Threads sinnvoll ist - damit es echte Operationen sind und nicht run die alles tun kann, was sie will. Wenn Ihr Thread blockieren wird, dann wird ein BlockQueue ist in Ordnung, aber blockieren Sie nicht vom AWT EDT.

java.awt.EventQueue.invokeAndWait ist wie die Verwendung eines Schlosses. Wahrscheinlich werden Sie ein anderes Schloss verwenden. Oder vielleicht ein Schloss wie invokeAndWait in Ihrem eigenen Thread. Wenn Sie das nicht tun, verwendet AWT trotzdem eine Sperre. Unkontrollierte verschachtelte Sperren bedeuten also wahrscheinlich einen Deadlock. Verwenden Sie nicht invokeAndWait !

0voto

AlexTheo Punkte 3847
final bool result = doSomething();
SwingUtilities.invokeLater( new Runnable(){
       //Runnable method implementation. 
       //use result in your method like local var.
    });

Stellen Sie sicher, dass Ihre gemeinsam genutzten Daten synchronisiert werden, indem Sie Sperrobjekte verwenden. Wenn Sie Argumente an Runnable übergeben müssen, machen Sie Ihre lokalen Variablen einfach final, und verwenden Sie sie in der Run-Methode.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X