|
Réalisation 
|
|
Paint et Swing HELP !
|
Salut,
J'essaye de faire un pti jeu en Java comportant une grille (MVC)
J'ai donc un JPanel sur lequel je dessine des cases
Pour eviter que ca rame je redessine que ce dont j'ai besoin (2 cases) Et
pour eviter que mes composants parent m'explose mon dessin je ne fait pas
de super.paint(g);
Mon probleme c'est qu'il a une gestion des graphics completement etrange
et que mon parent doit faire un translate foireux sur mon graphics avant
de me le passer ou un truc du genre si je ne fais pas de super.paint(g);
Resultat les scrollbar ne marche pas, et des cases phantome sont
dessinees...
Bref:
*****
- Soit je repaint tout a chaque fois, ca marche tres bien mais ca rame en
1600x1200 (meme avec des offscreen ...) - Soit je repaint des pti bout
mais ca foire :-(
Le FullScreen JDK 1.4 ce sera pour apres ;-)
Ma question:
***************
Comment redessiner en Swing des petit bouts d'ecran à moi sans se faire
repaindre violement par les swing autour ?
-> Sachant que toutes les technique de offscreen ne marche pas (le
plaquage de l'offscreen a l'ecran est trop lent) et que les technique de
clipping ne sont pas trop appliquable.
Vous pouvez avoir un exemple sur http://www.encausse.net/
dans la rubrique civilisation, c'est du Java Web Start.
Merci beaucoup à tous,
Jp
Jean-Philippe Encausse
Jean-Philippe@Encausse.net - http://www.encausse.net
ICQ: 109796741 - AOL: NextOne6666 - Tel: 06.63.47.93.13
Do it Once, Use it Twice ~ Do it Twice, Generalize It
 |
 |
