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

AWT/Swing Java Discussion :

paint, repaint, thread?


Sujet :

AWT/Swing Java

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    82
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 82
    Points : 46
    Points
    46
    Par défaut paint, repaint, thread?
    Bonjour, voila un problème que je retrouve souvent et auquel je ne trouve pas de solution. J'ai l'impression que la méthode paint, ou repaint est threadée. Le terme n'est surement pas correct mais je ne sais pas comment appeler ce phénomène.
    Voici un exemple:

    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
     
    public void unemethode(){
      repaint();
      end= true;
    }
     
    public void paint(Graphics g){
      g.draw.......
      ......
      g.draw.......
      if (!end){//dessin de ma figure
        g.draw...
        g.draw...
      }
    }
    Le problème est que end est déjà a true lors du test if(!end)
    Résultat, ma figure n'est pas tracée. Alors que dans le principe, end ne devrait être à true qu'aprés que repaint() se termine....
    Bref, je ne sais pas du tout comment résoudre ce problème.
    J'ai déjà essayé les synchronized de repaint et paint, mais ca ne change rien et d'ailleurs à cause de ca je n'arrive pas à comprendre ce qui se passe.

    Si quelqu'un peut m'espliquer ce qui se passe dans le détail et comment résoudre le problème de façon propre...
    Merci d'avance.

  2. #2
    Rédacteur
    Avatar de eclesia
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    2 108
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 108
    Points : 3 203
    Points
    3 203
    Par défaut
    le "dessin" des interfaces est effectivement dans un thread séparé.
    qu'on nomme l'EDT.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    82
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 82
    Points : 46
    Points
    46
    Par défaut re
    D'accord, merci.
    Il est facile de régler le problème en utilisant des petites stratégies simples,(par exemple mettre un booléen à vrai en sortant du paint et attendre dans la fonction qui apelle repaint que ce booléen soit vrai pour passer à l'instruction suivante) mais je trouve que ce n'est vraiment pas propre, et d'ailleurs surement pas adapté.
    Connaissez vous des façons "intéressantes" de régler le problème?

    Merci

  4. #4
    Rédacteur
    Avatar de eclesia
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    2 108
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 108
    Points : 3 203
    Points
    3 203
    Par défaut
    mais je trouve que ce n'est vraiment pas propre, et d'ailleurs surement pas adapté.
    Connaissez vous des façons "intéressantes" de régler le problème?
    je ne sais pas ce que tu cherche a faire, donc ca va etre dur.

    Si l'affichage est dans un autre thread, c'est pour ne pas bloquer l'application (fenetre grise quand on deplace, bouton qui ne reagisse pas) pendant les traitements longs.

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    82
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 82
    Points : 46
    Points
    46
    Par défaut re
    Alors imaginons un bout de code comme ca:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    public void afunc(){
      while(c>0){
        repaint();
        c--;
      }
      this.end= true;
    }
     
    public void paint(Graphics g){
      if (!end){
        ...
      }
    }
    je veux que pain soit apelé c fois, or il risque fortement d'être apelé c-1 fois.

    Je pourrais bien sur remplacer ce code par quellque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    public void afunc(){
      while(!this.end)
        repaint();
    }
     
    public void paint(Graphics g){
      ....
      c--;
      if (c==0) this.end= true; 
    }
    Mais je trouve ca un peu tordu.
    Ce qui m'ennuies un peu, c'est de gérer dans paint des choses qui n'ont plus rien à voir avec l'affichage directement, mais qui sont plutot des tests pour controler l'affichage. En effet, ce n'est pas bien grave, mais si je ppouvais trouver un moyen plus propre d'éxécuter mon premier code en étant sur que l'affichage se fasse c fois, ca serait bien pratique (imaginez l'affichage d'une horloge ou quelque chose comme ca). J'aurais pensé que faire une section critique avec paint serait utile, mais non.
    Donc si vous voyez comment faire...

    Merci

  6. #6
    Membre émérite
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Points : 2 582
    Points
    2 582
    Par défaut
    J'ai l'impression que tu loupes quelque chose dans la compréhension du paint, mais il est difficile de saisir quoi, car, comme eclesia, je ne vois pas très bien pourquoi tu fais tout ça.

    Pourquoi veux-tu appeler repaint "c" fois ?? Habituellement on appelle repaint quand il y a quelque chose à dessiner, et non pas un nombre déterminé de fois

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    82
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 82
    Points : 46
    Points
    46
    Par défaut re
    Oui, peut être que je loupe quelque chose. Mais j'ai bien l'impression que si je veux afficher un objet consécutivement dans 60 états différents, j'aurais besoin d'apeler 60 fois repaint(), n'est ce pas. Encore une fois, imaginons l'affichage d'une horloge...
    Le problème ne se poserait pas si j'utilisais des composants comme des boutons ou autre, mais si je veux que mon graphique varie au cours du temps, il est bien logique que j'apelle repaint pour montrer ces variations, non?

    Désolé si je me trompe.

  8. #8
    Rédacteur
    Avatar de eclesia
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    2 108
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 108
    Points : 3 203
    Points
    3 203
    Par défaut
    tu peux essayer de modifier les variables de ton dessin et faire un revalidate() entre chaque.


    sinon honnetement je trouve ca un peu bizarre de vouloir 60fois redessiner dans une boucle, et ca sans tempo entre chaque nouveau dessin. ca risque d'aller vite.

    tu devrais faire un thread qui :
    - dessine une premiere fois
    et N fois :
    - pause d'un temps t
    - modifie les variables de dessin
    - redessine

  9. #9
    Membre émérite
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Points : 2 582
    Points
    2 582
    Par défaut
    Oui, il y a quelque chose de prévu pour ça, c'est javax.swing.Timer. Et aucun besoin de tester si repaint est fini ou pas, swing s'en occupe.

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    82
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 82
    Points : 46
    Points
    46
    Par défaut
    Ben je vous comprend pas trop.
    J'ai déjà utilisé un thread pour arriver au résultat voulu, nommé MTimer, et ca marche, bien sur, mais dédier un thread juste pour ca je trouve cela un peu étrange. Je ferais un test avec Timer pour voir si cela fait une différence.
    D'autre part, évidemment, je n'affiche pas mes 60 fois "tempo", j'utilise un Thread.sleap, mais dans la mesure ou tout se fait dans le même thread, cela ne change absoluement rien.au problèle des 60 affichages.
    Bon, imaginbez le cas suivant.
    Vous utilisez une horloge en barre par exemple, qui affiche en rouge la proportion de temps utilisée.
    Lorsque tout le temps est passé, vous voulez bien sur que la barre soit entièrement rouge sans faire le calcul de proportion. En ben vous vous retrouvez dans mon cas.

    Merci pour vod réponses.

  11. #11
    Membre émérite
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Points : 2 582
    Points
    2 582
    Par défaut
    Si c'est ton cas, c'est nous qui avons raison, et toi qui a tord

    Pour comprendre tu peux regarder des choses comme How to Use Swing Timers, How to Use Progress Bars dans le tutorial java (déjà bien orienté java 6 il me semble, moi j'en suis encore à java 5)...

    Voici le principe général de programmation de ta pendule.

    1. Tu prépares et affiches ta GUI avec ta pendule, et tu prépares le mécanisme interne de ta pendule.
    2. Tu lances un timer (pas un Thread.sleep ! ) qui incrémente ta pendule et relance l'affichage par un repaint.
    3. Tu regardes ta pendule avancer.

    Concernant les threads, comme je pense que tu n'as pas grand chose à faire pour incrémenter le temps de 1 seconde, tu pourras tout faire dans le processus du timer, je veux dire que le timer avance le temps de 1 et envoie le repaint, tandis que le paint dessine les aiguilles à la bonne place.

    Moralité : éh oui, tu dédies un thread juste pour ça

  12. #12
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    82
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 82
    Points : 46
    Points
    46
    Par défaut re
    Ok, merci, je vais essayer comme ca.
    Mais je redoute fortement d'avoir le même problème que lorsque j'avais implémenté un timer simple à ma manière.
    Si c'est le cas, j'expliciterai ce problème.
    Je dois dire que c'est vraiment pas simple à expliquer, c'est vraiment des petits détails.

    Merci

  13. #13
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 872
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 872
    Points : 22 939
    Points
    22 939
    Billets dans le blog
    53
    Par défaut
    Citation Envoyé par gifffftane
    Pourquoi veux-tu appeler repaint "c" fois ?? Habituellement on appelle repaint quand il y a quelque chose à dessiner, et non pas un nombre déterminé de fois
    Note : ce n'est pas tout le temps vrai. Pour obtenir une bonne optimisation lors d'une animation 2D, par exemple, il est plus pratique d'appeler repaint() avec sa variante prenant une zone de clip. Et ceci peut etre fait plusieurs fois dans le meme traitement (si cela a lieu dans l'EDT puisque aucun affichace n'a lieu durant le traitement), chacun des appels sera fusionne (union de formes) a la zone a repeindre par le repaint manager. Voir Scott Hommel: Custom Painting - Is This Fast Enough?

  14. #14
    Membre émérite
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Points : 2 582
    Points
    2 582
    Par défaut
    @rageice : aucun problème, fais-nous un source indépendant qui compile que tu n'arrives pas à faire marcher et on te le fera marcher.

    @bouye : oui tu as tout à fait raison.

Discussions similaires

  1. [JPanel] paint, paintComponent et repaint ?
    Par Pill_S dans le forum Composants
    Réponses: 8
    Dernier message: 08/02/2013, 18h38
  2. pb : paint et repaint d'une image à partir d'un thread
    Par zazou0506 dans le forum Graphisme
    Réponses: 1
    Dernier message: 03/01/2008, 01h57
  3. pb paint et repaint d'une image dans un thread
    Par zazou0506 dans le forum AWT/Swing
    Réponses: 2
    Dernier message: 02/01/2008, 23h21
  4. Probleme paint() repaint()
    Par Uren dans le forum AWT/Swing
    Réponses: 4
    Dernier message: 27/07/2007, 19h02
  5. Réponses: 4
    Dernier message: 08/10/2006, 16h16

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