5 Stimmen

Swing-Komponenten korrekt aktualisieren

Ich habe Werte auf Swing-Komponenten genau wie ich würde jede andere Variable, aber ich stieß auf diese Seite - https://bitguru.wordpress.com/2007/03/21/will-the-real-swing-single-threading-rule-please-stand-up/ - und es scheint, dass ich alle Änderungen an Swing-Komponenten mit einem Ereignis-Dispatching-Thread machen -

Also, ist dies richtig, sollte ich den gesamten Code ändern, wo ich Swing-Komponenten von diesem aktualisiert

    String name = this.getNameTextfield().getText();
    String password = new String(this.getPasswordField().getPassword());
    String confirmPassword = new String(this.getConfirmPasswordField().getPassword());

dazu?

java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
               String name = this.getNameTextfield().getText();
               String password = new String(this.getPasswordField().getPassword());
               String confirmPassword = new String(this.getConfirmPasswordField().getPassword());
            }
        });

Ist das die gängige Praxis?

Edit: Oops, gerade kopiert und eingefügt einige meiner Komponente im Zusammenhang mit Code, übersehen die Tatsache, dass es warnt Aktualisierung componenets.

9voto

kleopatra Punkte 50122

Die Swing-Bibel hat eine Kapitel über Gleichzeitigkeit unterm Strich:

alle Codes, die eine oder interagiert mit Swing-Komponenten müssen auf dem Ereignis-Versand-Thread laufen

(Hervorhebung von mir)

Sie müssen also immer sicherstellen, dass alle Zugriffe, ob lesend oder schreibend, auf dem EDT erfolgen.

Das Gute daran ist, dass Sie, sobald die Anwendung auf dem EDT korrekt gestartet ist, bereits sind und fast alle Zugriffe erfolgen natürlich über den EDT. Das ist nur dann nicht der Fall, wenn Sie explizit einen anderen Thread gestartet haben (z.B. um eine langwierige Hintergrundaufgabe zu erledigen) und sich in der Benutzeroberfläche zurückmelden müssen: dann müssen Sie die Zugriffsaufrufe in invokeLater verpacken (oder einen SwingWorker verwenden, der dies intern tut)

4voto

Adam Punkte 34323

Strings sind unveränderlich - die folgenden Zeilen sind so ziemlich gleichwertig

String password = new String(this.getPasswordField().getPassword());
String password = this.getPasswordField().getPassword();

Sie verändern die Komponenten nicht.

Wenn Sie sie aktualisieren, dann nur, wenn die Aktualisierung aus einem anderen Thread stammt. Wenn Sie z. B. ein Textfeld über einen ActionListener aktualisieren, der an eine Schaltfläche angehängt ist, wäre dies unnötig, da Sie sich bereits im Event-Dispatch-Thread befinden.

Für maximale Korrektheit sollten Sie zuerst feststellen, ob Sie auf dem EDT sind.

Runnable update = new Runnable() {
    @Override
    public void run() {
        getNameTextfield().setText("foo");
    }
};
if (SwingUtilities.isEventDispatchThread()) {
    update.run();
} else {
    SwingUtilities.invokeLater(update);
}

3voto

MByD Punkte 133514

In diesem speziellen Fall ändern Sie keine Komponente, so dass Sie es nicht auf dem EDT tun müssen, aber wenn Sie die UI ändern, ist die zweite Methode richtig.

1voto

mikera Punkte 103423

Wenn Sie nur Daten aus Komponenten lesen, brauchen Sie dies wahrscheinlich nicht zu tun. Die meisten Lesevorgänge von Swing-Komponenteneigenschaften sind thread-sicher.

invokeLater sollte verwendet werden, wenn Sie Code auf dem Event-Dispatching-Thread ausführen wollen, was in der Regel der Fall ist, wenn Sie die GUI tatsächlich aktualisieren wollen.

Es gibt eine kurzes kleines Tutorial über die Verwendung von invokeLater .

Um Ihnen das Leben einfacher zu machen und das Risiko von Problemen zu minimieren, würde ich empfehlen, sicherzustellen, dass jeder Code, der mit der Swing-GUI interagiert, auf dem EDT läuft. Wie kleopatra richtig bemerkt, ist die gute Nachricht, dass dies so gut wie automatisch geschieht, da Ihr gesamter Code zur Ereignisbehandlung vom EDT aufgerufen wird.

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