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

AWT/Swing Java Discussion :

Process de rafraichissement d'une interface


Sujet :

AWT/Swing Java

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2009
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 18
    Points : 9
    Points
    9
    Par défaut Process de rafraichissement d'une interface
    Bonjour,

    Ca ne me ressemble pas, mais je reviens m'en remettre à vos compétences, je me suis arraché les cheveux toute la nuit pour essayer de comprendre ce qui ne va pas dans mon code... Il faut croire qu'on ne nous apprend rien en cours... Ou du moins, très mal.

    J'ai un élément d'interface (un JPanel) qui écoute une instance d'une classe de données, un Personnage. Cet élément possède un JTextField lui même écouté par une autre classe, le Contrôleur. Lorsque ce JTextField est modifié (keyReleased()), le controleur demande la modification du personnage, qui à son tour, demande la mise à jour de ses écouteurs (le JPanel, celui-ci met ensuite à jour le texte de plusieurs Label qui lui appartiennent).

    Le process en lui même fonctionne, j'ai bien une mise à jour qui s'effectue, seulement au niveau graphique, je me retrouve avec des choses plutôt étranges. Les Label modifiés ne ressemblent plus à grand chose. J'ai bien essayé un repaint(), mais c'est encore pire, et je n'arrive pas a comprendre pourquoi (lors du repaint, j'ai carrément d'autres éléments qui se retrouvent dédoublés dans un coin du panel). Un revalidate() ne fonctionne pas non plus, il ne change rien.

    Voici mon code, sans le personnage qui n'aurait à mon avis que peu d'intérêt ici, mon évènement étant correctement généré.

    Je peux ajouter une copie d'écran si vous le désirez, merci d'avance, vous pouvez sauver les quelques cheveux qu'il me reste...



    Dernière minute : une idée m'est venue Je me suis dit qu'il y avait certainement quelque chose que je n'avais pas bien compris dans le process de rafraichissement des fenêtres/éléments en JAVA... (il m'a quand même fallu quelques heures...) J'ai donc ajouté, en lieu et place du duo revalidate/repaint, un simple setVisible(false);setVisible(true); ... Et ca fonctionne Ca ne me satisfait pas en revanche pour plusieurs raisons. J'en déduis donc qu'il me manque quelque chose pour effectuer le rafraichissement dans les rêgles du lard. Donc mon nouveau problème : connaissez-vous une bonne documentation sur ce point précis, en français si possible (C'est quand même un peu technique donc... N'allons pas risquer de comprendre de travers ). Ou mieux : quelqu'un aurait quelques minutes a perdre pour m'expliquer ce que j'ai raté? Rien qu'un nom, que je trouve sur google


    Merci ^^

  2. #2
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,

    Pour les composants Swing, il ne faut pas redéfinir paint() mais paintComponent() et ne pas appeler explicitement paintChildren() !

    De même évites de charger l'image dans la méthode de dessin...

    a++

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2009
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 18
    Points : 9
    Points
    9
    Par défaut
    Merci de t'intéresser à mon problème

    J'ai bien noté le soucis du paintComponent(), penses-tu que cela puisse être la cause de l'affichage buggué? Je vais tester.

    Quand à l'appel à paintChildren(), apparemment les enfants sont dessinés avant l'appel à paint(), du coup je ne vois plus aucun composant après avoir dessiné le fond. Je suis donc obligé de les redessiner. Je pourrais me passer de cette façon de faire si je trouvais un autre moyen d'ajouter un fond à mon panel, mais pour l'instant mes recherches ne donnent rien. Que me conseille-tu?


    Edit : après vérification, si j'appelle paintComponent(), je peux effectivement me passer de l'appel a paintChildren(). Toutefois mon problème empire, car même l'appel à setVisible(false);setVisible(true); ne corrige plus l'affichage buggué...

    La meilleure chose à faire serait, comme tu me le conseille, de dessiner mon fond d'une autre manière, seulement je ne vois pas comment... Une piste? (sachant en plus que j'ai plusieurs images qui se chevauchent, dont certaines contiennent des parties transparentes)

  4. #4
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Ximenjun Voir le message
    Edit : après vérification, si j'appelle paintComponent(), je peux effectivement me passer de l'appel a paintChildren(). Toutefois mon problème empire, car même l'appel à setVisible(false);setVisible(true); ne corrige plus l'affichage buggué...
    Disons que je trouve aberrant de devoir faire des setVisible(false/true) !

    Tu dois avoir un autre problème quelque part !

    Maintenant, pour en revenir à ton problème, c'est difficile de t'aider avec si peu de code : on ne sait même pas comment tu ajoutes tes composants au panel !

    a++

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2009
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 18
    Points : 9
    Points
    9
    Par défaut
    Disons que je trouve aberrant de devoir faire des setVisible(false/true) !
    C'est sur et comme je l'ai dit, ca ne me satisfait pas, mais dans une optique de debug ca a le mérite de marcher et de montrer que quelque chose change entre les deux méthodes.

    J'édite mon premier post pour ajouter le code restant. J'ai quand même volontairement réduit le tout, je peux tout mettre si tu le souhaite mais ca va faire lourd...

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2009
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 18
    Points : 9
    Points
    9
    Par défaut
    J'ai résolu mon problème en effectuant mes repaint() sur ma JFrame plutot que sur chaque composants, indépendamment. J'ai quand même du mal à comprendre pourquoi, lorsque j'apelle repaint() sur un de mes panel, il dessine son fond et y ajoute le fond d'autres panels qui ne lui appartiennent pas (panels de même niveau dans ma JFrame). Y'a-t-il une rêgle en swing qui stipule de n'appeller repaint() que pour le composant principal?

    Je ne met pas le TAG résolu pour l'instant, n'ayant pas encore trouvé de réponse à ce problème...

  7. #7
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    en appelant repaint, tu fais redessiner le composant et tous ses fils. Frocément si tu le fait sur la fenetre, ut va redessiner toute la fenetre. Cependant, tu ne devrais pas avoir besoin d'appeler repaint() explicitement. Un appel à invalidate() devrais suffire (bien que la pluspart des composant le fassent d'eu meme).

    Comme on a pas la partie principale:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Personnage.setMsSlotUp()
    Difficile de dire ce qui coince.

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2009
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 18
    Points : 9
    Points
    9
    Par défaut
    J'ai ajouté la classe Personnage ainsi que l'interface écouteurs et l'événement associé. Mais je ne pense pas (je me trompe sans doute ^^) que ca vienne de la.

    Et mon problème est vraiment général, toute l'interface a besoin d'être redessinée explicitement dès qu'un élément bouge un peu. (clic sur une liste déroulante par exemple, sinon j'ai droit a un beau carré gris après avoir selectionné mon item). A noter qu'il n'y a pas toute l'interface ici... Ma JInterface contient deux autres panels qui dessinent également leur fond.

    J'ai vraiment l'impression que ca vient de cette saleté de dessin... En tout cas merci de t'intéresser à mon cas tchize_

  9. #9
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Pour etre notifie des modifications d'un JTextField il faut mettre un DocumentListener sur son Document. Pour etre notifier des modifications d'un JFormattedTextField, il faut mettre un PropertyChangeListener sur sa propriete "value".

    S'il y a des trucs dedoubles ou des erreurs graphique, generalement, cela vient du fait que le composant ne peint pas entierement sa surface rectangulaire (soit en faisant un fillRect() soit en faisant un super.paintComponent()) alors que son isOpaque() return true, ce qui pour Swing est contradictoire et peut mener a ce genre d'abherations graphiques.
    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

  10. #10
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2009
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 18
    Points : 9
    Points
    9
    Par défaut
    Bonjour bouye et merci de venir me donner un coup de main

    Merci pour le DocumentListener, ca va me faciliter la vie.

    J'ai bien une erreur qui ressemble fort à ce que tu décris.

    avant mise à jour le JTextField :


    après mise à jour du JTextField :


    sur la seconde en revanche c'est un peu différent, le fond du JPanel ne se redessine pas après avoir fait un choix dans la liste déroulante :

    avant choix :


    après choix :





    Pourtant j'ai beau chercher, je vois pas ce que je fais de si terrible

    A part les images de fond, j'ai toujours codé comme ca, et ca a toujours fonctionné... Je vois vraiment que ca qui pourrait vraiment "clocher". Vous avez pas une idée sur un autre moyen de procéder?



    Edit : Toutes ces erreurs d'affichage sont corrigées si je fais un repaint() de ma JFrame après l'évènement déclencheur...

  11. #11
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Jolie interface pour Aion, j'aurais du faire des trucs équivalent pour Guild Wars il y a qq années

    La règle est :

    - si un composant utilise une couleur (ou peinture) de fond transparent (alpha = [0-1[) alors isOpaque() doit retourner false.

    - si un composant ne peint pas entièrement sa boite englobante rectangulaire alors isOpaque() doit retourner false.

    - si un composant peint entièrement sa surface rectangulaire avec une couleur (ou peinture) opaque (alpha = 1) alors isOpaque() peut retourner true (normalement le rendu est sensé être plus rapide que quand ça retourne false car Swing ne perd pas de temps à peindre les choses qui pourraient se trouver derrière le composant).

    Par défaut, hormis JComponent, JLabel et peut-être JButton, la plupart des composants Swing peignent entièrement leur boite englobante rectangulaire avec une couleur opaque et ont un isOpaque() qui retourne true.

    Vérifie bien tes méthodes de rendu et si besoin fait un setOpaque(false) dans le constructeur de la classe ou à l'initialisation de l'objet en question.
    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

  12. #12
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Concernant le décallage... hum ca sent le translate() (resp transformation affine) sur un Graphics sans faire un translate() opposé (resp transformation affine inverse) une fois le rendu fait.
    Genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    @Override
    protected void paintComponent(Graphics g) {
       g.translate(x, y);
       [...]
       // Il manque le translate inverse !!!!!
       //g.translate(-x, -y);
    }
    Un moyen d'éviter des oublis de ce genre est de faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    @Override
    protected void paintComponent(Graphics g) {
       Graphics2D g2d = (Graphics2D)g.create();
       try {
         g2d.translate(x, y);
         // On dessine sur g2d.
         [...]
       }
       finally {
         g2d.dispose();
       }
    }
    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

  13. #13
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2009
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 18
    Points : 9
    Points
    9
    Par défaut
    Citation Envoyé par bouye Voir le message
    Jolie interface pour Aion, j'aurais du faire des trucs équivalent pour Guild Wars il y a qq années
    Merci Ca serait mieux si elle était correctement codée ^^



    Arghhh... Après vérification, en effet ca n'était que 2 setOpaque que j'avais du oublier dans mon empressement...

    Merci merci merci Je vais m'auto-flageller sur le champs pour mon incompétence


    Encore merci d'avoir perdu de votre temps pour m'aider


    Edit : Bien joué pour les translate, j'ai aussi oublié de les inverser. En revanche le bug de translation persiste malgré la correction (des translate hein, tout marche nickel avec les setOpaque() ^^). Je vais continuer a tester voir si j'ai quand même pas une autre erreur de ce coté-ci.

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

Discussions similaires

  1. Problème de rafraichissement d'une interface SWT
    Par franckB dans le forum SWT/JFace
    Réponses: 2
    Dernier message: 20/02/2008, 15h43
  2. Comment faire une interface de ce type....
    Par SpiderAlpha dans le forum C++Builder
    Réponses: 6
    Dernier message: 30/04/2007, 13h50
  3. Comment créé une "interface" pour mes programmes??
    Par alcazar dans le forum Autres éditeurs
    Réponses: 5
    Dernier message: 09/02/2004, 13h02
  4. [MFC] probleme de rafraichissement d'une image
    Par Vestaproman dans le forum MFC
    Réponses: 6
    Dernier message: 09/01/2004, 23h59
  5. portabilité d'une interface
    Par marou dans le forum JBuilder
    Réponses: 4
    Dernier message: 21/03/2003, 08h53

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