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 :

animation qui ne s'anime pas


Sujet :

2D Java

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    95
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 95
    Par défaut animation qui ne s'anime pas
    Bonjour,
    j'ai un problème qui doit être assez classique.
    Le voici :
    Pour faire simple, je veux créer une petite animation, mettons un rectangle qui se déplace dans un JPanel. Sa position dépend de la numérotation d'étapes.
    J'ai une méthode dans une classe Anim qui trace le rectangle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    public void traceRectangle(int etape, Graphics2D g2D)
    {
         g2D.draw(rectangle);
    }
    puis je redéfinie, comme il se doit, la méthode paintComponent de la classe JPanel 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
     
    protected void paintComponent(Graphics g)
    {
            super.paintComponent(g);
            Graphics2D g2D = (Graphics2D) g;
     
            for(int etape = 1; etape <= 10; etape++)
            {
                anim.traceRectangle(etape, g2D);
                System.out.println("Etape = " + etape);
                Thread.sleep(1000);
             }
    }
    Je passe bien sûr sur le bloc try/catch que je n'ai pas mis pour simplifier.

    Donc quand je lance le prog, les messages : "Etape = 1 Etape = 2, ... Etape = 10, s'affichent bien à raison d'une étape par seconde comme prévu, en revanche, et c'est là mon problème, les rectangles ne s'affichent pas les uns après les autres mais les 10 d'un seul coup.
    Alors pourquoi cela fonctionne avec l'affichage des étapes et pas avec l'affichage des rectangles ?
    Et comment remédier simplement à ce problème ? ... sans créer de Thread (car ça je sais faire, ou à peu près).

    Merci pour vos réponses.
    Virgile

  2. #2
    Membre Expert
    Avatar de visiwi
    Profil pro
    Inscrit en
    Février 2008
    Messages
    1 052
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 1 052
    Par défaut
    Salut,

    Une voie possible assez simple est de :

    Tu doit séparer ce qui d'un coté représente une modélisation (des calculs), même simple, comme par exemple dire que régulièrement on doit déplacer de tant de pixels tel objet. Et de l'autre l'affichage de ces objets.
    Cela t'amène a un objet possédant deux méthodes l'une chargée de calculer et mettre à jour tes objets d'un point de vue mathématiques (des données), et l'autre chargée de les dessiner (avec un objet Graphics) à l'écran.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class Game {
     
          public void calcul() {
                // calculs
          }
     
          public void dessine(Graphics g) {
                // peindre les objets
          }
     
    }
    Ensuite, il te faut passer par un Thread (ou un dérivé), sinon ton appli sera bloqué. Ce Thread sera charger d'appeler régulièrement d'abord la méthode calcul, puis de dessiner les objets. Tu peut avantageusement utiliser un Timer.

    Le fait "d'endormir" ton paint par un sleep(n) est à proscrire. En raison du fonctionnement de l'EDT (chargé de l'affichage en Swing), cela fait que tout s'affiche d'un coupt. C'est une notion importante et tu trouvera de la doc sur le sujet sur le site (EDT = EventDispatchThread).

    Voici un exemple simple :
    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
     
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.Timer;
     
    // le jeu qui est un panel
    public class Game extends JPanel {
     
    	public static void main(String[] args) {
    		JFrame frame = new JFrame();
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		frame.setContentPane(new Game());
    		frame.pack();
    		frame.setLocationRelativeTo(null);
    		frame.setVisible(true);
    	}
     
    	private final static int FRAME_RATE = 50; // fps (on aura environ 50 cycle d'animations toutes les secondes), cela conditionne la vitesse général du jeu (donc de tous les objets animés)
    	private final static int TIMER_TIME = 1000 / FRAME_RATE;// en millisecondes (soit 1 secondes diviser par fps)
     
    	private Timer timer;
    	private Balle balle;
    	private int step;
     
    	public Game() {
    		setPreferredSize(new Dimension(200, 200));
    		step = 3; // en pixel (cela conditionne uniquement la vitesse de la balle)
    		balle = new Balle();
    		// la méthode actionPerformed sera appeler toutes les TIMER_TIME fois millisecondes
    		timer = new Timer(TIMER_TIME, new ActionListener() {
    			@Override
    			public void actionPerformed(ActionEvent e) {
    				compute();
    				repaint();
    			}			
    		});
    		timer.start(); // démmarrer le timer
    	}
     
    	// calcul les nouvelles coordonnées des objets, dans ce cas il n'y en a qu'un
    	public void compute() {
    		int newX = balle.getX() + step; // nouvelle coordonneé en x
    		// on vérifie que la nouvelle coordonnée ne touche pas un bord
    		if (newX < 0) {
    			newX = 0; // empêche la balle de sortir du cadre gauche
    			step = -step;  // inverser le sens de déplacement de la balle
    		} else if (newX + balle.getDiametre() > getWidth()) {
    			newX = getWidth() - balle.getDiametre(); // empêche la balle de sortir du cadre droit
    			step = -step; // inverser le sens de déplacement de la balle
    		}
    		balle.setX(newX); // fixer la nouvelle coordonnée en x
    	}
     
    	// dessine les objets, dans ce cas il n'y en a qu'un
    	@Override
    	protected void paintComponent(Graphics g) {
    		super.paintComponent(g);
    		balle.draw(g);
    	}
     
    }
     
    // un objet représentan le modèle d'une balle avec une méthode pour la dessiner
    class Balle {
     
    	private int diametre;
    	private int x;
    	private int y;
     
    	public Balle() {
    		x = 0;
    		y = 50;
    		diametre = 30;
    	}
     
    	public int getDiametre() {
    		return diametre;
    	}
     
    	public void setDiametre(int diametre) {
    		this.diametre = diametre;
    	}
     
    	public int getX() {
    		return x;
    	}
     
    	public void setX(int x) {
    		this.x = x;
    	}
     
    	public int getY() {
    		return y;
    	}
     
    	public void setY(int y) {
    		this.y = y;
    	}
     
    	public void draw(Graphics g) {
    		g.fillOval(x, y, diametre, diametre);
    	}
     
    }
    En espérant que cela puisse te faire avancer...
    N'hésite pas si tu as des questions.
    @+

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    95
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 95
    Par défaut Ok. merci beaucoup mais regardez ceci
    Je ne comprend pas pourquoi l'animation marche dans ce cas-là, alors que ça ressemble fortement à mon cas (qui lui, ne marche pas).

    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
     
    import java.awt.Color;
    import java.awt.Graphics;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
     
     
     
    public class Main {
     
        int x = 70, y = 70;
     
        public static void main(String[] args) {
            Main ihm = new Main();
            ihm.go();
        }
     
        public void go() {
            JFrame cadre = new JFrame();
            cadre.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
            MonPanneau panneau = new MonPanneau();
     
            cadre.getContentPane().add(panneau);
            cadre.setSize(300, 300);
            cadre.setVisible(true);
     
            for(int i = 0; i < 130; i++) {
                x++; y++;
                panneau.repaint();
     
                try{
                    Thread.sleep(50);
                } catch (Exception e){
                }
            }
     
        }
     
        class MonPanneau extends JPanel {
     
            @Override
            protected void paintComponent(Graphics g)
            {
                super.paintComponent(g);
                g.setColor(Color.WHITE);
                g.fillRect(0, 0, this.getWidth(), this.getHeight());
     
                g.setColor(Color.GREEN);
                g.fillOval(x, y, 40, 40);
            }
     
     
        }
     
    }

  4. #4
    Membre Expert
    Avatar de visiwi
    Profil pro
    Inscrit en
    Février 2008
    Messages
    1 052
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 1 052
    Par défaut
    Citation Envoyé par Virgile le chat Voir le message
    Je ne comprend pas pourquoi l'animation marche dans ce cas-là, alors que ça ressemble fortement à mon cas (qui lui, ne marche pas).
    Mais il fonctionne (du moins ton cercle se déplace) mais ce n'est pourtant pas la même chose. Ton appli est bloqué le temps de l'animation.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    for(int i = 0; i < 130; i++) {
                x++; y++;
                panneau.repaint();
     
                try{
                    Thread.sleep(50);
                } catch (Exception e){
                }
            }

  5. #5
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Août 2005
    Messages : 6 914
    Billets dans le blog
    54
    Par défaut
    L'EDT est une Thread qui, dans l'AWT ou dans Swing, s'occupe a la fois de dessiner et de propager les evemements. Si tu la bloques sur un long calcul, elle ne fera ni l'un, ni l'autre :
    - Quand tu fais un sleep() ou une boucle dans le paintComponent(), ton appli ne fait rien d'autre durant ce temps (elle ne se reaffiche pas).
    - Et c'est pareil quand tu fais ce genre ces trucs dans un listenener quelconque.
    C'est ainsi que fonctionne l'EDT, c'est une Thread unique.

    Donc ton sleep() ou ta boucle doit etre fait dans une autre Thread et appeller repaint() de maniere a ce que l'EDT puisse dessiner les etapes intermediaires (un jeu ou un moteur d'animation plus precis utilisera des methodes de timing plus complexes qui tiennent compte du FPS, du taux de rafraichissement ou du temps passe a rendre une frame par exemple pour essayer d'avoir l'animation la plus fluide possible).

    Lancer une autre Thread pour faire un travail lourd c'est facile, tu peux utiliser :
    - Thread
    - java.util.Timer (a ne pas confondre avec javax.swing.Timer qui lui fait des taches dans l'EDT).
    - SwingWorker

    Mais il faut alors faire attention a l'interraction entre cette nouvelle Thread et l'EDT. Pas de probleme quand on appelle juste repaint() (repaint() est une methode qui retourne immediatement et indique juste qu'il faut repeindre plus tard) ou dans ton cas juste modifier les coordonnees de ta forme. Par contre pour appeler des trucs du genre myJTable.setXXXX, ces appels doivent exclusivement se faire sur l'EDT et donc il faut utiliser SwingUtilities.invokeLater() pour mettre a jour la GUI dans la bonne Thread.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    95
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 95
    Par défaut merci
    Merci pour ces très intéressantes réponses.
    Mais j'ai du mal à comprendre le fonctionnement du Thread EDT.
    Par exemple, avec mon exemple ci-dessus (la boule qui se déplace), si j'ai bien compris ce que vous m'avez expliqué, ça fonctionne car il y a deux Thread (le Thread Main et l'EDT). Le Thread main exécute main et l'edt s'occupe de l'affichage. Mais j'ai modifié légèrement ce petit programme test en ajoutant un bouton à la fenêtre et en mettant et en mettant dans actionPerformed (méthode appelée lors du clic sur le bouton) le code qui éxécutait le déplacement de la boule. Voici une portion du 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
    17
    18
    19
    20
    21
    22
     
    JButton go  = new JButton("GO !");
     
            go.addActionListener(new ActionListener() {
     
                public void actionPerformed(ActionEvent e)
                {
                    for(int i = 0; i < 130; i++) {
                                x++; y++;
                                System.out.println("Avant repaint " + Thread.currentThread().getName());
     
                                panneau.repaint();
     
                                System.out.println("Après repaint" + Thread.currentThread().getName());
     
                                try{
                                    Thread.sleep(50);
                                } catch (Exception exp){
                                }
                            }
                }
            });
    Et là, le clic sur le bouton ne fait plus déplacer la boule !!!
    La boucle s'éxécute bien puisque j'ai une série d'affichages du type :
    Avant repaint : AWT- event queue
    Après repaint : AWT- event queue

    Que se passe-t-il donc ?
    La demande de rafraichissement de l'affichage (repaint) n'est plus prise en compte dans ce cas-là. Je suppose que c'est parce qu'elle est à l'intérieur de la méthode actionPerformed (seule possibilité!). Bon ok. Et alors ???
    Donc si j'ai bien compris, le repaint n'est pas exécuté parce qu'il est exécuté par le thread EDT et que celui-ci est en train d'éxécuter actionPerformed ?
    Et pourquoi ???
    Pourquoi ce thread n'exécute pas repaint même s'il est en train d'éxécuter actionPerformed ? Quel rapport ?

    Désolé d'être aussi insistant mais je déteste ne pas comprendre précisémment les choses. Et ces histoires de Thread EDT m'ont l'air d'avoir un fonctionnement un peu spécial.
    Merci beaucoup.

  7. #7
    Membre Expert
    Avatar de visiwi
    Profil pro
    Inscrit en
    Février 2008
    Messages
    1 052
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 1 052
    Par défaut
    Bonjour,

    Oui, c'est pas forcément simple à comprendre !
    Ton prog doit fonctionner, mais d'une part ton bouton doit rester enfoncé, et la balle ne doit pas se déplacer (à l'écran), puis, lorsque la méthode actionPerformed se termine, la balle doit se déplacer d'un coup d'un seul à sa destination final.
    Tout cela à cause du fonctionnement de l'EDT. C'est ce que ta fort bien résumé bouye.

    Par analogie tu peut voir l'EDT comme un gars qui fait la plonge (enfin peut-être ). Son travail c'est de laver une pile d'assiettes empilés. Seulement, il lave toujours l'assiette en bas de la pile. Il y a des serveurs qui viennent rajouter des assiettes sur le dessus de la pile de temps en temps, mais le pongeur/EDT lave assiette du bas après assiette du bas. Donc les assiettes seront toujours lavées dans un certain ordre, celui de leur arrivée sur la pile. Les assiettes tu l'aura compris est ce que tu demande à l'EDT. Ce mode de fonctionnement présente le gros avantage que tu sais à l'avance que les assiettes seront lavées dans l'ordre d'arrivé, pas dans un ordre aléatoire.

    Pour revenir à ton exemple :
    Dans la méthode actionPerformed de ton bouton tu es dans l'EDT (listener). Dans cette méthode tu fait varier la coordonnée de la balle et demande un repaint, l'EDT empile ces demande (comme les serveurs empilaient les assiettes). Mais il est dans l'incapacité de les traiter car il est déjà en train de faire quelque chose (l'EDT de ne fait qu'une chose après l'autre), c'est à dire traiter ton événement de clic sur ton bouton (ta méthode actionPerformed). Une fois que cet événement est traité (la fin de la méthode actionPerformed) il a du temps pour faire autre chose, c'est à dire de faire tous ce que tu lui a demandé dans ta boucle, et comme ça va très vite, et bien ta balle se retrouve tout d'un coup affiché à sa destination finale sans que ton œil est pu l'a voir s'animer.
    Ton sleep sert juste à retarder l'EDT, pas à temporiser une animation.

    Solution :
    Un Thread.
    Lance le code dans ton listener à l'interieur d'un Thread et cela fonctionnera.
    Parce que tu libère l'EDT de son assiète actuelle qui est traiter la méthode actionPerformed. Au passage, tu verra aussi que le bouton ne reste plus enfoncé.

    Voila, je ne sais pas si j'ai été très clair ni si cela t'aidera, mais au moins j'aurais essayer

  8. #8
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Août 2005
    Messages : 6 914
    Billets dans le blog
    54
    Par défaut
    Pour en rajouter une couche, ton Tread main se termine juste après la fin de cet appel : frame.setVisible(true);
    Mais il se trouve que cet appel a créé et démarrer une nouvelle Thread non-daemon* : l'EDT.
    Donc ton programme ne se termine pas après cet appel comme il aurait du le faire (PS : sur des JVM récentes sous Windows et/ou dans JavaFX d'autres Threads daemon* peuvent être également lancés comme une Thread direct3D helper, etc.).

    *Une Thread daemon c'est une Thread qui n'empêche pas la fermeture du programme.

    Souviens-toi, L'EDT n'est pas une Thread daemon et si tu ne fais pas frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);, le programme ne se termine pas quand on ferme la fenêtre car l'EDT continue de tourner en tache de fond.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    	public static void main(String[] args) {
    		JFrame frame = new JFrame();
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		frame.setContentPane(new Game());
    		frame.pack();
    		frame.setLocationRelativeTo(null);
    		frame.setVisible(true);
    	}
    Au fait ton main() n'est pas bon : en effet pour bien programmer en Swing et se prévenir de crash potentiels (qui peuvent n'arriver que si tu changes de JVM ou de platforme), les composants Swing doivent uniquement être créés et manipulés dans l'EDT. Donc ton main() devrait plutot ressembler à 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
     
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {  
                 // Tout ce qui suit est désormais exécuté dans l'EDT.                       
                 JFrame frame = new JFrame();
                 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                 frame.setContentPane(new Game());
                 frame.pack();
                 frame.setLocationRelativeTo(null);
                 frame.setVisible(true);
            }
        }
    }
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    95
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 95
    Par défaut Oui mais repaint est dans actionperformed !
    D'abord merci a tous de prendre le temps de m'expliquer.
    Je crois avoir compris l'histoire de l'empilement des assiettes. Je comprends bien que l'EDT ne peut pas faire plusieurs choses à la fois et donc qu'il fini l'assiette actionperformed avant de passer à l'assiette suivante (pour reprendre l'analogie précédente ) mais actionperformed contient l'appel de repaint donc son exécution devrait entraîner l'execution de repaint !
    Bon, ok ça ne marche pas comme ça. Daccord. Donc si j'ai bien compris (corrigez moi sinon) l'EDT s'occupe de deux choses : dessinner et exécuter les méthodes des listeners. Et il ne peut pas faire deux choses en même temps. Donc quand un repaint est dans un actionperformed il exécute l'actionperformed et quand il voit le repaint dans cet actionperformed il se dit "oh mon Dieu, j'ai pas assez de bras pour exécuter tout de suite ce repaint donc je le garde en mémoire (assiette suivante) , je finis mon action performed en ignorant temporairement ce repaint. Et je ferai tous ces repaint après " c'est bien ça ? Quelle idée bizarre. Enfin, j'imagine qu'il y a une raison à tout ça.

  10. #10
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Août 2005
    Messages : 6 914
    Billets dans le blog
    54
    Par défaut
    repaint() ne peint rien.
    repaint() met juste un flag quelques part qui dit "hey pssst, la prochaine fois que tu as tu temps libre redessine-moi pleaze" et retourne immédiatement.

    Donc comme prévu pendant que tu gères les évènements tu n'es pas en train de redessiner.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    95
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 95
    Par défaut Merci
    Merci à tous d'avoir pris tout ce temps pour m'expliquer.
    Je crois que j'ai à peu près compris tout ça...grâce à vous !

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

Discussions similaires

  1. Animation flash qui ne s'affiche pas en ligne
    Par Thierry_A dans le forum Flash
    Réponses: 1
    Dernier message: 21/09/2008, 12h27
  2. Réponses: 2
    Dernier message: 28/10/2007, 18h46
  3. gif animé qui ne s"affiche pas sous IE
    Par manaboko dans le forum Balisage (X)HTML et validation W3C
    Réponses: 3
    Dernier message: 10/08/2007, 17h11
  4. Réponses: 1
    Dernier message: 21/11/2006, 22h56
  5. Un Gif animé qui ne se fige pas lors des traitements ?
    Par delphi+ dans le forum Composants VCL
    Réponses: 11
    Dernier message: 18/03/2006, 11h31

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