Salut,
J'ai eu le même Pb, et ma solution a été de comprendre
la gestion des graphics java, plutôt que de la refaire à ma sauce ;-)
=> utilise le clipping !
Dans ta méthode paint(Graphics g) commence par un test :
paint(Graphics g) {
Rectangle clip = g.getClipBounds();
if ( ! clip.intersects(maZone) )
return;
Là ça ne ramera plus, vu ton code devient très rapide !
Rémi
> J'essaye de faire un pti jeu en Java comportant une grille (MVC)
> J'ai donc un JPanel sur lequel je dessine des cases
>
> Pour eviter que ca rame je redessine que ce dont j'ai besoin (2 cases)
> Et pour eviter que mes composants parent m'explose mon dessin je ne fait
> pas de super.paint(g);
>
> Mon probleme c'est qu'il a une gestion des graphics completement etrange
> et que mon parent doit faire un translate foireux sur mon graphics avant
> de me le passer ou un truc du genre si je ne fais pas de super.paint(g);
> Resultat les scrollbar ne marche pas, et des cases phantome sont
> dessinees...
> -> Sachant que toutes les technique de offscreen ne marche pas (le
> plaquage de l'offscreen a l'ecran est trop lent) et que les technique de
> clipping ne sont pas trop appliquable. => Pourquoi ??
 |
 |
Le 17 Jan 02, Jean-Philippe Encausse a écrit :
> [...]
> Pour eviter que ca rame je redessine que ce dont j'ai besoin (2 cases)
> Et pour eviter que mes composants parent m'explose mon dessin je ne fait
> pas de super.paint(g);
>
Es-tu sûr ? A une époque j'ai dû travailler à optimiser l'affichage
swing, et je ne me souviens pas que super.paint faisait des choses
particulièrement anormales, ou dispendieuses en temps. Si
super.paint prend beaucoup de temps, c'est pour des raisons
justifiées, et il faut revoir ton architecture, ton code, ou je sais pas
quoi d'autre.
Première idée, ne serait-ce pas la méthode paintComponent qu'il
serait préférable de redéfinir ? (mais il faudra que tu re-appelles
super.paint, si tu fais ça).
Deuxième idée, tu sembles parler de temps en temps d'ascenceur.
Dès qu'il y a un ascenceur, l'optimisation est quasi-impossible, en
tout cas je connais pas la technique. A chaque fois, il faut
forcement redessiner tout le contenu de l'ascenceur.
Troisième idée, s'il y a des composants dans ton JPanel, il faut
archi-controler les sous-affichages. Pour peu que tu controles mal
les packs, les preferredSize et autres, ou que ton layout soit trop
compliqué, swing déclenche 150 fois l'affichage des sous-
composants. Rien de rédibitoire au niveau de la vitesse,
simplement il faut faire gaffe. S'il y a beaucoup de sous-
composants, plutôt que des JComposants, utilise la technique des
Renderers, que swing a développé pour les JTable, mais qui est
très mal généralisée. N'hésites pas à t'en faire une totalement
perso, en ne retenant que l'esprit de la technique.
> Mon probleme c'est qu'il a une gestion des graphics completement etrange
> et que mon parent doit faire un translate foireux sur mon graphics avant
> de me le passer ou un truc du genre si je ne fais pas de super.paint(g);
> Resultat les scrollbar ne marche pas, et des cases phantome sont
> dessinees...
>
Je dois admettre qu'il se passe des choses que j'ai pas toujours
comprites dans l'affichage swing.
> [...]
> Comment redessiner en Swing des petit bouts d'ecran à moi sans se faire
> repaindre violement par les swing autour ?
>
Moi je l'avais fait par l'utilisation des clips, en controlant bien que
paintComponent ne redessine que le clip (de toutes façons je crois que
swing empeche de le faire, mais en attendant ton code a passé du temps à
dessiner des trucs qui ne seront pas affichés), et en controlant bien que
les ordres d'affichages de l'appli (tout ton code extérieur au paint, et
qui aboutit en général à un repaint), contrôle lui aussi ce clip. Cela ne
sert à rien de controler le clip si les ordres d'affichage prennent
systématiquement tout l'écran !
> -> Sachant que toutes les technique de offscreen ne marche pas (le
> plaquage de l'offscreen a l'ecran est trop lent) et que les technique de
> clipping ne sont pas trop appliquable.
>
Je suis pas assez spécialiste pour optimiser le plaquage de
l'offscreen (si y'en a dans la salle, d'ailleurs, leurs idées
m'interessent).
Si le clipping n'est pas appliquable, c'est sans solution. Tu dois te
placer dans une config où le clipping est appliquable.
Tu peux aussi voir du coté des trucs habituels : éviter la création
d'objet (plus difficile à dire qu'à faire, puisqu'il faut la controler aux
trois niveaux de la MVC) (et avec les classes standards de swing c'est
totalement impossible), utiliser un outil de profiling, te doter d'outils
pour être parfaitement certain de tes clips (qui devraient être
appliquables :-); bien repérer la psychologie de l'affichage...
Bon courage, c'est possible : j'y suis arrivé !
--
Sur le Web, tout de suite.
Herve AGNOUX - diaam informatique
http://www.diaam-informatique.com
 |
 |
