Progress bar qui ne s'affiche qu'a la fin de traitement [Résolu]

Messages postés
17
Date d'inscription
mercredi 7 avril 2010
Dernière intervention
20 mars 2013
- - Dernière réponse : cormandyr
Messages postés
600
Date d'inscription
samedi 20 mai 2006
Dernière intervention
8 juillet 2016
- 18 avril 2012 à 08:15
Bonjour, je suis confronté à un problème qui je suis sur est très simple à gérer, mais je regarde des forums et autres sans trouver de réponses à mon problème...

Lorsque je veux afficher ma progressbar, le SwingWorker fait ce qu'il a à faire et incrémente la progression de ma barre de chargement mais rien ne s'affiche jusqu'à la fin de mon autre tâche qui gère des actions avec une base de données...

pourriez vous m'aider à comprendre pourquoi le thread se lance mais ne fait pas son boulot entièrement (il calcul une nouvel valeur de progression mais ne l'affiche pas...)?

Merci d'avance, voici mon code...

public class MyProgressMonitor extends JFrame implements PropertyChangeListener{

private static final long serialVersionUID = 1L;
private JProgressBar current;
private Dimension screenSize;
private int windowX;
private Dimension windowSize;
private int windowY;
private static JButton but;
private JPanel pane;
private Task task;
    
class Task extends SwingWorker<Void, Void> {
        /*
         * Main task. Executed in background thread.
         */
        @Override
        public Void doInBackground() {
            Random random = new Random();
            int progress = 0;
            //Initialize progress property.
            setProgress(0);
            while (progress < 100) {
                //Sleep for up to one second.
                try {
                    Thread.sleep(random.nextInt(2000));
                } catch (InterruptedException ignore) {}
                //Make random progress.
                progress += random.nextInt(10);
                setProgress(Math.min(progress, 100));
            }
            return null;
        }
        
        public void done() {
            Toolkit.getDefaultToolkit().beep();
            setCursor(null); //turn off the wait cursor
        }        
}
        
public MyProgressMonitor(JButton button, boolean b) {
        super("Progression");
        setBackground(Color.white);
        setLocationRelativeTo(null); 
screenSize = Toolkit.getDefaultToolkit().getScreenSize();
windowSize = getSize();
windowX = Math.max(0, (screenSize.width - windowSize.width) / 3);
windowY = Math.max(0, (screenSize.height - windowSize.height) / 2);

if(button != null){
        but = button;
        but.setEnabled(b);
}
        pane = new JPanel();
        pane.setLayout(new FlowLayout());
        
        current = new JProgressBar(0, 99);
        current.setValue(0);
        current.setString ("Progession: " + (int)(current.getPercentComplete()*100) + "%");
        current.setStringPainted(true);
        
        setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
        task = new Task();
        task.addPropertyChangeListener(this);
        task.execute();
        
        pane.add(current);

        setVisible(true);
        setSize(new Dimension(250,75));
setResizable(false);
setLocation(windowX, windowY);
        setContentPane(pane);
    }

public void remove(JButton butt) {
// TODO Auto-generated method stub
setVisible(false);
current = null;
pane = null;
butt.setEnabled(true);
}

@Override
public void propertyChange(PropertyChangeEvent arg0) {
// TODO Auto-generated method stub
if ("progress" == arg0.getPropertyName()) {
            int progress = (Integer) arg0.getNewValue();
            if(current != null){
            current.setValue(progress);
current.setString ("Progession: " + (int)(current.getPercentComplete()*100) + "%");
            }
        }
}
}


et je le crée dans une autre classe, pendant un traitement assez long :

MyProgressMonitor prog = new MyProgressMonitor(button,false);


Merci encore ;)
Afficher la suite 

Votre réponse

9 réponses

Meilleure réponse
Messages postés
600
Date d'inscription
samedi 20 mai 2006
Dernière intervention
8 juillet 2016
3
Merci
quand tu appelles la méthode de traitement (celle qui calcule quoi ^^) fais ceci:

code actuel:
public void calcul(){
    /* tout plein de code ^^ */
}


nouveau code :
public void calcul() {
    new Thread(new Runnable() {
        public void run(){
            /* tout plein de code ^^ */
        }
    }).start();
}

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 96 internautes nous ont dit merci ce mois-ci

Commenter la réponse de cormandyr
Messages postés
2116
Date d'inscription
samedi 8 novembre 2003
Statut
Contributeur
Dernière intervention
6 octobre 2012
0
Merci
salut,

SwingWorker : je ne connais pas cette class (pas le temps de regarder ce matin sorry) .... Ceci dit si elle n instancie pas effectivement un thread, c est normale ...

Essai de tracer ca construction... sinon fait ta propre class et remplace la pour tester ;o) ...

GL

GodConan ;o)
Commenter la réponse de cs_GodConan
Messages postés
600
Date d'inscription
samedi 20 mai 2006
Dernière intervention
8 juillet 2016
0
Merci
Salut, oui en effet, le fait que la progress bar ne s'affiche qu'à la fin du traitement laisse à penser qu'il s'agit d'un problème de thread... Autrement dit, le traitement et l'affichage sont fait dans la même Thread et ton GUI n'est rafraichi qu'à la fin du traitement...
Commenter la réponse de cormandyr
Messages postés
17
Date d'inscription
mercredi 7 avril 2010
Dernière intervention
20 mars 2013
0
Merci
oui je penses bien que c'est un problème de thread mais il me semblait que le fait d'utiliser swingWorker résolvait ce genre de problèmes avec les thread.

