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

Agents de placement/Fenêtres Java Discussion :

Problème redessiner composants


Sujet :

Agents de placement/Fenêtres Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Développeur Java
    Inscrit en
    Février 2012
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 24
    Par défaut Problème redessiner composants
    Bonjour à tous j'ai actuellement un gros problème je souhaite réaliser un déplacement d'une boule, le déplacement se passe correctement, mais il s'accade énormément ! en effet lorsque j'enlève par exemple le "Thread.sleep'" on voit bien tout les composants se raffraichir !

    Voici le code :

    Core.java :

    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
    package com.batak;
     
    import com.batak.frame.components.PlayerDecors;
     
    public class Core implements Runnable{
    	private Thread thread;
    	private PlayerDecors playerDecors;
    	public boolean stop = true;
     
    	public Core(PlayerDecors player_decors) {
    		this.playerDecors = player_decors;
    		this.setThread(new Thread(this));
    		this.thread.start();
    	}
     
    	public void setThread(Thread _Thread) {
    		this.thread = _Thread;
    	}
     
    	public Thread getThreadInstance() {
    		return this.thread;
    	}
     
    	@Override
    	public void run() {
    		try {
    			while(true) {
    				//Thread.sleep(50);
    				if(!stop)this.playerDecors.move();
    			}
    		} catch(Exception e) {
    			System.out.println("Interruption du Thread : "+this.thread.getName());
    		}
     
    		System.exit(0);
     
    	}
     
    }
    Loader.java :

    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
    package com.batak;
     
    import java.awt.BorderLayout;
     
    import javax.swing.JFrame;
     
    import com.batak.frame.MapInitializer;
    import com.batak.listener.KeyboardListener;
     
    public class Loader {
     
    	private static JFrame frame;
     
    	public static void main(String[] args) {
    		frame = new JFrame();
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		MapInitializer mInit = new MapInitializer();
    		frame.getContentPane().setLayout(new BorderLayout());
    		frame.getContentPane().add(mInit, BorderLayout.CENTER);
    		frame.pack();
    		frame.setVisible(true);
    		frame.setResizable(false);
     
     
    		Core core = new Core(mInit.getMapBuffer().getPlayer());
    		KeyboardListener kListener = new KeyboardListener(core);
    		frame.addKeyListener(kListener);
    	}
     
    	public static JFrame getFrame() {
    		return frame;
    	}
     
    }
    MapBuffer.java :

    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
    package com.batak.frame;
     
    import java.awt.Color;
    import java.awt.Graphics2D;
    import java.awt.image.BufferedImage;
    import java.util.ArrayList;
     
    import com.batak.Loader;
    import com.batak.frame.components.ComponentModel;
    import com.batak.frame.components.InteractiveDecors;
    import com.batak.frame.components.PlayerDecors;
     
    public class MapBuffer {
     
    	private BufferedImage MapImgBuffer;
    	private Graphics2D GraphBuffer;
    	private int Width = (int)Loader.getFrame().getToolkit().getScreenSize().getWidth() / 2;
    	private int Height = (int)Loader.getFrame().getToolkit().getScreenSize().getHeight() / 2;
    	private MapInitializer mapInit;
    	private static MapBuffer instance = null;
    	private PlayerDecors player;
     
    	private ArrayList<Object> tile = new ArrayList<Object>();
     
    	public MapBuffer(MapInitializer Map_Init) {
    		this.mapInit = Map_Init;
    		this.initialize();
    	}
     
    	private void initialize() {
    		instance = this;
    		this.setMapBuffer(new BufferedImage(this.Width, this.Height, BufferedImage.TYPE_INT_ARGB));
    		this.setGraphBuffer(this.MapImgBuffer.createGraphics());
     
    		/*this.GraphBuffer.setColor(Color.WHITE);
    		this.GraphBuffer.fillRect(0, 0, this.Width, this.Height);*/
     
    		InteractiveDecors.initializer(this);
    		PlayerDecors.initializer(this);
     
    		tile.add(new InteractiveDecors(60, 40));
    		tile.add(new InteractiveDecors(10, 30));
    		tile.add(player = new PlayerDecors());
     
    		this.draw();
    	}
     
    	public PlayerDecors getPlayer() {
    		return player;
    	}
     
     
    	public void draw() {
    		this.GraphBuffer.setColor(Color.WHITE);
    		this.GraphBuffer.fillRect(0, 0, this.Width, this.Height);
    		for(Object o : this.tile) {
    			ComponentModel cModel = (ComponentModel)o;
    			//this.GraphBuffer.setBackground(Color.WHITE);
    			this.GraphBuffer.drawImage(cModel.getBuffer(), cModel.getX(), cModel.getY(), this.mapInit);
    		}
    	}
     
    	public int getWidth() {
    		return Width;
    	}
     
    	public int getHeight() {
    		return Height;
    	}
     
    	public BufferedImage getMapBuffer() {
    		return this.MapImgBuffer;
    	}
     
    	public void setMapBuffer(BufferedImage Map_Buffer) {
    		this.MapImgBuffer = Map_Buffer;
    	}
     
    	public Graphics2D getGraphBuffer() {
    		return this.GraphBuffer;
    	}
     
    	public void setGraphBuffer(Graphics2D Graph_Buffer) {
    		this.GraphBuffer = Graph_Buffer;
    	}
     
    	public static MapBuffer getInstance() {
    		return instance;
    	}
     
    	public MapInitializer getMapInit() {
    		return this.mapInit;
    	}
     
    }
    MapInitializer.java :
    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
     
    package com.batak.frame;
     
    import java.awt.Dimension;
    import java.awt.Graphics;
     
    import javax.swing.JPanel;
     
    public class MapInitializer extends JPanel{
     
    	/**
             * 
             */
    	private static final long serialVersionUID = 1L;
    	private MapBuffer MapBuffer;
     
    	public MapInitializer() {
    		this.setMapBuffer(new MapBuffer(this));
    		this.setOpaque(true);
    	}
     
    	public MapBuffer getMapBuffer() {
    		return this.MapBuffer;
    	}
     
    	private void setMapBuffer(MapBuffer Map_Buffer) {
    		this.MapBuffer = Map_Buffer;
    	}
     
    	public Dimension getPreferredSize() {
    		return new Dimension(MapBuffer.getWidth(), MapBuffer.getHeight());
    	}
     
    	@Override
    	protected void paintComponent(Graphics graph)
    	{
    		super.paintComponent(graph);
    		graph.drawImage(this.MapBuffer.getMapBuffer(), 0, 0, this );
    	}
     
    }
    ComponentModel.java :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    package com.batak.frame.components;
     
    import java.awt.image.BufferedImage;
     
    public interface ComponentModel {
     
    	public abstract int getX();
     
    	public abstract int getY();
     
    	public abstract BufferedImage getBuffer();
     
    }
    InteractiveDecors.java :

    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
    package com.batak.frame.components;
     
    import java.awt.Color;
    import java.awt.Graphics2D;
    import java.awt.image.BufferedImage;
     
    import com.batak.frame.MapBuffer;
     
    public class InteractiveDecors implements ComponentModel{
     
    	private static BufferedImage DecorsImgBuffer;
    	private static Graphics2D GraphDecors;
     
    	private int Width = 80;
    	private int Height = 30;
    	private int PosX;
    	private int PosY;
     
    	public InteractiveDecors(int pos_X, int pos_Y) {
    		this.PosX = pos_X;
    		this.PosY = pos_Y;
     
    		this.drawComponent();
    	}
     
    	private void drawComponent() {
    		GraphDecors.setColor(Color.BLACK);
    		GraphDecors.fillRect(0, 0,this.Width, this.Height);
    	}
     
    	public static void initializer(MapBuffer Map_Buffer) {
    		DecorsImgBuffer = new BufferedImage(Map_Buffer.getWidth(), Map_Buffer.getHeight(), BufferedImage.TYPE_INT_ARGB);
    		GraphDecors = DecorsImgBuffer.createGraphics();
    	}
     
    	@Override
    	public int getX() {
    		return this.PosX;
    	}
     
    	@Override
    	public int getY() {
    		return this.PosY;
    	}
     
    	@Override
    	public BufferedImage getBuffer() {
    		return InteractiveDecors.DecorsImgBuffer;
    	}
     
    }
    PlayerDecors :
    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
     
    package com.batak.frame.components;
     
    import java.awt.Color;
    import java.awt.Graphics2D;
    import java.awt.image.BufferedImage;
     
    import com.batak.frame.MapBuffer;
     
    public class PlayerDecors implements ComponentModel{
     
    	private static BufferedImage PlayerImgBuffer;
    	private static Graphics2D GraphPlayer;
     
    	private int Width = 50;
    	private int Height = 50;
    	private int PosX = 50;
    	private int PosY = MapBuffer.getInstance().getHeight() - 100;
     
    	public PlayerDecors() {
    		this.drawComponent();
    		move();
    	}
     
    	private void drawComponent() {
    		GraphPlayer.setColor(Color.BLACK);
    		GraphPlayer.fillOval(0, 0, this.Width,this.Height);
    	}
     
    	public static void initializer(MapBuffer Map_Buffer) {
    		PlayerImgBuffer = new BufferedImage(Map_Buffer.getWidth(), Map_Buffer.getHeight(), BufferedImage.TYPE_INT_ARGB);
    		GraphPlayer = PlayerImgBuffer.createGraphics();
    	}
     
    	public void move() {
    		for(int a = 0; a < 20; a++) {
    			this.PosX += 3;
    			MapBuffer.getInstance().draw();
    			MapBuffer.getInstance().getMapInit().repaint();
    			try {
    				Thread.sleep(20);
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    		}
    	}
     
    	@Override
    	public int getX() {
    		return this.PosX;
    	}
     
    	@Override
    	public int getY() {
    		return this.PosY;
    	}
     
    	@Override
    	public BufferedImage getBuffer() {
    		return PlayerDecors.PlayerImgBuffer;
    	}
     
    }
    et KeyboardListener.java :

    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
    package com.batak.listener;
     
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
     
    import com.batak.Core;
     
    public class KeyboardListener implements KeyListener{
    	private Core core;
     
    	public KeyboardListener(Core _core) {
    		this.core = _core;
    	}
     
    	@Override
    	public void keyPressed(KeyEvent arg0) {
    		this.core.stop = false;
     
    	}
     
    	@Override
    	public void keyReleased(KeyEvent arg0) {
    		this.core.stop = true;
     
    	}
     
    	@Override
    	public void keyTyped(KeyEvent arg0) {
    		// TODO Auto-generated method stub
     
    	}
     
    }
    Voilà donc en fait lorsque je redessine tout, je redessine également un rectangle plein blanc pour mettre par dessus le reste.

    Merci

  2. #2
    Membre Expert
    Avatar de yotta
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Septembre 2006
    Messages
    1 097
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 097
    Par défaut
    Vous devriez plutôt utiliser un javax.swing.SwingWorker
    ...
    Une technologie n'est récalcitrante que par ce qu'on ne la connait et/ou comprend pas, rarement par ce qu'elle est mal faite.
    Et pour cesser de subir une technologie récalcitrante, n'hésitez surtout pas à visiter les Guides/Faq du site !

    Voici une liste non exhaustive des tutoriels qui me sont le plus familiers :
    Tout sur Java, du débutant au pro : https://java.developpez.com/cours/
    Tout sur les réseaux : https://reseau.developpez.com/cours/
    Tout sur les systèmes d'exploitation : https://systeme.developpez.com/cours/
    Tout sur le matériel : https://hardware.developpez.com/cours/

  3. #3
    Membre averti
    Homme Profil pro
    Développeur Java
    Inscrit en
    Février 2012
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 24
    Par défaut
    Un swingWorker n'est pas utilisé plutôt dans les cas ou il faut faire un calcul assé gourmant pour mettre à jour un affichage ? ici je modifie juste les coordonnées du point pour le faire avancer.
    J'ai également utilisé un timer qui refresh tout le temps le point toute les 5s, cela marche mais j'ai peur que sa fasse trop "bidouillage" je vais donc essayer avec un swingWorker

  4. #4
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par reben Voir le message
    Un swingWorker n'est pas utilisé plutôt dans les cas ou il faut faire un calcul assé gourmant pour mettre à jour un affichage ? ici je modifie juste les coordonnées du point pour le faire avancer.
    J'ai également utilisé un timer qui refresh tout le temps le point toute les 5s, cela marche mais j'ai peur que sa fasse trop "bidouillage" je vais donc essayer avec un swingWorker
    Oui le swingworker sert à effectuer un changement d'état à afficher qui est long, et donc qui bloquerait l'UI si on le faisait dans le thread de la GUI.

    Il faut prendre les deux problématiques séparément :
    - d'un coté le changement d'état
    - de l'autre l'affichage de l'état

    imaginons par exemple qu'on veuille dessiner une horloge :
    1) les changements d'état sont :
    - à chaque seconde, l'aiguille des secondes bouge
    - à chaque minute, l'aiguille des minutes bouge
    - à chaque heure, l'aiguille des heures bouge
    l'état est heures, minutes, secondes
    2) l'horloge doit pouvoir se dessiner n'importe quand quelque soit son état (par exemple on peut vouloir que l'horloge s'étende sur la totalité de la fenêtre, et donc quand on redimensionne la fenêtre, elle se redessine dans une nouvelle taille)

    Il faut donc un état à son rythme, et quand l'état est complètement changé, dire à la GUI que l'état a changé, et qu'elle doit se redessiner.
    Le rithme de changement d'état peut être controllé par
    - un thread, ou un timer, pour un changement à intervalle régulier, ou pas d'ailleurs
    - mais également un système évenementiel : genre chaque fois qu'on clique à la souris, ou on appuie sur une touche du clavier, ou autre...
    - peut importe, d'ailleurs, tant que le changement d'état est asynchrone par rapport au dessin de la GUI

    Eventuellement le tranfert d'un état très complexe (comme par exemple la position de milliers de sprites) peut être long à transférer à l'UI : il faut s'arranger donc pour que lorsqu'on redessine un état celui ci ne puisse pas changer : on peut faire çà facilement en gérant l'état dans une classe à part :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    paintComponent(Graphics g) {
     
       MyState paintstate = this.state;
       g."draw"(paintstate.getVar1..., ...);
       g."draw"(paintsetat.getVar2...
     
    }
    ainsi tu peux changer ta variable de classe même si paintComponent est en cours, le state = newState étant atomique.

    ensuite, il peut y avoir des effets disgracieux dans l'affichage, comme le flickering : le multibuffering permet de l'éviter...

    J'avais donné un exemple d'anim avec doublebuffering une fois dans le post là. Si ça peut t'aider...
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  5. #5
    Membre averti
    Homme Profil pro
    Développeur Java
    Inscrit en
    Février 2012
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 24
    Par défaut
    Merci pour t'as réponse qui m'a énormément aidé, alors tout d'abord :

    J'utilise désormais un timer qui s'occupe de raffraichir "la balle" toute les 5ms.
    Dans mon keyEventListener lorsque l'on appuie une touche je donne la valeur de 1 à ma variable dx

    Dans mon timer je redessinne cette balle tout le temps en prenant en compte la valeur de dx, ce qui fait un déplacement correct.
    Il se peut que des fois il y'est des clippings ...

    J'ai donc regardé le bufferStrategy, hors est-ce que je ne l'utilise pas déjà ? en créant plusieurs BufferedImage et en les prenant lors du paintComponent qui est appelé ?

  6. #6
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par reben Voir le message
    J'ai donc regardé le bufferStrategy, hors est-ce que je ne l'utilise pas déjà ? en créant plusieurs BufferedImage et en les prenant lors du paintComponent qui est appelé ?
    Vite vu comme ça, j'ai pas l'impression : justement tu dessines toujours dans la même image, celle donc qui s'affiche à chaque repaint, donc tu peux être entrain de dessiner une partie de l'image alors que l'autre s'affiche ce qui fait du flicker...

    Le bufferStrategy fait qu'on multiple les images, et que celle dans laquelle on dessine et celle qui est utilisé pour rafraichir l'image n'est pas la même. Lorsqu'on a terminer de dessiner, on l'indique, et l'image dans laquelle on dessinait et celle qui servait à l'affichage se décale (ou s'échange en double buffer),

    pour du multibuffering, il faut 2 images au moins
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

Discussions similaires

  1. Problème de rafraîchissement/redessine composant
    Par pepito62 dans le forum Composants VCL
    Réponses: 0
    Dernier message: 13/01/2011, 22h00
  2. [ENVOI D'EMAIL] Problème de composant CDONTS
    Par ybenmakh dans le forum ASP
    Réponses: 1
    Dernier message: 10/01/2006, 15h43
  3. Problème de composant
    Par leycho dans le forum C++Builder
    Réponses: 7
    Dernier message: 03/01/2006, 16h04
  4. [C#]Problème sur composant perso (Bouton Transparent)
    Par SLE dans le forum Windows Forms
    Réponses: 1
    Dernier message: 06/10/2005, 00h12
  5. [VB.NET] Problème sur composant comboBox hérité
    Par SergeF dans le forum Windows Forms
    Réponses: 3
    Dernier message: 08/06/2004, 14h54

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