2016-04-05 4 views
1

Ich habe einen Thread, den ich starte, wenn ich den Startknopf drücke. Ich möchte die Labels neu streichen, damit sie die Informationen enthalten, an denen mein Thread Änderungen vornimmt. Das einzige Problem, mit dem ich konfrontiert bin, ist, dass die jLabels nur dann neu streichen, wenn der Thread fertig ist. Kann mir jemand irgendwas sagen, wie ich es neu streichen kann, während der Thread läuft? Vielen Dank.Repaint eine Schwungkomponente, während ein Thread läuft

Hier ist ein Ausschnitt aus meinem Code:

Store m = new Store(); //Store extends Thread 
private void startActionPerformed(java.awt.event.ActionEvent evt) {  
    .... 
    //I get the simulation time of the store from a textbox 
    //the thread runs for this number of seconds 
    //when it is done, the store is closed(the open variable is set to false) 
    .... 

    m.start(); 

    while (m.isOpen()) { 
     queue0.setText(String.valueOf(m.clientiCasai(0))); 
     //here I will have more queues 
     .... 
     noOfClients.repaint(); //this is the label that should show the number of clients in queue 0 
    } 
} 
+0

Führen Sie diese while-Schleife nicht auf dem EDT aus, sondern lassen Sie Ihren Thread die Repaint-Ereignisse auslösen, was bereits geschehen sollte, wenn der Thread 'noOfClients.setText (whatever) 'aufruft. – Thomas

+3

Blockieren Sie den Swing-Thread nicht. Neuanstrich wird erst aufgerufen, nachdem Ihre Aktionsmethode ausgeführt wurde. 'repaint()' führt keine Neubemalung durch, sondern informiert nur Swing, dass die Komponente später neu gestrichen werden muss. Für weitere Informationen lesen Sie bitte [Concurcency in Swing] (https://docs.oracle.com/javase/tutorial/uiswing/concurrency/) –

+0

Wrap in setText() in SwingUtilities.invokeAndWait() – StanislavL

Antwort

1

Ihre startActionPerformed() Methode sollte nicht auf EventDispatchThread (EDT) laufen, die das Thema ist, die für alle Swing-Änderungsoperationen verwendet werden soll. Wenn Sie den EDT blockieren, wird Ihre UI nicht neu streichen, sondern freeze.

Ihre noOfClients.repaint() Aufruf sollte auf EDT erfolgen, sondern auch den neuen Wert zu queue0 Label Ihren Anruf sollte auf EDT sein Einstellung.

Zur Vereinfachung. Wenn Sie Ihre queue0.setText() Aufruf auf EDT, wird die Neulackierung für Sie getan, so dass Sie es entfernen können. entweder man konnte die Methode startActionPerformed halten() zu Ihrem Shop eine Referenz

SwingUtilities.invokeLater(new Runnable() { 

     @Override 
     public void run() { 
      queue0.setText("<text>"); 
     } 
    }); 

zu lösen Ihr Problem an die Instanz übergeben und von dort aus rufen Sie bei Bedarf oder:

Dies kann durch den Aufruf erreicht werden Sie könnten einen anderen Thread starten, der den Store-Fortschritt überwacht und ihn an den Swing-EDT weiterleitet.

+1

'm.start() ; 'wird von' startActionPerformed' aufgerufen. Mit anderen Worten, er startet den Thread in 'startActionPerformed', so dass' startActionPerformed' im EDT läuft. – Oebele

1

Das Problem ist, dass das eigentliche Malen auch während der Ereignisschleife des EDT erfolgt; Ihre while() Schleife verhindert grundsätzlich das Fortschreiten der EDT. Eine mögliche Problemumgehung wäre, einen zusätzlichen Thread zu haben, der sich um das Aktualisieren des Etiketts kümmern würde.

Verwandte Themen