1

J'ai un code simple avec une boucle for. Dans chaque passage de la boucle, je dois incrémenter le JProgressBar; Cependant, cela ne fonctionne pas. Voir ci-dessous:thread en Java Swing ne fonctionne pas

public void atualizarBarraDeProgresso(final int valorGeral, final int valorAtual) { 
    Thread threadProgressoCarregamento = new Thread() { 
     @Override 
     public void run() { 
      jProgressBarPersistindo.setValue(valorAtual); 
     } 
    }; 
    threadProgressoCarregamento.start(); 
} 

J'appelle la méthode "atualizarBarraDeProgresso" dans une boucle comme ci-dessous:

progressBar.setMinimum(0); 
progressBar.setMaximum(qtd); 
for(int i = 0; i < qtd; i++) { 
    atualizarBarraDeProgresso(qtd, i + 1); 
    doSomething(); 
} 

Mais rien ne se passe avec mon progressBar.

+6

-vous * vraiment * voulez que plusieurs threads? Dans tous les cas, je suppose que le problème est que la * boucle elle-même * se produit sur l'ADT (c'est-à-dire dans un "gestionnaire de clic") et * bloque * l'interaction de l'interface utilisateur Swing et les met à jour jusqu'à la fin. Pensez à utiliser un [SwingWorker] (http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html) - l'utiliser correctement éliminera probablement tous les problèmes. Assurez-vous également de mettre à jour * seulement * les objets Swing sur l'ADT. – user2246674

+0

Appelez repaint() sur le JPanel contenant après avoir défini la valeur à tout moment? C'est peut-être tout ce qui manque. – Barryrowe

+0

appelez la méthode repaint(), et en passant, la solution est très mauvaise. –

Répondre

0

Essayez d'ajouter un fil de discussion avant de le faire. J'espère que cela fonctionne

progressBar.setMinimum(0); 
    progressBar.setMaximum(qtd); 

    new Thread(){ 
     @Override 
     public void run() { 
      for(int i = 0; i < qtd; i++) { 
       atualizarBarraDeProgresso(qtd, i + 1); 
       doSomething(); 
      } 
     } 
    }.start(); 
0

Ceci devrait être facilement géré avec une implémentation SwingWorker. SwingWorker s sont utiles lorsque vous avez besoin de "faire quelque chose" mais que vous ne voulez pas bloquer l'interface graphique en le faisant. La classe vous fournit également une API utile pour communiquer vers l'EDT lorsque vous devez mettre à jour un composant de l'interface graphique tout en effectuant un autre travail via les méthodes publish()/process().

L'implémentation ci-dessous gère votre boucle sur un thread de travail afin de ne pas bloquer l'EDT (le thread graphique). Les appels au publish(Integer...) sont relayés vers l'EDT sous la forme d'un appel au process(List) où vous souhaitez mettre à jour votre JProgressBar, car comme tous les composants Swing, vous devez uniquement mettre à jour un JProgressBar sur l'EDT.

public class MySwingWorker extends SwingWorker<Void, Integer> { 

    private final int qtd; 
    private final JProgressBar progressBar; 

    public MySwingWorker(JProgressBar progressBar, int qtd){ 
     this.qtd = qtd; 
     this.progressBar = progressBar; 
    } 

    /* This method is called off the EDT so it doesn't block the GUI. */ 
    @Override 
    protected Void doInBackground() throws Exception { 
     for(int i = 0; i < qtd; i++) { 

      /* This sends the arguments to the process(List) method 
      * so they can be handled on the EDT. */ 
      publish(i + 1); 

      /* Do your stuff. */ 
      doSomething(); 
     } 
     return null; 
    } 

    /* This method is called on the EDT in response to a 
    * call to publish(Integer...) */ 
    @Override 
    protected void process(List<Integer> chunks) { 
     progressBar.setValue(chunks.get(chunks.size() - 1)); 
    } 
} 

Vous pouvez commencer comme ça

int qtd = ...; 

progressBar.setMinimum(0); 
progressBar.setMaximum(qtd); 

SwingWorker<? ,?> worker = new MySwingWorker(progressBar, qtd); 

worker.execute();