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

jimdano 17 Messages postés mercredi 7 avril 2010Date d'inscription 20 mars 2013 Dernière intervention - 16 avril 2012 à 23:38 - Dernière réponse : cormandyr 600 Messages postés samedi 20 mai 2006Date d'inscription 8 juillet 2016 Dernière intervention
- 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
cormandyr 600 Messages postés samedi 20 mai 2006Date d'inscription 8 juillet 2016 Dernière intervention - 17 avril 2012 à 11:56
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();
}

Merci cormandyr 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 96 internautes ce mois-ci

Commenter la réponse de cormandyr
cs_GodConan 2116 Messages postés samedi 8 novembre 2003Date d'inscriptionContributeurStatut 6 octobre 2012 Dernière intervention - 17 avril 2012 à 06:52
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
cormandyr 600 Messages postés samedi 20 mai 2006Date d'inscription 8 juillet 2016 Dernière intervention - 17 avril 2012 à 08:36
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
jimdano 17 Messages postés mercredi 7 avril 2010Date d'inscription 20 mars 2013 Dernière intervention - 17 avril 2012 à 11:38
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
Twinuts 5283 Messages postés dimanche 4 mai 2003Date d'inscription 22 octobre 2018 Dernière intervention - 17 avril 2012 à 21:36
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
jimdano 17 Messages postés mercredi 7 avril 2010Date d'inscription 20 mars 2013 Dernière intervention - 18 avril 2012 à 00:37
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
jimdano 17 Messages postés mercredi 7 avril 2010Date d'inscription 20 mars 2013 Dernière intervention - 18 avril 2012 à 00:38
0
Merci
Et merci à tout ceux qui se sont attardé sur mon cas =)
Commenter la réponse de jimdano
jimdano 17 Messages postés mercredi 7 avril 2010Date d'inscription 20 mars 2013 Dernière intervention - 18 avril 2012 à 01:24
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
cormandyr 600 Messages postés samedi 20 mai 2006Date d'inscription 8 juillet 2016 Dernière intervention - 18 avril 2012 à 08:15
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.