Swing et le double-buffering. - Java - Programmation
Marsh Posté le 22-05-2004 à 13:10:50
Bon alors, les soit-disant pro en java ? Y en a pas un seul qui connait ca ?
Marsh Posté le 22-05-2004 à 13:55:33
amauryxiv a écrit : Bon alors, les soit-disant pro en java ? Y en a pas un seul qui connait ca ? |
peut-être un problème de motivation pour te répondre ...
Marsh Posté le 22-05-2004 à 13:56:54
nraynaud a écrit : peut-être un problème de motivation pour te répondre ... |
Et pourquoi ma question motiverait moins qu'une autre ?
Marsh Posté le 22-05-2004 à 14:03:16
bof, le newbies qui ont un pb, mais prétendent déjà savoir où il n'est pas ça ne m'engage pas.
Et puis s'intéresser à un détail d'implémentation plutôt qu'à la recherche du bug, ça sent le sujet pas hyper-passionnant.
Enfin, le double-buffering de swing n'a aucun intérêt particulier, donc une éventuelle discussion là-dessus n'apporterait pas grand-choses aux autres.
si vraiment tu crois avoir trouvé un bug dans ce code, va le chercher sur la bugparade de java.
Marsh Posté le 22-05-2004 à 14:03:23
amauryxiv a écrit : Et pourquoi ma question motiverait moins qu'une autre ? |
deja parce qu'on est samedi. Il faut savoir que la plupart des gens postent dans cette categorie pour éviter de bosser quand ils sont au taf.
Ensuite, tu as mal lu :
Citation : Swing's double buffer mechanism uses a single offscreen buffer per containment hierarchy (usually per top-level window) |
Il y a donc un buffer par ensemble de composants qui ont un lien de parenté.
Citation : And although this property can be set on a per-component basis, the result of setting it on a particular container will have the effect of causing all lightweight components underneath that container to be rendered into the offscreen buffer, regardless of their individual "doubleBuffered" property values. |
Deja la propriétés dont il parlent, c'est le booleen qui decide si le composant est oui ou non double-buffered, ils ne parlent pas du buffer lui-même.
Ensuite c'est clairement dit que si un container est double-buffered, tous ses descendants le seront, quoique tu leur dise.
Marsh Posté le 22-05-2004 à 14:08:05
Et ben voila j'en demandait pas plus ! Chuis une burne en anglais et pour moi les docs c'est pas tres clair.
Donc merci de bien vouloir m'expliquer ......
Marsh Posté le 22-05-2004 à 14:09:48
nraynaud a écrit : bof, le newbies qui ont un pb, mais prétendent déjà savoir où il n'est pas ça ne m'engage pas. |
Ca va les chevilles ? Excuse moi mais t'as pas l'air de comprendre beaucoup mieux que moi. Donc avant de qualifier quelqu'un de newbie et de te prendre pour un pro tourne sept fois ta langue dans ta bouche !
Marsh Posté le 22-05-2004 à 14:13:24
nraynaud a écrit : bof, le newbies qui ont un pb, mais prétendent déjà savoir où il n'est pas ça ne m'engage pas. |
Et puis t'as pas bien compris ma demarche. J'ai jamais pretendu avoir trouve un bug dans le JDK (ché pas d'ou tu sors ca). Seulement vu la gueule du bug dans mon programme, il peut venir que de quelque chose que deux panels qui ont un parent en commun partagent. Partant de la ya des chances que ce soit en rapport avec le buffer. Donc ca veut dire que j'ai mal exploite le double-buffering. Et pour bien l'exploiter j'ai besoin de savoir comment ca marche.
C'est tout.
Marsh Posté le 22-05-2004 à 14:46:41
amauryxiv a écrit : Ca va les chevilles ? Excuse moi mais t'as pas l'air de comprendre beaucoup mieux que moi. |
t'inquiètes pas pour moi va. Le double-buffering semble me poser moins de problèmes qu'à toi, c'est embêtant pour un système sensé être invisible.
Marsh Posté le 22-05-2004 à 14:57:26
nraynaud a écrit : t'inquiètes pas pour moi va. Le double-buffering semble me poser moins de problèmes qu'à toi, c'est embêtant pour un système sensé être invisible. |
De deux choses l'une: soit t'es aussi malin que tu le dis et tu devrais avoir des trucs a m'apprendre (ce que tu 'as pas fait jusqu'a present)soit tu devrauis peut-etre faire preuve d'un peu plus de modestie et prendre au serieux les idees de ceux que tu qualifie de "newbie".
Marsh Posté le 22-05-2004 à 15:11:45
amauryxiv a écrit : tu devrais avoir des trucs a m'apprendre (ce que tu 'as pas fait jusqu'a present) |
nraynaud a écrit : J'ai trouvé le bug |
(tu n'as manifestement rien compris à ça, ton post suivant le prouvant)
nraynaud a écrit : non, pas en swing. |
(tu es resté sur ton idée à la con)
amauryxiv a écrit : Ba h peu importe c'est pas important et c'est pas ca qui fait foirer le truc ........ |
(tu es incapable de trouver le bug, mais tu sais déjà où il n'est pas, tu appelles paint() de 2 taches différentes, tu a un bug, et tu prétends que le pb ne *peut pas* venir de là)
C'est pourquoi il ne reste qu'une seule attitude possible : t'envoyer te faire foutre.
edit : être un noob, ça n'a rien de mal, quand je prends mon petit tuto pour installer tomcat, je suis un noob de la chose. Par contre, j'envoie pas chier les gens quand j'ai un pb avec tomcat.
Marsh Posté le 22-05-2004 à 15:12:29
je serais toi je titillerai pas nraynaud là dessus : c une grosse brute en java...en plus si tu le titille trop il risque de te ramener les furieux de blabla@prog et ca va te pourrir ton topic...
Il répond toujours sur un ton bourru mais il est comme ça, il est pas méchant en fait...
--> l'anglais de la javadoc est d'une simplicité déconcertante...faut vraiment te mettre à l'anglais, parce que programmer en java sans comprendre la javadoc, c comme piloter un avion qui fonce sur une falaise sans avoir le mode d'emploi du manche à balai...
Si toutefois la javadoc t'effraie à ce point, je me permet de te recommander Java in a Nutshell aux éditions O'reilly, qui malgré son titre se trouve en français (la nouvelle version a une couverture écrite en rouge)...en gros c une bible de java, qui explique pendant 200 pages les fonctionnements du langage, puis ensuite pendant les 1000 pages restante, te présente les classes un peu comme la javadoc...en général les gens l'aiment moyen vu que c une repompe de la javadoc, mais bon...
Marsh Posté le 22-05-2004 à 17:14:18
Pas la peine de t'ennerver a ce point.
Je suis tout a fait d'accord pour dire que le probleme est lie au fait que j'appelle paint de deux thread differents. J'ai jamais dit le contraire. Seulement c'est pas ca que tu m'as reprocher dans tes precedents posts.
J'ai bien essye de lire "la regle". Seulement comme je l'ai deja dit, j'ai beaucoup de mal avec l'anglais, aussi simple qu'il soit.
Puisque visiblement t'as l'air de bien connaitre tu pourrais faire quelques suggestions !
Je sais bien qu'apres avoir mosifie un modele il faut le signaler pour que la vue soit mise a jour. Seulement avec le fonctionnement de swing, qui met a jour la vue dans un autre thread que celui qui modifie le modele, la mise a jour de la vue prends du retart sur les modifications du modele (qui dans mon programme sont extremement frequentes, puisqu'elles correspondent au mouvements de mes personnages).
Alors qu'est ce que je dois faire ? Utiliser InvokeAndWait() ? Qqchose du genre ?
P.S. : avant d'envoyer les gens se faire foutre, assure toi qu'il n'y a pas eu de quiproquo ou de malentendu.
Marsh Posté le 22-05-2004 à 17:20:10
Jubijub a écrit : je serais toi je titillerai pas nraynaud là dessus : c une grosse brute en java...en plus si tu le titille trop il risque de te ramener les furieux de blabla@prog et ca va te pourrir ton topic... |
Je te remercie de tes bons conseils. Je veux bien croire que nraynaud soit tres fort en java, mais quand meme, ca autorise pas tout. Moi quand je reponds a des questions, j'essaie de donner des suggestios sur ce que l'on peut faire. Je renvoie pas simplement a une doc.
Et je permets de dire a personne que sa question est ininterressante.
Enfin bref passons ...
Marsh Posté le 22-05-2004 à 20:33:17
amauryxiv a écrit : |
j'ai fait 3 tentatives quand même.
Bon maintenant qu'on est sur des bonnes bases, on va voir.
Les "modèles" de swing doivent vivre au rythme de swing, donc n'être modifiés que dans le thread de répartition des évènements swing (listeners de souris par exemple) ou dans le cadre d'un invokeLater() ou dans le cadre d'un invokeAndWait().
Ceci pour une raison simple : le modèle va être lu pour faire de la peinture, hors il faut que les données ne se modifient pas pendant tout le temps de peinture. Par exemple, valider une JList consiste (schématiquement) à lire la longueur de la liste, calculer avec le renderer la taille du rectangle que ça représente, regarder si ça change le layout, si oui, refaire tout le layout. Si entre le moment où j'ai calculé le nouveau layout et le moment où je vais peindre chaque case, le nombre d'éléments a changé, je vais dans le mur.
On va donc communiquer avec le thread de répartition des évènements swing par une file de messages, et c'est ce thread-là qui fera les modifications à un moment où ça ne mettra pas la zone dans le système.
Pour ça, il y a plusieurs méthodes :
- envoyer un évènement swing (enfin awt, la package a été rétrofité). Je sais pas comment on fait, et java.sun.com semble en vrac chez moi.
- utiliser SwingUtilities.invokeLater(), qui consiste à insérer un Runnable dans la file, il sera exécuté une seule fois à un moment où il n'y a aucun risque
- utiliser SwingUtilities.invokeAndWait(), qui va insérer un Runnable dans la file, mais bloquer le thread appelant jusqu'à la fin de l'exécution de run() du runnable passé en paramètre.
A noter une exception notable au principe de du thread unique : les méthodes de modification du texte dans les JTextComponent (en réalité, c'est AbstractDocument qui implémente un locking) peuvent être appellées depuis n'importe quel thread. Si c'est vrai !
Dans ton cas, mon conseil est bien entendu de créer ton propre composant, qui aura son propre modèle associé. Le modèle variera à intervalles réguliers en fonction de l'horloge, et préviendra le composant en face.
Le rattrapage se fera avec invokeLater ou invokeAndWait au niveau de la notification du composant, je sais pas trop lequel est le plus indiqué dans ce cas. Peut-être qu'en testant un des 2 sera pire que l'autre.
Marsh Posté le 22-05-2004 à 21:26:55
Mouais pas tres clair pour moi tout ca.
Pour l'instant j'ai mis tous mes appels à paintImmediatly() dans des invokeAndWait(). Comme ca ils sont bien executes par l'event dispatch thread.
Ca resoud le petit bug dans l'affichage du score (ou des personnages apparaissaient en haut a gauche).
Par contre, quand pour les éléments du tableau (les fruits) je mets des gifs animes, alors la tout part en couille. Des interferences reappariassent et le jeu s'arrete brutalement au bout de quelques secondes.
Donc dans l'etat actuel des choses, chaque timer modifie mon modele et appelle un invokeLater() pour repeindre, et ces deux choses sont faites l'une apres l'autre dans le meme thread. De plus, deux personnages ne peuvent pas etre repeints en meme temps.
Je suppose, que c'est pas encore ce qu'il faut puisque je peux pas mettre de gifs animes. Je posterai bientot le code qui sert au dessin.
Marsh Posté le 22-05-2004 à 21:35:00
donne tout, parce que sans eclipse pour naviguer dans le, c'est la galère.
Marsh Posté le 22-05-2004 à 22:19:31
Ma classe principale:
Code :
|
La classe Tableau:
Code :
|
La classe Drawable, dont heritent tous les elements du tableau:
Code :
|
La classe Personnage dont heritent Pacman et Fantome:
Code :
|
Voila. Je crois qu'il y a l'ssentiel de ce qu'il faut. Le methode move() de chaque personnage est declenchee par un timer et modifie l'emplacement ou doit etre dessine le personnage (variable pixel dans la classe Drawable), puis decleche le redessin en appelant repeindre().
Marsh Posté le 22-05-2004 à 23:26:17
je capte pas le rôle de surfaceARepeindre.
j'ai comme l'impression que tu n'as pas tout donné.
pourquoi faire de la peinture sur des JPanels au lieu de faire ton propre JComponent ?
Il faudrait mettre ses minimumSize, maximumSize et preferedSize à la même valeur, pour bloquer tout.
tu peux m'envoyer une copie d'écran des défaut par mail (hfr@nraynaud.com) ? je posterai la chose ici en l'hébergeant chez moi. Mais ça aiderait probablement pour y voir clair sur ce bug. As-tu la garantie que le score n'est pas modifié pendant la peinture ?
Tu as parlé de timers, je les vois pas.
la doc dit que paint() c'est mieux que paintImmediately(), qu'est-ce qui rend obligatoire cette dernière ? et pourquoi pas plutôt repaint(), puisqu'il est précisé qu'on ne doit pas utiliser paint() dans la javadoc.
edit : bordel de touchpad.
Marsh Posté le 22-05-2004 à 23:32:08
on verra après pour les gifs annimés, mais on va procéder par étape.
Marsh Posté le 22-05-2004 à 23:36:36
- surfaceARepeindre je pourrais m'en passer. Ca sert seulement a connaitre le petit rectangle qu'il y a a rafrachir. Donc ca evite d'appeler super.paintComponent() sur mon PanelTableau, qui repeint tout le fond en noir, ce qui prend du temps.
- Ben Jpanel ou JComponent je sais pas si ca change grand chose. En tout cas je vois pas ce qu'on perd en prenant un JPanel.
- Les timers je les ai pas mis, c'est sans interet. C'est tous des timers de type java.util.Timer.
- J'appelle paintImmediatly a la place de paint parce que ca m'evite d'avoir a generer l'objet Graphics. Et j'utilise pas repaint() parce que repaint utilise invokeLater() et la peinture se fait alors trop tard.
- pour les copies d'ecran je vais essayer.
Marsh Posté le 22-05-2004 à 23:46:48
fait péter les timertask (et ce qui va avec pour les comprendre) quand même stp.
Je suis *très* perplexe par rapport à repaint(), voire même je subodore un candidat au bug graphique, il faudrait vérifier par rapport aux trains d'évènements, mais j'en ai pas les moyens. Tu as le bug d'affichage avec repaint() ?
Marsh Posté le 22-05-2004 à 23:51:30
- Voila les timers:
Code :
|
- Pour repaint: quand j'utilise repaint(), c'est un autre bug qui apparait. Quand j'utilise repaint(), les timers bougent les personnages pendant la peinture et ca laisse place a pas mal de bug, surout sur des machines pas puissantes.
Marsh Posté le 22-05-2004 à 23:56:08
concernant les timer > c'est la cata.
repaint > ça c'est un problème dans ta conception, c'est exactement ce dont je parlais dans mon paté au-dessus, ton modèle swing est modifié pendant la peinture. c'est à ça qu'il faut que tu t'attaques.
Marsh Posté le 22-05-2004 à 23:59:17
nraynaud a écrit : concernant les timer > c'est la cata. |
- Qu'est ce qu'y zont mes timers ? Ya rien de plus simple !
- mon modele est modifie pendant la peinture si j'appelle repaint, mais pas dans l'etat actuel de mon code.
Marsh Posté le 23-05-2004 à 00:06:16
si j'ai bien compris, ton code ne fonctionne pas dans l'état actuel non plus, on en serait pas là sinon.
Sauf que dans l'état actuel, y'a personne pour t'aider car il n'y a aucune doc sur l'utilisation de paint() n'importe où.
Sachant que tu peux avoir des problèmes de lenteur (ça arrive en temps réel) on peut régler les pb d'optimisation.
Marsh Posté le 23-05-2004 à 00:08:34
Ben y fonctionne qu'en partie. Y merde que quand je mets des gifs animes pour les fruits. Tant que c'est des images statiques tout marche.
Sur ce je m'en tiendrai la pour ce soir: il se fait tard.
Merci de ton aide, et bonne nuit !
Marsh Posté le 23-05-2004 à 00:47:58
concernant les Timers :
on ne créé qu'un seul timer pour toute l'application et on lui fait exécuter tous les TimerTasks qu'on veut, mais on ne créé pas des dizaines de Timers, ça bouffe une tonne de ressources. D'autre part, les Timers utilisent en interne un algo de ouf (un tas binaire) pour pouvoir, justement, gérer un très grand nombre de taches.
Marsh Posté le 23-05-2004 à 12:42:14
Ouais mais alors avec un seil Timer, comment tu effectue plusieurs tache a des frzequences differentes ???
Marsh Posté le 23-05-2004 à 13:12:23
Code :
|
pas de problème.
Marsh Posté le 23-05-2004 à 15:45:23
Ouais mais a ce moment la tu peux plus arreter qu'une seule tache. C'est toutes ou rien.
Bref je pourrais economiser quelques Timers, c'est vrai, mais c'est pas ca qui fait merder mon programme ....
Marsh Posté le 23-05-2004 à 15:49:37
amauryxiv a écrit : Ouais mais a ce moment la tu peux plus arreter qu'une seule tache. C'est toutes ou rien. |
http://java.sun.com/j2se/1.4.2/doc [...] l#cancel()
bon, je commence à croire que j'avais eu raison de t'envoyer chier, je ne sais combien de pavés pour en arriver à "c'est pas ça qui fait merder mon programme" alors que je t'ai montré une erreur majeure dedans.
Marsh Posté le 23-05-2004 à 16:06:33
Ben je suis navre, mais si je concoit que ma facon de faire avec les timers soit tres loin de qqchose d'optimisé, moi je vois pas de rapport avec des problemes qui concernent swing; et si y en a un t'as qu'a l'expliquer, au moins ca sera clair.
Maintenant si ca te saoule de me repondre t'es pas oblige. Je pase volontier qu'on m'envoie chier.
Marsh Posté le 23-05-2004 à 16:16:05
amauryxiv a écrit : Ben je suis navre, mais si je concoit que ma facon de faire avec les timers soit tres loin de qqchose d'optimisé, moi je vois pas de rapport avec des problemes qui concernent swing; et si y en a un t'as qu'a l'expliquer, au moins ca sera clair. |
Je parle de repaint() .
Le problème c'est les gros nazes qui font du java, y'en a partout et après j'entends tout le temps "java sapu c'est lent et ça bugge" alors je tente d'éduquer un peu les gens à faire du java correct. D'autant plus que ne pas savoir lire le manuel n'est pas un frein professionnellement, et avec l'accélération de l'informatisation de la vie quotidienne, j'aimerais bien qu'un de ces gros nazes ne me tue pas par ses bugs à la con et sa désinvolture.
Marsh Posté le 23-05-2004 à 20:05:07
Ecoute mon pote ché pas si t'as vu la gueule de mon programme, mais je le fais pour m'amuser moi. Chuis pas au boulot tu vois.
Alors si ta seule intention c'est de me prendre sur ce ton la tu peux te casser, je me passerai de toi.
Moi les je-sais-tout je m'en fous. Et si tu veux pas que je te dise des trucs que tu trouves cons t'as qu'a etre clair dans tes reponses.
Maintenant tu peux te casser, je t'ai assez entendu. Et compte pas sur moi pour "m'eduquer an java" en ecoutant un con dans ton genre.
Marsh Posté le 23-05-2004 à 21:06:00
amauryxiv a écrit : Ecoute mon pote ché pas si t'as vu la gueule de mon programme, mais je le fais pour m'amuser moi. Chuis pas au boulot tu vois. |
on m'y reprendra à pas envoyer chier le boulets tiens !
Marsh Posté le 23-05-2004 à 21:37:39
amauryxiv a écrit : Ecoute mon pote ché pas si t'as vu la gueule de mon programme, mais je le fais pour m'amuser moi. Chuis pas au boulot tu vois. |
nraynaud reste ici ! toi par contre, t'auras tout le temps de lire les règles du forum !
Marsh Posté le 23-05-2004 à 23:40:51
Reply
Marsh Posté le 21-05-2004 à 16:39:53
Salut a tous.
Pour ceux qui ne m'ont pas deja lu, j'essaie de faire un jeu sous swing.
(cf http://amauryxiv.no-ip.info:8080/pacman/pacman.htm quand mon serveur est en route).
J'essaie de comprendre le mecanisme de rafraichissement et d'affichage des composants swing.
Et ce que je ne comprends pas c'est comment marche le double-buffering. A cause de lui, j'ai plein de bugs quand j'essaie de faire certaines choses.
Sur la doc, (http://java.sun.com/products/jfc/t [...] html#swing) ils disent qu'on peut faire en sorte qu'il y ait un buffer par composant. Mais dans le javadoc, ils disent le contraire.
Est ce que quelqu'un aurait des précisions à m'apporter ?
Merci d'avance.
Message édité par amauryxiv le 21-05-2004 à 18:51:38
---------------
Amaury.