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

Interfaces Graphiques en Java Discussion :

[thread]bug graphique?


Sujet :

Interfaces Graphiques en Java

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 162
    Points : 72
    Points
    72
    Par défaut [thread]bug graphique?
    Voilà j'ai une appli qui lit en entrée un fichier XML. Ce fichier contient des actions a effectuer par mon interface graphique dans un certain ordre. Pour voir ces actions visuellement j'utilise un système de couleur qui change à chaque action réalisée.

    Mon code est le suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    for(int i=0; i<actions.size();i++){
                String act = actions.get(i);
                try {
                    Method m = ts.getClass().getMethod(act, (Class[])null);
                    m.invoke(ts, (Object[])null);
                    simulFrame.refresh();();//rafraichit mon interface et change donc sa couleur
     
     
                }
    ...
    Quand je fais ça ça marche très bien sauf que ça s'éxécute tellment vite que je n'ai pas le temps de voir les différentes étapes (changement de couleur) et j'obtiens tout de suite une interface avec la couleur indiquant que c'est terminé.
    J'ai donc essayé de mettre un sleep comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    for(int i=0; i<actions.size();i++){
                String act = actions.get(i);
                try {
                    Method m = ts.getClass().getMethod(act, (Class[])null);
                    m.invoke(ts, (Object[])null);
                    Thread.sleep(1000);
                    simulFrame.refresh();//rafraichit mon interface et change donc sa couleur
     
                }
    ...
    L'objectif étant de voir chaque changement de couleur pendant 1 seconde.
    Malheureusement quand je fais ça j'ai mon JFileChooser qui se "bloque" (cadre grisé au dessus de mon interface) et je ne vois aucun changement de couleur jusqu'a la fin de l'éxécution ou j'obtiens le même résultat que sans le sleep....

    Une chtite idée?
    Merci ;-)

  2. #2
    Membre éprouvé
    Profil pro
    Développeur Back-End
    Inscrit en
    Avril 2003
    Messages
    782
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Back-End

    Informations forums :
    Inscription : Avril 2003
    Messages : 782
    Points : 935
    Points
    935
    Par défaut
    bonjour,

    ce n'est pas un bug

    voici un lien vers un article concernant les swings et les threads
    http://java.sun.com/products/jfc/tsc.../threads1.html

    bonne lecture.

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 162
    Points : 72
    Points
    72
    Par défaut
    Non c'est vrai je me suis mal exprimée c'est un bug de moi qui ne connait pas suffisamment bien les threads
    Je lis ça et je reviens si ça va pas...
    Oups y'a pas la mêm chose en Français? Parce que là je vais lutter ;-) Mais bon je va essayer qd même !

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 162
    Points : 72
    Points
    72
    Par défaut
    Bon j'ai lu tout ça mais je ne suis pas sûre d'avoir vraiment tout compris...
    Dans mon cas quelle méthode vaut-il mieux que j'appelle ? invokeLater() ou invokeAndWait() Je pensais plutôt la deuxième mais j'ai des InvocationTargetException qui se lancent... Avec la 1ere pas d'exception mais j'obtiens le même résultat qu'auparavant...

    Peut -être cela vient t-il de l'endroit ou j'appelle ces méthodes?
    Voici ce que j'ai fait :
    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
     public void refresh(){
            try{
            Runnable doWorkRunnable = new Runnable() {
                    public void run() { 
                        for(int i=0; i<taches.size();i++){
                            SimulationToggleButton b =taches.get(i);
                            b.changeStatut(b.tache.etat);
                        }
                    }
            };
            javax.swing.SwingUtilities.invokeAndWait(doWorkRunnable);
            }
            catch(Exception e){
                System.out.println(e);
            }
        }

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 162
    Points : 72
    Points
    72
    Par défaut
    J'ai vu qu'une solution avec SwingWorker était souvent abordée. Est ce que je ne devrais pas plutôt utilisé ça?
    Mon problème c'est que tous les exemples que je vois sont dans des cas ou l'application est lente... Alors que moi c'est l'inverse ça s'éxécute tellement vite qu'on a pas le temps de voir ce qu'il se passe sur l'interface.

    C'est pour ça ça me plaisait bien un sleep :-(

  6. #6
    Membre habitué
    Inscrit en
    Avril 2004
    Messages
    170
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 170
    Points : 174
    Points
    174
    Par défaut
    Pour faire court, a ta place je creerai une petite class qui herite de Thread (ou runnable) qui rafraichit ta frame tous les 10emes de secondes par exemple comme cela :

    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
     
    class maRefreshThread extends Thread {
       private JFrame frameARafraichir_;
     
       public maRefreshThread(JFrame frameARafraichir) {
         frameARafraichir_ = frameARafraichir;
       }
     
       public void run() {
          while(true) {
             frameARafraichir.refresh();
             sleep(10);
          }
       }
    }
    Et avant d'entrer dans ta boucle for tu lances le travail de rafraichissement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    new maRefreshThread(this).start();
    Voila. Dis moi si ca t'aide.

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 162
    Points : 72
    Points
    72
    Par défaut
    alors j'ai essayé de mettre le start avant la boucle mais j'obtiens d'abord un cadre gris bloqué puis des exceptions :

    java.lang.OutOfMemoryError: unable to create new native thread
    at java.lang.Thread.start0(Native Method)
    at java.lang.Thread.start(Thread.java:574)
    at ModuleSimulation.SimulationFrame.refresh(SimulationFrame.java:139)
    Apres j'ai essayé de metre le start avant le rfresh comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     for(int i=0; i<actions.size();i++){
                String act = actions.get(i);
                try {
                    Method m = ts.getClass().getMethod(act, (Class[])null);
                    m.invoke(ts, (Object[])null);
                    TimerFrame tf= new TimerFrame(this);
                    tf.start();
                    simulFrame.refresh();
                }
                catch(Exception e){
                    System.out.println(e);
                }
            }
    Et là pas de problèmes particuliers mais c'est comme si j'avais rien fait. Je ne vois pas les étapes et arrive directement à la fin...

    Ca me paraissait bien ça pourtant! Merci en tout cas!

  8. #8
    Membre habitué
    Inscrit en
    Avril 2004
    Messages
    170
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 170
    Points : 174
    Points
    174
    Par défaut
    Si tu deplaces ces 2lignes de code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    TimerFrame tf= new TimerFrame(this);
    tf.start();
    avant la boucle for tu as une exception java.lang.OutOfMemoryError ?!?

    Petite question neanmoins : que fais ta methode simulFrame.refresh() ?

    Edit: Je viens de voir que j'avais fait une boulette dans le bout de code que je t'ai filer tout a l'heure. Je voulais mettre repaint a la place de refresh avant le sleep.

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 162
    Points : 72
    Points
    72
    Par défaut
    Peut-être ne parle t'on pas de la meme boucle for... En fait j'en ai 2 :
    La première parcours les actions du fichier XML et a chaque tour je suis censée rafraichir mon interface pour voir l'effet de l'action.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     for(int i=0; i<actions.size();i++){
                String act = actions.get(i);
                try {
                    Method m = ts.getClass().getMethod(act, (Class[])null);
                    simulFrame.refresh();
                }
                catch(Exception e){
                    System.out.println(e);
                }
            }
    Et j'ai une boucle dans ma méthode refresh...

    Le mieux est que je mette le code de refresh :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for(int i=0; i<taches.size();i++){
                SimulationToggleButton b =taches.get(i);
                b.changeStatut(b.tache.etat);
            }
    dans cette méthode taches est une liste de JToggleButton et je change la couleur de chacun de ses boutons avec la méthode changeStatut()

    L'exception est levée qd je met le start() avant la boucle for de la méthode refresh().[/code]

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 162
    Points : 72
    Points
    72
    Par défaut
    Ha avec le repaint j'ai droit à un nouveu comportement... Plus rien ne change de couleur ... Et je pense même que l'application ne tourne plus du tout (car je ne vois plus mes print) mais elle n'est pas bloquée puisque j'arrive à la fermer sans la tuer...

    Vive les threads que je comprends rien

  11. #11
    Membre habitué
    Inscrit en
    Avril 2004
    Messages
    170
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 170
    Points : 174
    Points
    174
    Par défaut
    Ok je comprends mieux alors.
    La boucle for dont je parle est celle avant le parcours des actions.
    Ensuite, dans la thread de rafraichiessement, il fuat que tu debrouilles pour appeler la methode pour rafraichir tes couleurs et pour rafraichir ta frame (pour que le changement de couleur se voit sur la frame).

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 162
    Points : 72
    Points
    72
    Par défaut
    Pour l'instant ça ne marche pas mais je pense qu'on s'approche... Quand je fais des print ça a l'air très bien mais je ne vois rien à l'écran. A mon avis c'est un problème indépendant des threads donc je devrais pouvoir trouver en fouillant un peu!

    Merci bien en tout cas pour ta patience!

    RRRRRRRRRRR J'ai beau faire des repaint sur la Jframe sur les boutons... Que dalle tout il est gris!

  13. #13
    Membre habitué
    Inscrit en
    Avril 2004
    Messages
    170
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 170
    Points : 174
    Points
    174
    Par défaut
    Quand tu auras trouver, dis moi ce qui ne marchait pas.

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 162
    Points : 72
    Points
    72
    Par défaut
    Bon j'ai parlé un peu vite une fois de plus!
    En fait j'avais fait une betise qui faisait que ça restait gris... Depuis que la betise est corrigée je confirme que je ne vois pas les étapes...

    En fait je me suis rendue compte que la série des sleep() et réveil (que je vois en faisant des print) ne se met en "marche" qu'après la fin de ma boucle qui parcours les actions. Ce qui explique que la Frame apparaisse en état fini tout de suite puisque toutes les actions sont terminées avant que mon thread ne se décide à rafraichir...

    Je m'excuse mille fois de ma nullité!

  15. #15
    Membre habitué
    Inscrit en
    Avril 2004
    Messages
    170
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 170
    Points : 174
    Points
    174
    Par défaut
    Peut etre que le sleep est trop long alors.
    Je te propose une autre solution dans ce cas : a chaque fois qu'une action se fini, tu passes un booleen a vrai. Dans la thread qui rafraichit, tu supprimes le sleep et tu entoures le rafraichissement d'un if avec comme condition le booleen a vrai :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    if(nvlActionFini) {
       nvlActionFini = false;
       rafraichissement...
     
    }
    Le seul danger qui reste a ce moment, c'est que pendant que tu rafraichis, une autre action se fini avant que le booleen soit de nv a faux. A voir. Dis moi si comme cela ca change qqch.

  16. #16
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 162
    Points : 72
    Points
    72
    Par défaut
    Bon alors déjà bonne nouvelle cette fois ça marche vraiment!!

    Finalement je suis restée sur l'idée de la première solution...
    La solution finale est un peu compliquée à expliquer mais en gros j'ai finalement mis dans le run() toute la procédure depuis le début(ouverture du fichier, lecture, action puis rafraichissement etc...)
    Et maintenant le .start() n'est plus devant la boucle for mais il est appelé au niveau de l'interface graphique sur un mouseClicked() de ouvrirFichierXml...

    Pour que ça marche j'ai eu besoin de changer aussi quelques algos mais là c'est OK!!!!

    En tout cas encore une fois merci beaucoup pour tes précieux indices!!!

  17. #17
    Membre habitué
    Inscrit en
    Avril 2004
    Messages
    170
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 170
    Points : 174
    Points
    174
    Par défaut
    Y'a pas de quoi.

    Peux tu me montrer le code du run? Je suis quand meme curieux de voir pouquoi ca ne marchait pas avant...

  18. #18
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 162
    Points : 72
    Points
    72
    Par défaut
    Voilà le code...
    Pas sûr que ça t'aide à comprendre mais bon...
    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
      public void run() { 
            //choisir un fichier
            java.io.File f = frameARafraichir.openChooseFile();
            XMLSimulReader reader =new XMLSimulReader(f);
            int depart=0;
            int size = reader.getNbEtapes();
            while(depart<size){
                HashMap<String,ArrayList<String>> map = reader.readSimul(depart);
                Iterator uneTache = map.keySet().iterator();
                String oidTache = (String)uneTache.next();
                ArrayList<String> aFaire =map.get(oidTache);
                AdaptateurP.AdaptateurSimulation.rejoueTache(oidTache,aFaire);//c'est ici qu'il ya la boucle d'éxécution des actions (la ou j'avais mis le sleep)
                frameARafraichir.refresh();
                try{
                    sleep(1000);  
                }
                 catch(Exception e){
                     System.out.println(e);
                 }
                depart++;
            }
       }

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

Discussions similaires

  1. Bug Graphique après installation interface graphique
    Par hulahup dans le forum Windows Forms
    Réponses: 1
    Dernier message: 11/07/2007, 02h04
  2. Bug graphique fenetre modale HTML
    Par TheReturnOfMuton dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 03/04/2007, 14h27
  3. Gros bug graphique
    Par Myth_Titans dans le forum Matériel
    Réponses: 13
    Dernier message: 15/07/2006, 22h18
  4. [TP] Bug Graphique avec certaines configurations
    Par Ripley dans le forum Turbo Pascal
    Réponses: 1
    Dernier message: 29/01/2006, 18h23

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