At 09:36 17/01/2002 +0100, you wrote:
>Le 17 Jan 02, Jean-Philippe Encausse a écrit :
>
> > [...]
> > Pour eviter que ca rame je redessine que ce dont j'ai besoin (2 cases)
> > Et pour eviter que mes composants parent m'explose mon dessin je ne
> > fait pas de super.paint(g);
> >
>
>Es-tu sûr ? A une époque j'ai dû travailler à optimiser l'affichage
>swing, et je ne me souviens pas que super.paint faisait des choses
>particulièrement anormales, ou dispendieuses en temps. Si
>super.paint prend beaucoup de temps, c'est pour des raisons
>justifiées, et il faut revoir ton architecture, ton code, ou je sais pas
>quoi d'autre.
super.paint() ne prends pas de temps c'est juste qu'il dessine en gris mon
panel en gros j'ai un panel avec 50 case j'en redessine a chaque fois que
2 mais si je ne fais pas de super.paint() ca marche, si je fais
super.paint() il efface tout et me dessine que deux cases.
Le probleme est visible quand je fais 2 C et 2 V pour un M dans mon modele
MVC (http://jphe.dynodns.net/sitejp/Civilisation/civilisation.jsp)
>Première idée, ne serait-ce pas la méthode paintComponent qu'il
>serait préférable de redéfinir ? (mais il faudra que tu re-appelles
>super.paint, si tu fais ça).
je vais essayer.
>Deuxième idée, tu sembles parler de temps en temps d'ascenceur.
>Dès qu'il y a un ascenceur, l'optimisation est quasi-impossible, en
>tout cas je connais pas la technique. A chaque fois, il faut
>forcement redessiner tout le contenu de l'ascenceur.
Oui j'ai un listener sur le JSCrollPane qui redessine tout quand je scroll
et le JScroll est tres inteligent car il fait un clip sur le graphics pour
me laisser redessiner qu'une partie et sur ce point ca marche
>Troisième idée, s'il y a des composants dans ton JPanel, il faut
>archi-controler les sous-affichages.
Non non il n'y a pas de sous composants
> Pour peu que tu controles mal
>les packs, les preferredSize et autres, ou que ton layout soit trop
>compliqué, swing déclenche 150 fois l'affichage des sous-
>composants. Rien de rédibitoire au niveau de la vitesse,
>simplement il faut faire gaffe. S'il y a beaucoup de sous-
>composants, plutôt que des JComposants, utilise la technique des
>Renderers, que swing a développé pour les JTable, mais qui est
>très mal généralisée.
C'est un mechanisme dans ce genre que j'utilise
> N'hésites pas à t'en faire une totalement
>perso, en ne retenant que l'esprit de la technique.
>
>
> > Mon probleme c'est qu'il a une gestion des graphics completement
> > etrange et que mon parent doit faire un translate foireux sur mon
> > graphics avant de me le passer ou un truc du genre si je ne fais pas
> > de super.paint(g); Resultat les scrollbar ne marche pas, et des cases
> > phantome sont dessinees...
> >
>
>Je dois admettre qu'il se passe des choses que j'ai pas toujours
>comprites dans l'affichage swing.
>
>
> > [...]
> > Comment redessiner en Swing des petit bouts d'ecran à moi sans se
> > faire repaindre violement par les swing autour ?
> >
>
>Moi je l'avais fait par l'utilisation des clips, en controlant bien que
>paintComponent ne redessine que le clip (de toutes façons je crois que
>swing empeche de le faire, mais en attendant ton code a passé du temps à
>dessiner des trucs qui ne seront pas affichés), et en controlant bien que
>les ordres d'affichages de l'appli (tout ton code extérieur au paint, et
>qui aboutit en général à un repaint), contrôle lui aussi ce clip. Cela ne
>sert à rien de controler le clip si les ordres d'affichage prennent
>systématiquement tout l'écran !
Apres des tests hier ce n'est pas le temps de calcul de ce qu'il y a
afficher qui est lent ni le temps de dessiner des truc dans un offscreen
mais ce qui est lent c'est le fait de plaquer une grosse image ou
offscreen a l'ecran
> > -> Sachant que toutes les technique de offscreen ne marche pas (le
> > plaquage de l'offscreen a l'ecran est trop lent) et que les technique
> > de clipping ne sont pas trop appliquable.
> >
>
>Je suis pas assez spécialiste pour optimiser le plaquage de
>l'offscreen (si y'en a dans la salle, d'ailleurs, leurs idées
>m'interessent).
>
>Si le clipping n'est pas appliquable, c'est sans solution. Tu dois te
>placer dans une config où le clipping est appliquable.
Je fais une sorte de clipping mais surtout je voudrais que mon parent ne
nettoie pas mon graphics avant de me le donner car sinon cela m'oblige de
tout redessiner et donc de plaquer une grosse image et donc de faire ramer
l'affichage
>Tu peux aussi voir du coté des trucs habituels : éviter la création
>d'objet (plus difficile à dire qu'à faire, puisqu'il faut la controler
>aux trois niveaux de la MVC) (et avec les classes standards de swing
>c'est totalement impossible), utiliser un outil de profiling, te doter
>d'outils pour être parfaitement certain de tes clips (qui devraient être
>appliquables :-); bien repérer la psychologie de l'affichage...
Oui normalement la partie code est rapide et proche de la psychologie
swing et MVC mais c'est le plaquage qui est lent si je suis oblige de
plaquer
Il y a peut etre une piste dans le Paint Mode ? ou un moyen de lui dire de
ne pas exploser l'image precedente
>Bon courage, c'est possible : j'y suis arrivé !
C'est vrai je chipotte car je dis que ca rame mais c'est en 1600x1200 :op
mais je suis sure qu'on peut mieux faire et j'ai bcp a apprendre en dessin
sous swing
Merci bcp,
@+
 |
 |