Il le gère en quelque sorte car il effectue ce qui lui est demandé mais je ne comprends pas pourquoi il ne l'affiche pas, je ne vois pas comment résoudre ce problème...

J'ai essayé d'effectuer des Thread.yield(); dans le programme appelant afin de voir si cela ne laisserait pas le temps d'afficher correctement la progressbar mais cela ne change rien à mon problème...

A vrai dire, je ne sais pas quoi essayer, j'ai également refait une classe sans le swingWorker mais c'est pire, rien ne s'effectue en tâche de fond...

Merci encore si quelqu'un à déja eu ce genre de problème et sait comment ou le régler, ou si quelqu'un connait juste la réponse à mon problème^^
Commenter la réponse de jimdano
Messages postés
5307
Date d'inscription
dimanche 4 mai 2003
Dernière intervention
14 décembre 2018
0
Merci
Salut,

Je ne sais pas quoi dire ... J'ai ouvert eclipse (+ création d'un projet bidon + une classe MyProgressMonitor) ensuite j'ai fait un petit copier/coller de ton code vers eclipse, j'ai également ajouté le bloc suivant (simple main):
public class MyProgressMonitor // ...
  // ...
  public static void main(String[] args) {
    new MyProgressMonitor(null,false);
  }
// ...
}

et à l'exécution .... j'ai bien une fenêtre qui s'ouvre et anime la progressbar de façon régulière...
Donc visiblement rien à signaler de ce coté... tu nous as également parlé d'une interaction avec une base de données ?

Sinon elle te sert à quoi cette très mais vraiment très vilaine copie dans le constructeur du bouton vers une variable static ?


-----

"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

OoWORAoO
Commenter la réponse de Twinuts
Messages postés
17
Date d'inscription
mercredi 7 avril 2010
Dernière intervention
20 mars 2013
0
Merci
En fait, la copie dans le constructeur du bouton me sert à empêcher l'utilisateur d'appuyer sur le bouton pendant l'interaction avec la base de données et pendant l’exécution de mes méthodes^^

Je ne redonne le droit d'action au bouton qu'à la fin du chargement^^

Sans l'interaction avec ma base de données, la progress bar marche parfaitement, en effet.

En fait la progress bar s'anime, mais que à la fin du traitement avec la base de donnée, je ne peux pas te donner le code, il y a 6000 lignes pour mon projet, mais en gros, pendant l'interaction avec la base de données, je dis à l'utilisateur de patienter jusqu'à la fin de la progress bar (qui sera à optimiser quand elle marchera), le traitement se fait bien en parallèle, mais pas l'affichage de la progress bar, c'est ça que je ne comprends pas... :/

Merci cormandyr, ca marche maintenant =) =)
Commenter la réponse de jimdano
Messages postés
17
Date d'inscription
mercredi 7 avril 2010
Dernière intervention
20 mars 2013
0
Merci
Et merci à tout ceux qui se sont attardé sur mon cas =)
Commenter la réponse de jimdano
Messages postés
17
Date d'inscription
mercredi 7 avril 2010
Dernière intervention
20 mars 2013
0
Merci
public class MyProgressMonitor extends JFrame implements ChangeListener{

private static final long serialVersionUID = 1L;
private JProgressBar current;
private Dimension screenSize;
private int windowX;
private Dimension windowSize;
private int windowY;
private static JButton but;
private JPanel pane;
        
public MyProgressMonitor(JButton button, boolean b) {
        super("Progression");
        setBackground(Color.white);
        setLocationRelativeTo(null); 
screenSize = Toolkit.getDefaultToolkit().getScreenSize();
windowSize = getSize();
windowX = Math.max(0, (screenSize.width - windowSize.width) / 3);
windowY = Math.max(0, (screenSize.height - windowSize.height) / 2);

if(button != null){
        but = button;
        but.setEnabled(b);
}
        pane = new JPanel();
        pane.setLayout(new FlowLayout());
        
        current = new JProgressBar(0, 99);
        current.setValue(0);
        current.setString ("Progession: " + (int)(current.getPercentComplete()*100) + "%");
        current.setStringPainted(true);
        current.addChangeListener(this);
        
        setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
        
        pane.add(current);

        setVisible(true);
        setSize(new Dimension(250,75));
setResizable(false);
setLocation(windowX, windowY);
        setContentPane(pane);
    }

public void remove(JButton butt) {
setVisible(false);
current = null;
pane = null;
butt.setEnabled(true);
}

public void setProgress(int num){
current.setValue(num);
current.setString ("Progession: " + (int)(current.getPercentComplete()*100) + "%");
}

@Override
public void stateChanged(ChangeEvent arg0) {
current.setString ("Progession: " + (int)(current.getPercentComplete()*100) + "%");
}
}


et dans le programme appelant :

final MyProgressMonitor prog = new MyProgressMonitor(button,false);
new Thread(new Runnable() {
        public void run(){
            /* tout plein de code :) (interaction avec bdd...) */
        }
    }).start();


pour ceux qui voudraient s'en inspirer...
Commenter la réponse de jimdano
Messages postés
600
Date d'inscription
samedi 20 mai 2006
Dernière intervention
8 juillet 2016
0
Merci
au lieu de faire une copie de la référence de ton button, pourquoi ne pas directement travailler avec? Je veux dire, tu sais quand tu cliques sur le boutton (paf setEnabled(false)) et tu sais quand ton traitement est terminé (repaf setEnabled(true)) non?
Commenter la réponse de cormandyr

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.