IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

EDT/SwingWorker Java Discussion :

[JLabel][SwingWorker] Rafraîchissement du contenu


Sujet :

EDT/SwingWorker Java

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Août 2008
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 15
    Par défaut [JLabel][SwingWorker] Rafraîchissement du contenu
    Bonjour,

    Je n’ai pas trouvé le forum spécial «SwingWorker» s’il existe, je vous demande donc de m’excuser si je ne suis pas au bon endroit.

    Voilà ce que j’essaye de faire :

    J’écris un programme faisant s’ouvrir une JFrame Coordonnees à un moment de son exécution. Après validation, par l’utilisateur, des nombres que celui-ci a entré dans cette JFrame, le programme utilise ces entrées pour générer un tableau de matrices nommé Cof, ce qui est rapide. Le programme doit alors calculer le déterminant de chacune de ces matrices, ce qui est évidemment relativement lourd si le tableau est grand, et s’en servir pour générer une matrice Com. Je passe donc le tableau Cof en argument d’une classe Solve qui étend SwingWorker. Le but est :

    • de dégeler le JButton Validation de la fenêtre Coordonnees, qui reste bloqué pendant le calcul de la matrice Com.
    • d’indiquer à l’utilisateur que le calcul est bien en cours par le rafraîchissement des JLabel Compteur et Count de la fenêtre Coordonnees. Ces deux JLabel n’affichent rien avant la validation et ensuite :
    o Compteur doit afficher «Résolution :»
    o Count doit afficher «0 %» au départ puis l’avancement, en %, après le calcul du déterminant de chaque élément de Cof.

    Je récupère ensuite la matrice Com dans la fenêtre Coordonnees par la méthode get() de SwingWorker.

    Le problème :

    Le JButton Validation reste toujours bloqué pendant le calcul, de même que les deux JLabel qui n’affichent rien pendant de ce temps puis «Résolution :» et «0 %» à la fin.

    Le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    package PE;
    import java.awt.Rectangle;
    import java.beans.*;
    import java.math.*;
    import javax.swing.SwingWorker;
     
    public class Solve extends SwingWorker<Matrice,Integer> {
     
        public Matrice[][] Cof;
        public static final MathContext DECIMAL128 = new MathContext(34,RoundingMode.HALF_EVEN);
     
        public Solve(Matrice[][] Cof) {
            this.Cof = Cof;
            addPropertyChangeListener(new PropertyChangeListener() {
                @Override
                public void propertyChange(PropertyChangeEvent evt) {
                    if("started".equals(evt.getPropertyName())) {
                        Coordonnees.Validation.setEnabled(false);
                        Coordonnees.Validation.updateUI();
                        Coordonnees.Validation.paintImmediately(new Rectangle(Coordonnees.Validation.getLocation(),Coordonnees.Validation.getSize()));
                        Coordonnees.Compteur.setText("Resolution :");
                        Coordonnees.Compteur.updateUI();
                        Coordonnees.Compteur.paintImmediately(new Rectangle(Coordonnees.Compteur.getLocation(),Coordonnees.Compteur.getSize()));
                        Coordonnees.Count.setText("0 %");
                        Coordonnees.Count.updateUI();
                        Coordonnees.Count.paintImmediately(new Rectangle(Coordonnees.Count.getLocation(),Coordonnees.Count.getSize()));
                    }
                    if("progress".equals(evt.getPropertyName())) {
                        Coordonnees.Count.setText(String.valueOf(getProgress())+" %");
                        Coordonnees.Count.updateUI();
                        Coordonnees.Count.paintImmediately(new Rectangle(Coordonnees.Count.getLocation(),Coordonnees.Count.getSize()));
                    }
                }
            });
        }
     
        @Override
        public Matrice doInBackground() {
            Matrice Com = new Matrice(Cof.length,Cof.length);
            for (int i=0;i<Cof.length;i++) {
                for (int j=0;j<Cof.length;j++) {
                    Com.setElement(new BigDecimal("-1.0").pow(i+j,DECIMAL128).multiply(new BigDecimal(Cof[i][j].Det().toString()),DECIMAL128),i,j);
                    setProgress((int) (i*Cof.length+j+1)*100/(Cof.length*Cof.length));
                    publish(getProgress());
                }
            }
            return Com;
        }
     
    }
    Voici le code de la classe Solve(Cof). Je n’ai pas posté celui de Coordonnees car il est d’une taille conséquente, mais je peux vous le fournir, tout ou en partie, si vous en avez besoin. J’ai également essayé de passer le code de addPropertyChangeListener dans la méthode process, mais l’effet est le même. Pareil pour la construction d’une classe Solve(Cof,i,j) ou la double boucle se trouve dans la classe Coordonnes, effectuant ainsi plusieurs appels à Solve, et en utilisant la méthode done() pour récupérer un déterminant à chaque itération. J'ai l'impression de tourner en rond, donc merci à ceux qui prendraient le temps de se pencher sur mon problème.

    chrisRg2r

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Août 2008
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 15
    Par défaut Solution
    Je sais pas trop pourquoi ça marche comme ça et pas autrement, mais ce que je veux faire fonctionne si je mets, dans la méthode doInBackground(), toute la partie du calcul qui utilise la matrice Com et que j'avais laissé dans la classe Coordonnees, y compris les appels aux classes suivantes. J'ai donc transféré quasiment tout le calcul qui était dans Coordonnees.ActionPerformed(Valider) dans la méthode doInBackground() de Solve, qui peut alors renvoyer null puisqu'il n'y a plus de calculs à effectuer ailleurs. Et ça marche !

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Août 2008
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 15
    Par défaut
    Voici un exemple d'utilisation de SwingWorker pour ceux que ça intérresse.
    On considère une classe Interface, dans un package PE, qui doit recevoir des entrées utilisateur et s'en servir pour effectuer un calcul lourd tout en mettant à jour la progression de ce calcul dans son JLabel Count. Interface dispose également de 3 JButton : Validation qui permet de lancer le calcul s'il est arrêté, Arret qui permet d'arrêter le calcul en cours de route, et Annulation qui permet de fermer la fenêtre si le calcul est arrêté. J'ai imposé ici que le JButton Arret soit désactivé si le calcul est arrêté et activé si le calcul est en cours, et inversement pour les deux autres JButton, mais c'est juste un choix personnel. Quoiqu'il en soit on crée, dans le même package, une classe Solve qui étend SwingWorker et qui va effectuer le calcul. De façon a rendre ça plus lisible et pas trop lourd, les codes des deux classes ont été par moment remplacé par des commentaires. Ce n'est donc pas directement applicable mais beaucoup plus facilement adaptable :

    La classe Interface :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    package PE;
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    /**
     * Effectuer les autres imports necessaires a la classe Interface.
     */
     
    public class Interface extends JFrame implements ActionListener {
     
        /**
         * Definir les champs.
         * Definir les composants graphiques a actualier au cours du calcul lourd et le SwingWorker sans utiliser "private" et en utilisant "static", par exemple :
         *
         */
        protected static JButton Validation;
        protected static JButton Annulation;
        protected static JButton Arret;
        protected static JLabel Count;
        protected static Solve SW;
     
        public Interface(/*Arguments de Interface*/) {
            /**
             * Definir l'interface graphique sans utiliser "this." pour les composants graphiques definis par "static".
             */
           Arret.setEnabled(false);
        }
     
        @Override
        public void actionPerformed(ActionEvent e) {
            if (e.getActionCommand().equals("Valider")) {
                /**
                 * Verifier les entrees de l'utilisateur
                 * Generer les objets primaires si ces entrees sont coorectes.
                 * Les objets primaires sont les objets necessaires au calcul lourd et definis DIRECTEMENT a partir des entrees de l'utilisateur.
                 * Les arguments de Solve sont les objets necessaires pour finir le calcul,
                 * donc les objets primaires et eventuellement certains champs.
                 */
                SW = new Solve(/*Arguments de Solve*/);
                SW.execute();
            }
            if (e.getActionCommand().equals("Arreter")) {
                SW.cancel(true);
            }
            if (e.getActionCommand().equals("Annuler")) {
                this.dispose();
            }
        }
     
    }
    La classe Solve :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    package PE;
    import java.beans.*;
    import javax.lang.model.type.NullType;
    import javax.swing.SwingWorker;
    /**
     * Effectuer les autres imports necessaires a la classe Solve,
     */
     
    public class Solve extends SwingWorker<NullType,Integer> {
     
        /**
         * Definir les arguments de Solve en tant que champs.
         */
     
        protected Solve(/*Arguments de Solve*/) {
            /**
             * Attribuer les arguments de Solve aux champs correspondants.
             */
            addPropertyChangeListener(new PropertyChangeListener() {
                @Override
                public void propertyChange(PropertyChangeEvent f) {
                    if("progress".equals(f.getPropertyName())) {
                        if (getProgress() == 100 || Interface.SW.isCancelled()) {
                            Interface.Validation.setEnabled(true);
                            Interface.Annulation.setEnabled(true);
                            Interface.Arret.setEnabled(false);
                        }
                        else {
                            Interface.Validation.setEnabled(false);
                            Interface.Annulation.setEnabled(false);
                            Interface.Arret.setEnabled(true);
                        }
                        Interface.Count.setText(String.valueOf(getProgress())+" %");
                    }
                }
            });
        }
     
        @Override
        protected NullType doInBackground() {
            /**
             * Generer les objets secondaires.
             * Les objets secondaires sont les objets necessaires au calcul lourd et definis a partir des arguments de Solve.
             * Effectuer le calcul lourd, en general une ou plusieurs boucles imbriquees, et evaluer l'avancement du calcul :
             */
            boucles {
                if (this.isCancelled() == false) {
                    /*Operation de la boucle*/
                    setProgress((int) (/*Nombre de boucles effectuees*/)*100/(/*Nombre total de boucles*/));
                    publish(getProgress());
                }
            }
            if (this.isCancelled()) {
                /**
                 * Ecrire le code des actions a effectuer si le calcul lourd a ete arrete.
                 */
            }
            else {
                /**
                 * Ecrire le code des actions a effectuer si le calcul lourd est termine.
                 */
            }
            return null;
        }
     
    }

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [JTextArea] Rafraîchissement du contenu
    Par bennyben77 dans le forum Composants
    Réponses: 6
    Dernier message: 21/08/2008, 00h39
  2. [JLabel] Problème de mise à jour du contenu
    Par Traroth2 dans le forum Composants
    Réponses: 9
    Dernier message: 25/06/2008, 12h59
  3. [jLabel+jTextField] detecter le changement de contenu
    Par waldoun dans le forum Général Java
    Réponses: 5
    Dernier message: 03/05/2008, 14h12
  4. est ce qu on peu dimensionner une Image contenu dans un Jlabel
    Par uzumaki_naruto dans le forum AWT/Swing
    Réponses: 7
    Dernier message: 24/02/2007, 17h33
  5. [Thread] Contenu d'un Jlabel en utilisant un thread
    Par jlassiramzy dans le forum AWT/Swing
    Réponses: 4
    Dernier message: 18/01/2007, 12h20

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo