Swing, wie Sie die Benutzeroberfläche ordnungsgemäß aktualisieren

8

Was ist der richtige Weg, um die Benutzeroberfläche nach einigen Operationen auf Swing zu aktualisieren?

Zum Beispiel wird nach dem Anklicken einer Schaltfläche eine Methode aufgerufen, die fast augenblicklich sein kann oder einige Sekunden dauern kann. Tatsächlich wird die gesamte Anwendungslogik remote über einen Webdienst ausgeführt. Daher ist es normal, ein wenig zu warten, bis die Anwendung reagiert.

Mein Eventhandler für eine Schaltfläche könnte so aussehen:

%Vor%

Meine aktuelle Implementierung ruft die updateUI-Methode auf, die intern validate () und repaint () an die übergeordnete Komponente aufruft, die die UI enthält. Das funktioniert, aber manchmal kann ich den Bildschirm flackern sehen. Mache ich es falsch? Gibt es einen besseren Weg, es zu tun?

    
Hectoret 07.02.2011, 11:54
quelle

4 Antworten

5

Der richtige Weg wäre SwingWorker, aber wenn Sie es manuell machen wollen, müssen Sie das folgende Muster implementieren:

%Vor%

Rufen Sie normalerweise für die Repaint / Revalidate Frage revalidate() dann repaint() auf. Dies gilt natürlich nur für die Komponente, die Sie manuell zeichnen. Rufen Sie für Komponenten, die Sie wiederverwenden, einfach ihre Wertänderungsmethoden auf.

    
Olivier Grégoire 07.02.2011 12:28
quelle
4

Ich würde persönlich SwingWorker dafür verwenden, trotz einiger anderer Kommentare / Antworten:

  • Trotz der Tatsache, dass die Benutzerfreundlichkeit der Benutzeroberfläche nicht Teil der ursprünglichen Frage ist, ist es eine gute Übung, dies trotzdem zu tun (ich kann mir keinen einzigen guten Grund vorstellen, den EDT mit langwieriger Verarbeitung zu sperren.)
  • Es bietet eine done() -Methode, die implementiert werden kann, die standardmäßig auf dem EDT ausgeführt wird, wenn die Aufgabe abgeschlossen ist, was die Notwendigkeit zum manuellen Aufwickeln von Dingen in invokeLater() verhindert.
  • Es ist erweiterbarer und bietet den Rahmen, um Informationen wie Fortschritt später leicht hinzuzufügen, wenn es gewünscht wird.

Ich habe in letzter Zeit viel SwingWorker-Hass gesehen, und ich verstehe nicht warum. Es ist eine schön gestaltete, erweiterbare Klasse speziell für solche Zwecke, die gut funktionieren. Ja, Sie könnten Dinge in Threads einpacken und sie starten und andere Methoden in invokeLater() einschließen, aber warum das Rad neu erfinden, wenn es ein besseres gibt, das kostenlos zur Verfügung steht?

    
berry120 07.02.2011 13:56
quelle
1

Nehmen Sie die lange laufende Aufgabe zu einem anderen Thread. Senden Sie Ereignisse an den AWT Event Dispatch Thread (EDT) zurück, um die GUI mit java.awt.EventQueue.invokeLater zu aktualisieren.

    
Tom Hawtin - tackline 07.02.2011 12:25
quelle
0

Normalerweise müssen Sie nichts tun: Wenn Sie die Swing-Komponenten-Methoden oder die Methoden ihres Modells verwenden, werden die erforderlichen Ereignisse ausgelöst, und die GUI sollte sich automatisch aktualisieren.

Dies wird nicht der Fall sein, wenn Sie Ihre eigenen Modelle definieren (und vergessen, die notwendigen Ereignisse auszulösen, aber dann ist es ein Fehler in Ihren Modellen und sollte dort behoben werden.

    
JB Nizet 07.02.2011 12:21
quelle

Tags und Links