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

2D Java Discussion :

Dessin de forme géométrique, problèmes d'incompréhension avec repaint() etc


Sujet :

2D Java

  1. #1
    Futur Membre du Club
    Inscrit en
    Décembre 2008
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 10
    Points : 6
    Points
    6
    Par défaut Dessin de forme géométrique, problèmes d'incompréhension avec repaint() etc
    Salut à tous,

    Je fois développer un paintbrush like en Java pour un projet. A la base je connaissais un peu le java mais pas du tout les interfaces graphiques avec SWING/AWT etc. J'apprends donc sur le tas. Je travaille avec NetBeans 6.5 et je bloque sur le dessin de forme avec le drag'n drop de la souris.

    En fait mon programme est bateau à souhait puisqu'il doit permettre de dessiner des tracés à main levée, des rectangles, cercles, etc...

    En ce qui concerne le dessin à main levée je pense avoir réussi quoique il y encore des défauts dans ma manière de programmer que je n'arrive pas à éviter. Je vais expliquer au fur à mesure pourquoi je dis ca.

    Bon alors 1er, comme premier pas mon programme est capable de faire un dessin à main levée et des rectangles basiques (bordure noire, fond blanc).

    Pour cela j'utilise les événements liés à la souris (souris pressée, relâchée, draguée...). Mon problème est que, lorsque je veux dessiner un rectangle, celui ci s'affiche au fur et à mesure sur la zone de dessin (vous savez, tant que le bouton de la souris n'est pas relâché, on pré visualise le rectangle qui va être dessiné). Or avec le code fourni, il s'affiche bien lors des mouvements de souris en drag mais disparaît aussitôt que la souris devient immobile même si on garde le bouton enfoncé. C'est très frustrant. Je vous laisse jeter un coup d'œil à mon code pour ceux qui ont la patiente de m'aider.

    Je sais aussi que je m'y prends mal pour dessiner car je n'effectue pas tous les dessin dans paintComponent alors que c'est dit partout. Le fait inexpliqué pour moi est que le dessin est très lent si je procède de cette manière alors j'ai essayé de contourné la difficulté. J'ai aussi trouvé des exemples de paintBrush en Java mais ils ne m'aident plus à ce stade.

    Merci d'avance pour votre aide.

    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
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
     
    import java.awt.*;
    import java.util.Vector;
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
     
    /*
     * Dessin.java
     *
     * Created on 5 janv. 2009, 11:04:53
     */
     
    /**
     *
     * @author x
     */
    public class Dessin extends javax.swing.JPanel {
     
        Vector figuresList;
        int figure;
        Point start;
     
     
        /** Creates new form Dessin */
        public Dessin() {
            initComponents();
            figuresList = new Vector();
            start = new Point();
     
        }
     
        public void paintComponent(Graphics g){
            super.paintComponent(g);
            draw(g);
     
        }
     
        /** This method is called from within the constructor to
         * initialize the form.
         * WARNING: Do NOT modify this code. The content of this method is
         * always regenerated by the Form Editor.
         */
        @SuppressWarnings("unchecked")
        // <editor-fold defaultstate="collapsed" desc="Generated Code">
        private void initComponents() {
     
            setBackground(new java.awt.Color(255, 255, 255));
            addMouseListener(new java.awt.event.MouseAdapter() {
                public void mousePressed(java.awt.event.MouseEvent evt) {
                    formMousePressed(evt);
                }
                public void mouseReleased(java.awt.event.MouseEvent evt) {
                    formMouseReleased(evt);
                }
            });
            addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
                public void mouseDragged(java.awt.event.MouseEvent evt) {
                    formMouseDragged(evt);
                }
            });
     
            javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
            this.setLayout(layout);
            layout.setHorizontalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGap(0, 400, Short.MAX_VALUE)
            );
            layout.setVerticalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGap(0, 300, Short.MAX_VALUE)
            );
        }// </editor-fold>
     
     
     
        private void formMouseDragged(java.awt.event.MouseEvent evt) {                                  
            // TODO add your handling code here:
     
            //dessin à main levée
            if (figure == 1){
                Trace t = (Trace)figuresList.lastElement();
                t.add(evt.getX(), evt.getY());
                t.draw(this.getGraphics());
            }
     
            //Rectangle à dessiner
            else if (figure == 2){
                repaint();
                draw(this.getGraphics());
                Rect r = new Rect(Color.BLACK,start.x, start.y,
                                 evt.getX(), evt.getY());
                r.draw(this.getGraphics());
                this.getGraphics().dispose();
            }
     
        }                                 
     
        private void formMousePressed(java.awt.event.MouseEvent evt) {                                  
            // TODO add your handling code here:
            if (figure == 1){
               figuresList.add(new Trace(Color.BLACK));
           }
     
           else if(figure == 2){
               start.x = evt.getX();
               start.y = evt.getY();
           }
     
        }                                 
     
        private void formMouseReleased(java.awt.event.MouseEvent evt) {
            // TODO add your handling code here:
            if(figure == 2){
                figuresList.add(new Rect(Color.BLACK,
                                start.x, start.y, evt.getX(), evt.getY() ));
                repaint();
            }
        }
     
        public void draw(Graphics g){
            Figure f;
    		for(int i = 0 ; i < figuresList.size() ; i++) {
                f = (Figure)figuresList.elementAt(i);
    			f.draw(g);
            }
        }
     
        // Variables declaration - do not modify
        // End of variables declaration
     
    }
     
    abstract class Figure {
    	abstract void draw(Graphics g);
    }
    /**
     *
     * @author x
     */
    class Trace extends Figure {
     
     
        Color c;
    	Vector pointsArray;
     
    	Trace(Color c) {
    		this.c = c;
    		pointsArray = new Vector();
    	}
     
    	void add(int x, int y) {
    		pointsArray.addElement(new Point(x , y));
    	}
     
     
    	Point elementAt(int n) {
    		if (pointsArray.capacity() < n) return null;
    		return (Point) pointsArray.elementAt(n);
    	}
     
    	int nbPoints() {
    		return pointsArray.size();
    	}
     
    	void draw(Graphics g) {
    		int n = nbPoints();
    		if(n <= 1) return;
     
    		g.setColor(c);
    		int x_last = elementAt(0).x;
    		int y_last = elementAt(0).y;
     
    		int x,y;
     
    		for(int i = 1 ; i < n ; i++) {
    			x = elementAt(i).x;
    			y = elementAt(i).y;
    			g.drawLine(x_last, y_last, x, y);
    			x_last = x;
    			y_last = y;
    		}
    	}
     
     
    }
     
     
    class Rect extends Figure{
     
        Color c;
    	Point p1, p2;
     
    	Rect(Color c, int x1, int y1, int x2, int y2) {
    		this.c = c;
    		p1 = new Point(x1, y1);
    		p2 = new Point(x2, y2);
    	}
     
     
        void draw(Graphics g) {
            int x, y, width, height;
            g.setColor(c);
            x = Math.min(p1.x, p2.x);
    		y = Math.min(p1.y, p2.y);
    		width = Math.abs(p1.x - p2.x);
    		height = Math.abs(p1.y - p2.y);
            g.drawRect(x, y, width, height);
        }
    }

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

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    Bonjour,

    Tout opération de dessin effectuée dans un composant Swing doit se réaliser à l'intérieur de la méthode paintComponent. La méthode getGraphics qure tu utilises à l'heure actuelle ne doit pas être utilisée à ces fins.

    Donc grosso modo, il faut que tu prépares ta collection de figure dans tes listeners, puis que tu appelles la méthode repaint. La méthode répaint appellera par la suite la méthode paintComponent (c'est le comportement standard de Swing, pas besoin de surcharger la méthode repaint). Dans la méthode paintComponent et compmences par dessiner toutes les formes contenues dans ta collection, puis tu dessines suivant le cas, la forme que l'utilisateur est en train de composer. A noter qu'il faut bien redessiner toutes les formes à chaque appel de paintComponent.

  3. #3
    Futur Membre du Club
    Inscrit en
    Décembre 2008
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 10
    Points : 6
    Points
    6
    Par défaut
    Bonjour,

    Tout opération de dessin effectuée dans un composant Swing doit se réaliser à l'intérieur de la méthode paintComponent. La méthode getGraphics qure tu utilises à l'heure actuelle ne doit pas être utilisée à ces fins.

    Donc grosso modo, il faut que tu prépares ta collection de figure dans tes listeners, puis que tu appelles la méthode repaint. La méthode répaint appellera par la suite la méthode paintComponent (c'est le comportement standard de Swing, pas besoin de surcharger la méthode repaint). Dans la méthode paintComponent et compmences par dessiner toutes les formes contenues dans ta collection, puis tu dessines suivant le cas, la forme que l'utilisateur est en train de composer. A noter qu'il faut bien redessiner toutes les formes à chaque appel de paintComponent.

    Merci d'avoir répondu. Malheureusement j'ai déjà procédé de cette manière : toutes mes figures à dessiner étaient enregistrées dans un object Vector. Le dessin s'effectuait alors exclusivement dans paintComponent. Cela fonctionnait mais demeurait très lent à l'affichage et prenait bcp de ressources : le processeur à 100% pour un logiciel de dessin basique c'est pas recommandable...donc voilà même si tout le monde recommande de dessiner uniquement dans paintComponent, je n'ai pas trouvé d'autres solutions que d'utiliser directement le Graphics du panel ailleurs. J'ai finalement abouti à mes fins en utilisant la propriété setXORmode avec la couleur de fond de mon panel.

  4. #4
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Août 2005
    Messages : 6 851
    Points : 22 863
    Points
    22 863
    Billets dans le blog
    51
    Par défaut
    Ta maniere de dessiner n'est pas correcte et ce n'est pas parce que cela fonctionne sur ta machine que cela fonctionnera forcement ailleurs.

    Si ton rendu etait trop lent initialement c'est probablement car tu devais dessiner bien trop de choses sans tenir compte de la zone de clip positionnee sur le Graphics passe en parametre de paintComponent() et/ou de l'ordonancement de tes formes. De meme il faut appeler la version de repaint() qui prend en parametre les coordonnees de la zone a repeindre plutot que le repaint() global.

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

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    L'autre solution étant de dessiner sur une image et de n'avoir que lk'image à dessiner sur ton composant dans le paintComponent.

    Toutefois, ton histoire de 100% proc est très louche afficher des formes basiques comme celles que tu dessines ne doit pas mettre le proc sur les genous normalement

  6. #6
    Futur Membre du Club
    Inscrit en
    Décembre 2008
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 10
    Points : 6
    Points
    6
    Par défaut
    Ta maniere de dessiner n'est pas correcte et ce n'est pas parce que cela fonctionne sur ta machine que cela fonctionnera forcement ailleurs.

    Si ton rendu etait trop lent initialement c'est probablement car tu devais dessiner bien trop de choses sans tenir compte de la zone de clip positionnee sur le Graphics passe en parametre de paintComponent() et/ou de l'ordonancement de tes formes. De meme il faut appeler la version de repaint() qui prend en parametre les coordonnees de la zone a repeindre plutot que le repaint() global.
    Eh bien je sais tout ca, et c'est justement ce qui me frustre car qq chose m'échappe. Pour ce qui est de la zone de clip, je ne vois pas en quoi c'a m'est utile car à chaque fois que je vais appeler repaint(). Tout mon dessin va être effacé et donc du coup il faut veiller à tout redessiner. Sachant que c'est une application paint, l'utilisateur peut potentiellement dessiner partout dans la zone de dessin et donc restreindre la zone de clip n'a pas de sens?

    L'autre solution étant de dessiner sur une image et de n'avoir que lk'image à dessiner sur ton composant dans le paintComponent.

    Toutefois, ton histoire de 100% proc est très louche afficher des formes basiques comme celles que tu dessines ne doit pas mettre le proc sur les genous normalement
    Ben c'est bien ce qui me chagrine mais je ne trouve pas comment eviter ce problème, je sais que j'utilise mal l'api de dessin mais je dois rendre le projet bientot et croyez moi j'ai déjà cherché en vain de n'utiliser que la surcharge de paintComponent pour mon dessin mais c trop lent...et je ne sais pas pk.

  7. #7
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par filipaillou Voir le message
    Eh bien je sais tout ca, et c'est justement ce qui me frustre car qq chose m'échappe. Pour ce qui est de la zone de clip, je ne vois pas en quoi c'a m'est utile car à chaque fois que je vais appeler repaint(). Tout mon dessin va être effacé et donc du coup il faut veiller à tout redessiner.
    En appellant repaint(int x, int y, int width, int height) tu peux spécifier la zone qui a été modifié. Et tu n'a plus qu'a dessiner seulement cette zone dans ta méthode paintComponent() (bien sûr il ne faut pas appeler la méthode parente qui efface tout par défaut).


    Citation Envoyé par filipaillou Voir le message
    Sachant que c'est une application paint, l'utilisateur peut potentiellement dessiner partout dans la zone de dessin et donc restreindre la zone de clip n'a pas de sens?
    Oui mais au moment où tu dessines tu peut déterminer cette zone, et donc appeller repaint(int,int,int,int) avec la zone détaillé permet d'éviter de tout redessiner à chaque fois



    Citation Envoyé par filipaillou Voir le message
    Ben c'est bien ce qui me chagrine mais je ne trouve pas comment eviter ce problème, je sais que j'utilise mal l'api de dessin mais je dois rendre le projet bientot et croyez moi j'ai déjà cherché en vain de n'utiliser que la surcharge de paintComponent pour mon dessin mais c trop lent...et je ne sais pas pk.
    Si ta liste comporte un très grand nombre d'élément le problème de lenteur peut venir de là. Si tu fait un point sur l'image tu la redessines entièrement depuis le début




    Je ne sais pas comment c'est fait dans les outils pro de dessin, mais perso je gèrerais 3 éléments :
    • Une BufferedImage qui contiendrait la totalité du dessin, ce qui permettrait de repeindre une zone rapidement sans avoir à parcourir toutes la listes des modifications.
    • L'élément en cours de dessin (par exemple le rectangle), c'est à dire la figure qui est en train d'être dessiné mais qui n'est pas encore réellement ajouté au dessin.
    • Et optionnellement une liste des modifications effectuées, qui contiendrait l'image de départ et les différentes opérations. Ce qui permettrait de reconstruire l'image depuis le début si besoin (annulation des dernières opérations). Il faudra toutefois veuillez à ce qu'elle ne deviennent pas trop imposante en taille...



    Cas d'utilisation :
    1. Au démarrage le paint() dessinera la totalité de ton image buffer.
    2. Lorsque tu dessines une figure, ton listener effectue deux actions :
      • Il modifie la figure en cours de dessin.
      • Il appelle repaint() en indiquant les coordonnées de la zone.

      La zone sur laquelle tu dessines sera réinitialisé à partir du buffer puis il dessinera par dessus la figure en cours de dessin. Tant que ta figure n'est pas validé (si tu agrandit le rectangle par exemple) il redessinera la zone correspondante puis la figure temporaire par dessus.
      La seule chose à gérer c'est de conserver la zone de clip précédente et de l'utiliser si elle est plus grande que la zone courante (par exemple si on réduit le rectangle) afin de bien effacer tout ce qu'il faut.
    3. Une fois que la figure est validé (clic relâché par exemple), tu ajoutes la figure dans la liste des modifications, et tu la dessines sur le buffer avant de faire un repaint de la zone pour mettre à jour l'affichage.


    Ce qui donnerait une méthode paintComponent() a peu près 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
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    	protected void paintComponent(Graphics g) {
    		// On récupère la zone à redessiner :
    		final Rectangle r = g.getClipBounds();
     
    		// On détermine les positions de la zone de clip :
    		final int sx1 = r.x;
    		final int sy1 = r.y;
    		final int sx2 = r.x + r.width;
    		final int sy2 = r.y + r.height;
     
     
    		// On réinitialise la zone de clip avec le contenu
    		// de l'image utilisé en buffer à la même position.
    		g.drawImage(this.buffer,
    			sx1, sy1, sx2, sy2, // Positions dans le composant
    			sx1, sy1, sx2, sy2, // Positions dans le buffer
    			this);
     
     
    		// On dessine la figure en cours de dessin si besoin :
    		if (dessinEnCours) {
    			// TODO
    		}
    	}
    Dans ton paintComponent() tu fais le stricte minimum, en redessinant la zone de clip depuis une BufferedImage (ce qui devrait être assez rapide), puis en dessinant la figure en cours de dessin uniquement.
    Pas la peine de redessiner les 256 figures précédentes une à une

    a++

  8. #8
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Août 2005
    Messages : 6 851
    Points : 22 863
    Points
    22 863
    Billets dans le blog
    51
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    En appellant Oui mais au moment où tu dessines tu peut déterminer cette zone, et donc appeller repaint(int,int,int,int) avec la zone détaillé permet d'éviter de tout redessiner à chaque fois
    Effectivement le principe est de verifier si chaque forme* intersecte la zone a de clip et si c'est le cas la repeindre. Cette boucle et ces calculs sont bien bien plus rapides que de toute afficher a l'ecran.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if (clip.intersect(forme.getBounds()) && (forme.intersects(clip.getBounds())) {
      // A repeindre.
    }
    *si la boite englobante de la forme intersecte la zone de clip alors on teste si la forme elle-meme intersecte la zone de clip. Evidement si on utilise des indices de rendus avec de l'antialiasing, des Stroke assez epais ou meme des effets qui vont aggrandir la zone impactee par la forme (ex: flou gaussien), il faut se donner une marge d'erreur plus importante que la forme elle-meme.

    A voir apres si un test de colision plus avance/plus precis s'impose ou pas (idee: utiliser le PathIterator de la zone de clip et verifier si au moins un point est dans la forme. Mais ca peut etre couteux en performances).

    Je ne sais pas comment c'est fait dans les outils pro de dessin, mais perso je gèrerais 3 éléments :
    Je dirais, a priori (car je n'ai jamais fait quelques chose d'aussi avance) qu'un gros effort d'optimisation a du etre fait sur le stockage. Donc a fortiori (pas 36 solutions) la surface de dessin doit etre divisee en zones et les formes doivent etre stockees dans un arbre ou une table de hashage en fonction de la ou des zones dans lesquelles elles se trouvent et eventuellement de leur profondeur. Une simple liste ne semble evidement pas etre une bonne idee quand on a un tres grand nombre de formes.

  9. #9
    Futur Membre du Club
    Inscrit en
    Décembre 2008
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 10
    Points : 6
    Points
    6
    Par défaut
    Merci pour vos réponses, je vous avoue ne pas avoir tout compris mais je vais me pencher dessus plus tard. Pour le moment un tas de choses à faire. Je pense que de toute manière ce genre de techniques peut être utile à n'importe quelle personne qui veut faire du dessin un peu avancé en java.

Discussions similaires

  1. problème d'incompréhension avec les jointures
    Par healou dans le forum Requêtes
    Réponses: 15
    Dernier message: 08/06/2011, 11h32
  2. Réponses: 2
    Dernier message: 14/02/2009, 14h07
  3. Dessiner des formes géométriques 2D et 3D
    Par whitespirit dans le forum C++Builder
    Réponses: 14
    Dernier message: 21/01/2008, 09h09
  4. [Forms]sérieux problème avec forms
    Par med_anis_dk dans le forum Forms
    Réponses: 6
    Dernier message: 21/05/2006, 00h14
  5. Réponses: 7
    Dernier message: 19/10/2004, 16h12

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