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 :

contexte graphique (méthode paint)


Sujet :

AWT/Swing Java

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

    Informations forums :
    Inscription : Septembre 2006
    Messages : 68
    Points : 58
    Points
    58
    Par défaut contexte graphique (méthode paint)
    Bonjour,

    Je suis en train de créer une interface graphique pour un jeu de Blackjack en Java (car mine de rien c'est plus agréable quand on voit les cartes).

    Je suis plutot nul en java alors pour progresser je me ballade sur internet pour comprendre le code des autres (pas très glorieux mais efficace je trouve).

    J'ai remarqué que pour le graphisme il est courant de redéfinir la méthode paint au sein de la classe assurant la gestion de l'affichage.

    Cependant je ne comprends pas pourquoi le faire alors que cette méthode n'est jamais appelée par la suite. Par exemple ce bout de code :

    (En supposant créés tous les objets que l'on appelle)

    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
    class Ex1 extends FenetreGraphique {
      Ex1 () {}
      Ex1 (int w, int h, Color c) {super(w,h,c);}
     
      public void dessiner(Graphics2D g2) {
        g2.setPaint(Color.red);
        g2.drawString("coucou", 0, getHauteur());
      }
    }
     
     
    class Ex1Main {
      public static void main(String[] args) {
        FenetreGraphique fenêtre = new Ex1();
        fenêtre.ouvrir();
        fenêtre.informer("Un premier exemple");
      }
    }


    Dans cet exemple comme dans beaucoup d'autres je ne comprends pas comment cela peut fonctionner car, si j'ai bien compris, l'affichage du message coucou est assuré par la méthode dessiner. Cependant le constructeur de EX1 n'y fait pas appel ! Elle est juste définie dans la classe Ex1 mais jamais appelée.

    L'explication est surement tout bête mais ca me rend malade de ne pas comprendre.

    J'espere ne pas faire perdre de temps avec de telles questions.
    Merci d'avance.

    Akhan

  2. #2
    Membre confirmé

    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    159
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Novembre 2005
    Messages : 159
    Points : 467
    Points
    467
    Par défaut
    Il y a certaines méthodes que toi tu appelle directement, d'autres sont appellées par la JVM quand il le faut.
    La méthode paint est une méthode présente dans tout element AWT, paintComponent pour Swing que tu peux personaliser en fonction de ce que tu veux faire. Quand l'élement doit se redessiner, la méthode sera appellée. Tu peux aussi forcer un réaffichage avec la méthode repaint().

    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
    import java.awt.Color;
    import java.awt.Frame;
    import java.awt.Graphics;
     
    class Ex1 extends Frame {
     
        Ex1(){
            setSize(100, 100);
        }
     
        public void paint(Graphics g2) {
            g2.setColor(Color.red);
            g2.drawString("coucou", 0, getHeight());
        }
     
        public static void main(String[] args) {
            Ex1 fenetre = new Ex1();
            fenetre.setVisible(true);
        }
    }

  3. #3
    Expert éminent sénior
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    Pour commencer, il vaudrait mieux que tu redéfinisse la méthode paintComponent que la méthode paint, l'explication va arriver avec la suite.

    Donc la méthode paint (et toute les autres méthodes paintXXX d'un JComponent) on pour but de dessiner le composant graphique, enfin plustôt de préciser à java comment doit être dessiné le composant.

    Ces méthodes sont appelées de façon "cachée", cad automatiquement, par java lors de l'affichage, par exemple sur une fenêtre passant en avant plan un composant qui est ajouté automatiquement et ainsi de suite.
    Swing est une solution 100% java donc qui n'utilise aucun composant du système hote, donc tous le composants doivent être dessinés. Et c'est donc le but des méthodes paintXXX et paint.

    La méthode paint en l'occurence centralise l'appel aux différentes méthodes nécessaires pour dessiner le composant comme paintComponent, paintBorder et ainsi de suite.

    Donc dans ton ca il vaudra mieux seulement redéfinir paintComponent qui te permet de dessiner sur le composant, et de laisser la main à paint pour rassembler le tou
    Hey, this is mine. That's mine. All this is mine. I'm claiming all this as mine. Except that bit. I don't want that bit. But all the rest of this is mine. Hey, this has been a really good day. I've eaten five times, I've slept six times, and I've made a lot of things mine. Tomorrow, I'm gonna see if I can't have sex with something.

  4. #4
    Membre confirmé

    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    159
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Novembre 2005
    Messages : 159
    Points : 467
    Points
    467
    Par défaut
    Tout à fait d'accord avec toi sinok.
    Dans mes quelques lignes de code j'ai utilisé paint parce que j'utilisais AWT, mais tu as raison il est évident que Akhan utilise Swing.

  5. #5
    Membre chevronné
    Avatar de afrikha
    Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    1 600
    Détails du profil
    Informations personnelles :
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2005
    Messages : 1 600
    Points : 2 208
    Points
    2 208
    Par défaut
    Salut,
    juste pour dire que lors de la redéfinition de la méthode paintComponent, dans la plupart des cas il faut commencer par appeler celle de la classe mère.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    protected  void  paintComponent(Graphics g){
                  super.paintComponent(g);
                  /*redefinir ici.....*/


    Mes publications
    Lisez
    Les régles du forum
    Pensez au bouton

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

    Informations forums :
    Inscription : Septembre 2006
    Messages : 68
    Points : 58
    Points
    58
    Par défaut
    (Merci d'avoir pris du temps pour me répondre)

    En fait, si j'ai bien compris, les fonctions paintXXX sont automatiquement appelées par le machine java dès lors que l'on affiche une fenetre, etc?
    C'est la fonction paint qui est appelée et elle appelle elle-meme paintComponent etc...

    Mais lorsqu'on redéfinit paint (par exemple) et qu'on ne lui mets que deux trois lignes de code comme dans mon/vos exemples ; cette nouvelle méthode paint sera toujours appelée à la place de l'ancienne. Ainsi on ne perd pas des fonctionnalités importantes de cette méthode?
    Sinok vous m'avez dit que paint pilotait paintComponent par exemple ; donc si je redéfinis paint ; la gestion de paintComponent ne sera plus assurée automatiquement?

    afrhika, je me demande pourquoi il est nécessaire d'apeler le paintComponent de la classe mere avant de la redéfinir ?

    Enfin pourquoi faut il toujours mette en argument un objet de type Graphics ?

    Enfin (bis) ; meme si j'ai redéfini paint dans EX1 la portée de ce changement s'arete juste à cette cflasse je présume ?

    Merci d'avance.

  7. #7
    Membre chevronné
    Avatar de afrikha
    Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    1 600
    Détails du profil
    Informations personnelles :
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2005
    Messages : 1 600
    Points : 2 208
    Points
    2 208
    Par défaut
    Citation Envoyé par Akhan
    afrhika, je me demande pourquoi il est nécessaire d'apeler le paintComponent de la classe mere avant de la redéfinir ?
    La construction d'un objet graphique est loin d'étre une mince affaire. L'appel de paintComponent de la classe mere avant de la redéfinir, permet d'avoir un composant avec les bonnes bases. Sans cela on devrait redessiner entièrement le composant en partant de zéro, ce qui n'est pas fort envisageable. Pour t'en convaincre, jette un coup d'oeil au fichier source d'un simple JButton.


    Mes publications
    Lisez
    Les régles du forum
    Pensez au bouton

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

    Informations forums :
    Inscription : Septembre 2006
    Messages : 68
    Points : 58
    Points
    58
    Par défaut
    oui, mes lanternes commencent doucement à s'éclairer , Merci !!

    Par contre là je suis en train d'essayer, mais à la compilation il me dit qu'il ne trouve pas la méthode paintComponent.
    J'ai pourtant importé java.awt.* et javax.swing.*. Ca doit etre tout bete et une fois de plus je suis bloqué...

    Merci d'avance.
    Akhan

  9. #9
    Membre chevronné
    Avatar de afrikha
    Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    1 600
    Détails du profil
    Informations personnelles :
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2005
    Messages : 1 600
    Points : 2 208
    Points
    2 208
    Par défaut
    Montre-nous ton code pour qu'on puisse t'aider....


    Mes publications
    Lisez
    Les régles du forum
    Pensez au bouton

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

    Informations forums :
    Inscription : Septembre 2006
    Messages : 68
    Points : 58
    Points
    58
    Par défaut
    voici le début de 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
     
       import java.awt.*;
       import javax.swing.*;;
     
        public class fenetreTest extends JFrame{
          Image monImage ;
     
           fenetreTest(){
             setSize(200,200);
          }
           public void paintComponent(Graphics g){
          super.paintComponent(g);
          //puis ici je gere la récupération puis l'affichage de l'image
          }
     
       }
    Et là déja ca bloque à la compilation.
    jgrasp me renvoie :

    fenetreTest.java:12: cannot resolve symbol
    symbol : method paintComponent (java.awt.Graphics)
    location: class javax.swing.JFrame
    super.paintComponent(g);

    ^
    1 error

    (j'arrive pas à tabuler le "^" ; il devrait se trouver sur le "." de super.paintComponent)

  11. #11
    Membre chevronné
    Avatar de afrikha
    Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    1 600
    Détails du profil
    Informations personnelles :
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2005
    Messages : 1 600
    Points : 2 208
    Points
    2 208
    Par défaut
    Bien faire attention aux modificateurs de visibilité.

    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
    import java.awt.*;
       import javax.swing.*;;
    
        public class fenetreTest extends JFrame{
          Image monImage ;
       
           fenetreTest(){
             setSize(200,200);
          }
           protected void paintComponent(Graphics g){
          super.paintComponent(g);
          //puis ici je gere la récupération puis l'affichage de l'image
          }
       
       }


    Mes publications
    Lisez
    Les régles du forum
    Pensez au bouton

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

    Informations forums :
    Inscription : Septembre 2006
    Messages : 68
    Points : 58
    Points
    58
    Par défaut
    hum non le message d'erreur est toujours le meme.

  13. #13
    Membre chevronné
    Avatar de afrikha
    Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    1 600
    Détails du profil
    Informations personnelles :
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2005
    Messages : 1 600
    Points : 2 208
    Points
    2 208
    Par défaut
    En fait c'est normal, j'ai pas suffisament attention :
    En fait, JFrame n'herite pas de JComponent donc elle ne possède pas de méthode paintComponent. Voilà c'est aussi simple que ça. Par contre ce que tu peux faire c'est utiliser des JPanel (qui eux héritent de JComponent ) et les mettre dans ta JFrame. C'est généralement comme ça qu'on procède.

    P.S: Ma remarque au dessus est valable


    Mes publications
    Lisez
    Les régles du forum
    Pensez au bouton

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

    Informations forums :
    Inscription : Septembre 2006
    Messages : 68
    Points : 58
    Points
    58
    Par défaut
    Merci pour vos lumieres, afrikha !

    Bon, j'ai un peu continué mon entreprise ; j'ai créé une classe PanelTest dans laquelle j'ai redéfini paintComponent ; puis une classe fenetreTest comme suit :

    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
    public class PanelTest extends JPanel{
     
          Image monImage ;
     
           public PanelTest(){
             setSize(300,300);
             setVisible(true);
          }
     
           protected void paintComponent(Graphics g){
             super.paintComponent(g);
             Toolkit monTk = Toolkit.getDefaultToolkit();
             monImage =monTk.getImage("roi_pique.jpg");
             if(!(monImage==null))
                g.drawImage(monImage,0,0,this);
             else 
                System.out.println("monImage = null");
          }
     
     
       }
     
     import java.awt.*;
       import javax.swing.*;
     
        public class FenetreTest extends JFrame{
     
          PanelTest feuille ;
     
           FenetreTest(){
             setSize(500,500);
             feuille = new PanelTest();
             Container c = getContentPane();
             c.add(feuille);
             setVisible(true);
          }
     
     
     
           public static void main (String[] arguments){
             FenetreTest maFenetre = new FenetreTest();
     
          }
     
       }
    Et mon beau roi de pique s'affiche (quelle joie !!).
    Par contre ; il y a dix minutes cela ne marchait pas ,car initialement j'avais seulement une classe fenetreTest ; et comme ce n'est pas un JComponent (comme vous me l'avez précisé) , j'avais créé une méthode paintComponent quand même de cette facon :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    protected void paintComponent(Graphics g){
             super.paint(g);
             //etc...
          }
    Bien sur, quand j'ai choisi de créer finalement une classe PanelTest ; jai oublié de remplacer le super.paint(g) par super.paintComponent(g). Il n'ya pas eu d'erreur à la compilation, mais à l'execution j'ai eu une erreur Stackoverflow. A quoi est-elle due?

    Merci encore d'avoir résolu mon probleme !
    Akhan

  15. #15
    Expert éminent sénior
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    Tout simplement car tu enchainais les appel à paint:

    Un appel à paint entrainait un appel à apint Component qui lui même demandait un paint du père qui faisait appel au paintComponent du père et ainsi de suite.....
    Hey, this is mine. That's mine. All this is mine. I'm claiming all this as mine. Except that bit. I don't want that bit. But all the rest of this is mine. Hey, this has been a really good day. I've eaten five times, I've slept six times, and I've made a lot of things mine. Tomorrow, I'm gonna see if I can't have sex with something.

  16. #16
    Membre expérimenté Avatar de herve91
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    1 282
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 282
    Points : 1 608
    Points
    1 608
    Par défaut
    Citation Envoyé par afrikha
    Bien faire attention aux modificateurs de visibilité.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    protected void paintComponent(Graphics g){
          super.paintComponent(g);
          //puis ici je gere la récupération puis l'affichage de l'image
          }
       
       }
    Juste pour info, on a le droit de modifier la visibilité d'une méthode redéfinie dans une classe fille, à condition de ne pas la restreindre, donc protected -> visible est valide, mais pas protected -> private par exemple.

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

    Informations forums :
    Inscription : Septembre 2006
    Messages : 68
    Points : 58
    Points
    58
    Par défaut
    Merci pour toutes ces infos ;j'ai l'impression d'en avoir appris pas mal aujourd'hui !!

  18. #18
    Gfx
    Gfx est déconnecté
    Expert éminent
    Avatar de Gfx
    Inscrit en
    Mai 2005
    Messages
    1 770
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 770
    Points : 8 178
    Points
    8 178
    Par défaut
    À ce sujet... je ne sais par quel maléfice, 99% des méthodes paintComponent() surchargées deviennent publiques (notamment dans les tutoriaux, articles, etc.). Il n'y a aucune raison pour changer cette visibilité, pensez donc bien à garder cette méthode protected.
    Romain Guy
    Android - Mon livre - Mon blog

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

Discussions similaires

  1. [Panel]dessiner sans la méthode paint()
    Par paolo2002 dans le forum AWT/Swing
    Réponses: 1
    Dernier message: 20/10/2006, 02h35
  2. problème de méthode paint()
    Par guillaumeM63 dans le forum 2D
    Réponses: 2
    Dernier message: 16/05/2006, 23h50
  3. [JButton]Redéfinir la méthode paint(), colorer le fond.
    Par leminipouce dans le forum AWT/Swing
    Réponses: 4
    Dernier message: 23/01/2006, 15h51
  4. [Débutant] Obtenir un contexte graphique précis..
    Par milootooloo dans le forum 2D
    Réponses: 4
    Dernier message: 31/10/2005, 23h22
  5. [AWT] Peut-on choisir de lancer la méthode paint()
    Par noobiewan kenobi dans le forum Débuter
    Réponses: 16
    Dernier message: 28/07/2005, 16h41

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