Le 17 Jan 02, Jean-Philippe Encausse a écrit :
>
> super.paint() ne prends pas de temps c'est juste qu'il dessine en gris
> mon panel en gros j'ai un panel avec 50 case j'en redessine a chaque
> fois que 2 mais si je ne fais pas de super.paint() ca marche, si je fais
> super.paint() il efface tout et me dessine que deux cases.
>
Je ne pense pas que ce soit normal. Il doit y avoir quelque chose
de loupé dans ton code.
paint appelle normalement 3 méthodes, dans je ne sais plus quel
ordre : paintComponent, paintBorder, paintChildren. Il doit y en
avoir une de ces 3 qui te dessine tout en gris. Habituellement on
redéfini paintComponent (duquel il est inutile de faire
super.paintComponent), qui te donne le controle TOTAL de ce que
tu fais à l'écran. Il y aussi moyen de travailler avec le UI deleguate
mais j'ai jamais fait. Et si le paintComponent n'active pas le
UIdeleguate, il n'y a pas de UIDeleguate.
> Le probleme est visible quand je fais 2 C et 2 V pour un M dans mon
> modele MVC
> (http://jphe.dynodns.net/sitejp/Civilisation/civilisation.jsp)
>
Désolé je vais pas aller m'amuser à télécharger 3 Mo de JVM pour
faire plaisir à Sun et à mon Netscape.
> [...]
>
> Oui j'ai un listener sur le JSCrollPane qui redessine tout quand je
> scroll et le JScroll est tres inteligent car il fait un clip sur le
> graphics pour me laisser redessiner qu'une partie et sur ce point ca
> marche
>
Merveilleux tu es plus doué que moi sur le sujet !
> [...]
> Apres des tests hier ce n'est pas le temps de calcul de ce qu'il y a
> afficher qui est lent ni le temps de dessiner des truc dans un offscreen
> mais ce qui est lent c'est le fait de plaquer une grosse image ou
> offscreen a l'ecran
>
S'il n'y a que ça je ne peux malheureusement pas t'aider, je n'ai
aucune idée de la façon dont on optimise ça.
> [...]
> Je fais une sorte de clipping mais surtout je voudrais que mon parent ne
> nettoie pas mon graphics avant de me le donner car sinon cela m'oblige
> de tout redessiner et donc de plaquer une grosse image et donc de faire
> ramer l'affichage
>
Prends les choses à l'envers, et ne fait rien dans ton
paintComponent. S'il se redessine en gris malgré ça, c'est qu'il y a un
composant hostile ailleurs :-))
> [...]
> Il y a peut etre une piste dans le Paint Mode ? ou un moyen de lui dire
> de ne pas exploser l'image precedente
>
Vois peut être le isOpaque qui doit être à false ? (il l'est
normalement).
>
> C'est vrai je chipotte car je dis que ca rame mais c'est en 1600x1200
> :op mais je suis sure qu'on peut mieux faire et j'ai bcp a apprendre en
> dessin sous swing
>
Tu ne chipotes pas du tout, tu as raison. Un affichage rapide et
fluide est essentiel.
--
Sur le Web, tout de suite.
Herve AGNOUX - diaam informatique
http://www.diaam-informatique.com
 |
 |
