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:
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:
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
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:
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);
}
}
} |
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.