2017-02-19 3 views
-2

J'ai écrit du code en utilisant des librairies swing, qui, lorsqu'ajouté un actionlistener, ne mettra pas à jour un progressBar.java swing progressBar

Sans un bouton et un écouteur d'action, cela fonctionne très bien. Comment forcer une mise à jour ProgressBar aussi simplement et proprement que possible? Le code ajouté est un exemple facile à comprendre qui résume mon problème. Si vous commentez une méthode ActionPerformed et exécutez le programme à partir de main, cela fonctionne très bien.

Ne pas coller du code sans l'expliquer.

ps .: Je l'ai vu: swing progressBar threading

public class Okno { 

    private JProgressBar progressBar = new JProgressBar(0,306); 
    JFrame f = new JFrame("JProgressBar Sample"); 
    JButton b = new JButton("start"); 
    ActionListener a = new ActionListener() { 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      barupdate(); 
     } 
    }; 


    private void barupdate(){ 
     for(int p = 1; p<308;p=p+2){ 
      System.out.println(p); 

      progressBar.setValue(p); 

       try { 
         Thread.sleep(50); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
     } 
} 

private Okno(){ 

    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    progressBar.setStringPainted(true); 

    f.add(progressBar, BorderLayout.SOUTH); 
    f.add(b, BorderLayout.NORTH); 
    b.addActionListener(a); 
    f.setSize(300, 300); 
    f.setVisible(true); 

} 

public static void main(String[] args) { 
    Okno okno = new Okno(); 
} 
} 
+0

Ceci est un problème très commun qui a généralement résolu de la même manière, la meilleure solution dans ce cas est normalement en utilisant un 'SwingWorker', [par exemple] (http://stackoverflow.com/questions/12020949/jprogressbar-isnt -progressing/12021971 # 12021971). Vous pouvez également jeter un coup d'œil à [Concurrency in Swing] (http://docs.oracle.com/javase/tutorial/uiswing/concurrency/) pour plus de détails sur le problème. Dans la plupart des cas, utiliser un autre 'Thread' n'est pas le meilleur choix, Swing n'est pas thread-safe et vous devez prendre des précautions supplémentaires pour mettre à jour l'interface utilisateur, que' SwingWorker' vous fournit gratuitement;) – MadProgrammer

+0

@ MadProgrammer, 'la meilleure solution dans ce cas est normalement l'utilisation d'un SwingWorker ... vous devriez jeter un oeil à la concurrence dans Swing,' - j'aurais aimé y penser. – camickr

+0

@camickr La question devrait être fermée, mais je sais que vous avez des problèmes avec les gens qui font cela, alors j'ai laissé mon commentaire (vous soutenant répondu) et est parti – MadProgrammer

Répondre

1

Le problème est que vous avez une boucle où vous réglez le réglage de la barre de progression qui est appelé à partir d'un écouteur d'action. Le problème est que la barre ne sera pas mise à jour tant que l'auditeur n'aura pas terminé. Et donc vous n'obtiendrez pas de mises à jour. Non seulement cela, mais vous allez ralentir le gui parce que la fenêtre ne peut pas réagir aux mouseclicks etc pendant que vous êtes dans cette écoute d'action. Donc, la meilleure façon de gérer cela est de créer un timer, dans le listener d'action, et de mettre le code pour mettre à jour le bouton, et de démarrer le timer dans le listener d'action.

La minuterie ne doit mettre à jour la barre qu'une seule fois. et vous devriez permettre le fait que le minuteur sera appelé plusieurs fois, pour jouer le rôle de la répétitivité. Donc vous ne voulez pas avoir de boucles dans votre code.

+0

merci de me pointer dans une direction ... je vais rapporter comment ça s'est passé et le code postal –

0
Thread.sleep(50); 

N'utilisez pas Thread.sleep (...). Cela empêchera l'interface graphique de se repeindre jusqu'à ce que la boucle ait fini d'être exécutée. A la place, vous pouvez utiliser un SwingWorker.

Lire la section du tutoriel Swing sur Concurrency in Swing qui contient plus d'informations et contient un exemple de travail avec un SwingWorker.

Consultez également la table des matières du didacticiel. Il y a une section sur How to Use ProgressBars qui contient également un exemple de travail. Le tutoriel est le premier endroit à chercher des exemples.

+0

est un exemple qui résume mon problème, et la méthode sleep() est là juste pour progresser sur une barre de programme plus lente. Si vous supprimez le code d'actionlisting et démarrez le code de la barre de progression à partir de la page principale, cela fonctionne correctement. –

+0

Je sais. Lorsque vous démarrez la barre de progression depuis le main(), le code s'exécute dans un thread différent. Lorsque vous démarrez la barre de progression dans ActionListener, le code s'exécute sur le 'Fil d'envoi d'événement (EDT)', qui est le thread qui peint l'interface graphique. Vous devez donc commencer votre barre de progression dans un fil séparé, c'est pourquoi vous devez lire le tutoriel pour mieux comprendre le fonctionnement de Swing. 'Le tutoriel a des exemples de travail'. – camickr