Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Résolu] Problème d'affichage / repaint() de JPanel

    2 février 2009 à 1:15:28

    Tout d'abord,
    Bonjour / Bonsoir à tous les Zéros !

    C'est mon premier message sur ce :beaucoup de superlatifs: site,
    que j'ai déjà visité à moultes reprises, et qui, pour faire dans l'originalité,
    m'a appris de nombreuses choses et aidé à de nombreuses reprises !

    Enfin, je vais arrêter la pour le lançage de fleurs, car vous devez y être habitué ^^
    Et vais aborder le fameux problème qui m'amène ici... :-°

    ...

    Je suis en deuxième année d'IUT Informatique (à Montpellier), et ai pour projet de fin de semestre
    le développement en Java d'un jeu Othello implantant l'algorithme min/max pour l'Intelligence Artificielle.

    Si certains ne connaissent pas ce jeu, qui est très simple à comprendre,
    voici un lien avec quelques explications ( moins d'une minute devrait vous suffir ^^ ) :
    => http://www.ffothello.org/jeu/regles.php

    Toute la structure d'une partie, c'est a dire le bon déroulement des tours de jeu, est en place.
    L'interface graphique est aussi en place : une JFrame avec un JPanel, rempli de JButton! ( 64 pour le plateau de jeu )
    => Le processus principal et la fenêtre sont éxécutés dans deux tâches différentes.

    Voici un screen de ma fenêtre lors du premier tour :
    ( en bleu les cases jouables )

    Image utilisateur


    ...


    Pour une meilleure compréhension,
    je vous décris le déroulement d'un tour de jeu dans mon programme :


    ... 1- Tout d'abord, le programme calcule les cases étant jouables, et les affiche au joueur.
    ... ... => Envoi du nouveau plateau a afficher au panneau de la fenêtre.
    ... 2- Ensuite, il attend qu'un coup soit joué. ( il se bloque devant une CyclicBarrier, initialement à 2, et qu'il met 1. )
    ... 3- Une fois le coup joué, la barrière s'ouvre, le processus principal en récupère les coordonnées, et les inscris dans le plateau.
    ... 4- Une fonction détermine ensuite les cases "prises en sandwich" / "à retourner", et modifie le plateau.
    ... 5- Puis le programme affiche le nouveau plateau de jeu, avant de passer au tour suivant.
    ... ... => Nouvel envoi du nouveau plateau au panneau.


    Par "Envoi du nouveau plateau", j'appelle une méthode "affectation", qui est une sorte de second constructeur du panneau,
    et qui met à jour les données partagées par le panneau et la Partie, et fais un repaint() du panneau.
    => Dans ces données, il y a principalement le plateau, qui doit être réaffiché avec le repaint().
    ( ré-Affichage des 64 cases, qui sont des JButton )

    ...

    Mon problème est le suivant :


    - Lorsque c'est au premier tour, le processus principal calcule les coups jouables (pour le joueur blanc),
    les envoie au panneau qui se charge de les afficher, puis attend devant la barriere que le coup soit joué.
    ===> La réactualisation du panneau marche, comme vous pouvez le voir avec le screen. (affichage des cases jouables en bleu )

    - Dès que je clique sur une de ces cases jouables, celle ci se redessine avec la couleur du joueur, puis réveille le processus principal, et y envoie ses coordonnées. Le processus principal récupère ses coordonnées, les traite parfaitement... ( phases 3 et 4 )
    ==> Des test d'affichage en console montrent que le plateau est correctement à jour.

    - Mais, a la phase 5, à l'envoi de ce nouveau plateau, et malgré le repaint(), le panneau ne se réactualise pas...
    Et la fenetre affiche seulement l'ancien panneau (avec les cases jouables) et la case jouée qui s'est autoactualisée elle même.
    ( Hum... Je pense que certains vont commencer à se poser des questions sur ma méthodes de "repaintage" x-) )


    Plateau affiché après le clic sur la case que l'on souhaite jouer :
    ( la case noire prise en sandwich en [4][5] devrait être blanche, ce qu'elle est en console )

    Tour 1 - Cases Jouables pour le Blanc

    ...


    Mon souhait est donc simple :
    => Arriver à réactualiser mon panneau, avec les nouvelles informations de fin de tour !


    Précisions:

    - Comme dit au début, j'utilise deux tâches différentes pour la Partie et la fenêtre, synchronisées avec une CyclicBarrier (init à 2).
    ==> Mais il y a peut être un foirage dans leur utilisation... ? :-/

    - Quand je ne donne pas les coordonnées des coups avec l'interface graphique ( j'écris pour chaque tour les coordonnées dans le code ),
    => Tout se passe parfaitement ! Par ex, si je stoppe ma boucle de jeu au tour n°7, le panneau m'affiche le plateau comme il devrait être.
    ===> Par contre, si j'essaie de mettre un 'Thread.sleep()' de deux secondes a la fin de chaque tour, cela replante identiquement.



    ...


    Voila donc en gros mon problème...
    Dont je ne sais s'il est graphique ou 'synchronisationnel', ou bien même peut être les deux, ou encore moulte autre chose... ! ( o_O )
    J'ai testé des 'panneau.revalidate()' ou 'panneau.validate()' dans ma méthode 'affectation()', mais rien de plus...

    Je sais que ce message est un beau paté, mais j'essaie d'être clair pour vous faciliter la chose.. ( ou pas :o ) Mais cela fait en deux jours facilement 15h que je bute sur ce problème, en tentant le peu de choses que mes modestes compétences me permettent, et arpentant the Internet a la recherche de quelque chose.. Et je n'ai pour l'instant obtenu qu'un bon, beau, gros, frais, fort, nature... Pwet :-/

    ...

    Pour le code source entier, si des généreux et courageux seraient tentés de s'y aventurer,
    je l'ai mis à disposition à dans un dossier à dézipper, en format "projet" de Eclipse. ( Juste à importer )
    => http://www.megaupload.com/fr/?d=1VP243BS

    Je suis complètement partisan du "débrouilles toi avec ta besogne, on va pas te faire ton logiciel non plus !",
    mais si cela peut vous permettre d'y voir plus clair dans le comment j'ai fait ma merde, alors et bien c'est avec plaisir : -)
    ( Le code est normalement "bien" commenté et lisible, vous devriez vous en sortir )

    ...

    Voila voila... Pouf, allez je vais stopper ce message là.
    Et remercie d'avance toutes personnes qui auront eu le courage d'arriver jusqu'ici, et qui essaieront de m'aider. :)
    Je reste bien sûr au taquet réactif à quelconque question, ou demande de précisions !

    En vous souhaitant une Bonne fin de soirée, nuit, réveil !
    Bien Zéroment, NonoMoreno.


    P.S: Ah oui, précision comme ça... J'ai la soutenance de ce projet Mercredi matin à 9h.
    Et .. Bin si je peux avoir quelques conseils avant, ça m'arrangerait on va dire.. ^^
    ( Pas chiant le type... x-/ )
    • Partager sur Facebook
    • Partager sur Twitter
      2 février 2009 à 6:53:45

      Déja pour reactualiser ton panneau avec de nouveau paramatres tu n'a qu'a mettre une variable static qui passe a true si tu a atteind la fin et dans ta methode repaint, tu teste si cette variable est vrai pour appliquer la methode de repaint.
      • Partager sur Facebook
      • Partager sur Twitter
      J'ai tous les badges d'OpenClassrooms.
        2 février 2009 à 11:34:16

        bon je n'ai pas tout lut :p
        mais en général quand il y'a des problèmes de ré actualisation c'est souvent la même chose :p
        bref :)
        je pense que le probleme peut venir du faite que le thread principale est utilisé (par un sleep ou par une boucle sans fin c'est pareil)
        repaint() indique qu'il va falloir repeindre :)
        swing attend que le thread principale aie finis tous ses calcules avant de repeindre :)
        donc essaye de lancer tous les calcules dans un sous thread (et laisse tj le thread principale libre :o

        :o
        • Partager sur Facebook
        • Partager sur Twitter
          3 février 2009 à 5:00:12

          Du nouveau... !

          Finalement, j'ai suivi le conseil d'une personne sur un autre fofo, et ai opté pour un modèle événementiel au lieu de mon ancien modèle "synchronisationnel foireux"... Et... Ca marche !

          Après, j'ai quand même voulu re-essayer avec mon ancien modèle...
          Et ca marche aussi maintenant ! :o

          La raison...?


          ...

          => A chaque repaint(), mes nouveaux composants s'affichaient * en dessous * des anciens. o_O

          ...


          Allez, j'importe java.util.zenToolkit et je n'essaie pas de comprendre...
          En oubliant la trentaine d'heure passée sur un problème qu'un simple removeAll() a résolu avant chaque repaint()...

          Donc voila. Maintenant je vais pouvoir attaquer mon IA, qui, soyons fou, j'espère sera prête pour ma soutenance demain 9h :D
          Et merci beaucoup quand même a willard et Snooooopy pour votre aide ! : -)
          J'avais testé vos propositions, bien que malheureu-logiquement cela n'avait rien changé...

          Encore merci, et surement à une prochaine sur ce forum : -) !
          Bien Zéroment, NonoMoreno !
          • Partager sur Facebook
          • Partager sur Twitter

          [Résolu] Problème d'affichage / repaint() de JPanel

          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
          • Editeur
          • Markdown