Jean-Philippe Encausse wrote:
> At 09:36 17/01/2002 +0100, you wrote:
>
>> Le 17 Jan 02, Jean-Philippe Encausse a écrit :
>>
>> > [...]
>> > Pour eviter que ca rame je redessine que ce dont j'ai besoin (2
>> cases) Et
>> > pour eviter que mes composants parent m'explose mon dessin je ne
>> fait pas
>> > de super.paint(g);
>> >
>>
>> Es-tu sûr ? A une époque j'ai dû travailler à optimiser l'affichage
>> swing, et je ne me souviens pas que super.paint faisait des choses
>> particulièrement anormales, ou dispendieuses en temps. Si super.paint
>> prend beaucoup de temps, c'est pour des raisons justifiées, et il faut
>> revoir ton architecture, ton code, ou je sais pas quoi d'autre.
>
>
> super.paint() ne prends pas de temps c'est juste qu'il dessine en gris
> mon panel en gros j'ai un panel avec 50 case j'en redessine a chaque
> fois que 2 mais si je ne fais pas de super.paint() ca marche, si je fais
> super.paint() il efface tout et me dessine que deux cases.
Evite d'hériter de JPanel, utilise plutot un héritage directe de
JComponent, ca evitera je pense ce probleme. Sinon, redefinie la
méthode paintComponent(), pas paint().
Remi
 |
 |
Herve Agnoux et Jean-Philippe Encausse discutent:
>>super.paint() ne prends pas de temps c'est juste qu'il dessine en gris
>>mon panel en gros j'ai un panel avec 50 case j'en redessine a chaque
>>fois que 2 mais si je ne fais pas de super.paint() ca marche, si je fais
>>super.paint() il efface tout et me dessine que deux cases.
Normal, ton composant est par defaut opaque. Soit tu le rends
transparent (setOpaque(false)), soit tu surcharges la methode
update(Graphics _g).
> paint appelle normalement 3 méthodes, dans je ne sais plus quel
> ordre : paintComponent, paintBorder, paintChildren. Il doit y en
> avoir une de ces 3 qui te dessine tout en gris.
Aucune des trois, il s'agit de update();
> Habituellement on
> redéfini paintComponent (duquel il est inutile de faire
> super.paintComponent), qui te donne le controle TOTAL de ce que
> tu fais à l'écran.
Exact. Sauf si on veut controler l'affiche du bord et des enfants.
> Il y aussi moyen de travailler avec le UI deleguate
> mais j'ai jamais fait. Et si le paintComponent n'active pas le
> UIdeleguate, il n'y a pas de UIDeleguate.
Non c'est inutile.
>>Le probleme est visible quand je fais 2 C et 2 V pour un M dans mon
>>modele MVC
>>(http://jphe.dynodns.net/sitejp/Civilisation/civilisation.jsp)
Utilise le clip.
> Désolé je vais pas aller m'amuser à télécharger 3 Mo de JVM pour
> faire plaisir à Sun et à mon Netscape.
Civilisation ;-) est accessible en JNLP. Donc il faut Java Web Start (750K
pour JDK1.3, inclus dans le JDK1.4). Sinon personnellement je supprimerais
les scrollpanes et j'implanterais mon propre defilement lorsque la souris
s'approche des bords (plus ergonomique).
>>Apres des tests hier ce n'est pas le temps de calcul de ce qu'il y a
>>afficher qui est lent ni le temps de dessiner des truc dans un offscreen
>>mais ce qui est lent c'est le fait de plaquer une grosse image ou
>>offscreen a l'ecran
A voir. A mon avis je garderais l'idee du cache et je ne plaquerais que la
portion de l'image correspondant au clip.
>>Je fais une sorte de clipping mais surtout je voudrais que mon parent ne
>>nettoie pas mon graphics avant de me le donner car sinon cela m'oblige
>>de tout redessiner et donc de plaquer une grosse image et donc de faire
>>ramer l'affichage
Voir ci-dessus.
> Prends les choses à l'envers, et ne fait rien dans ton
> paintComponent. S'il se redessine en gris malgré ça, c'est qu'il y a un
> composant hostile ailleurs :-))
Paranoia;-)
>> C'est vrai je chipotte car je dis que ca rame mais c'est en 1600x1200
>> :op mais je suis sure qu'on peut mieux faire et j'ai bcp a apprendre en
>> dessin sous swing
Ca vient a l'usage.
Guillaume