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

Composants Java Discussion :

[swing] Créer un composant héritant de JComponent et ayant un comportement "natif"


Sujet :

Composants Java

  1. #1
    Invité
    Invité(e)
    Par défaut [swing] Créer un composant héritant de JComponent et ayant un comportement "natif"
    Bonjour à toute la communauté Developpez !
    Si je viens ici c'est que j'ai un problème depuis plusieurs semaines et que je n'arrive pas à le résoudre, je ne trouve rien sur le net qui répond à ma question.

    Pour les besoins d'un projet scolaire, un jeu en l'occurence, je suis chargé de developper un certain nombre de composants spécifiques à nos besoins.
    J'ai bien suivi beaucoup de tutoriels Swing et son utilisation m'est désormais familière, sans que j'en sois pour autant un expert, loin de la. J'ai appris les bases et l'utilisation, mais je ne sais pas réellement comment fonctionne Swing en arrière plan.

    Dans mon cas par exemple, j'ai besoin de créer un bouton personnalisé, qui comprendrait une image bien sur, mais aussi une image pour quand celui-ci à le focus etc... Bien sur ce composant doit être général pour être réutilisé à plusieurs endroits différents en changeant juste l'image dans le constructeur.
    La n'est pas le problème, ce que je n'arrive pas à gérer est la taille du composant pour notamment les redimensionnements.
    Dans l'idéal, la taille maximum et préférée du composant est la taille de l'image passée en paramètre, cependant si la taille disponible est inférieure il faudrait que le bouton se redimensionne comme il faut. Or, dans les méthodes que j'ai implémentées, soit le composant ne change jamais de taille et reste fixe, soit sa taille passe à 0, soit il n'a pas la taille qu'il devrait avoir.

    Pour exemple voici grossièrement ma classe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    public class MButton extends JComponent {
      protected Image image;
     
      public MButton(Image image) {
        super();
        this.image = image;
        this.setSize(this.image.getWidth(), this.image.getHeight());
      }
     
      public Dimension getPreferredSize() {
        return new Dimension (this.getWidth(), this.getHeight());
      }
      public Dimension getminimumSize() {
        return this.getPreferredSize();
      }
    public Dimension getmaximumSize() {
        return this.getpreferredSize();
    }
      public void paintComponent(Graphics g) {
        ...
      }
    }
    Je ne sais pas si ce que je demande est très clair, et si ce n'est pas le cas signalez le moi.

    En tous cas j'aimerais savoir si cette classe à un fonctionnement 100% fonctionnel avec Swing, et si non pourquoi. En tous cas si elle l'a je devrais chercehr mon erreur ailleurs.

    Merci à tous, bonne soirée !
    Dernière modification par sinok ; 11/04/2011 à 20h04. Motif: Ajout des balises [code][/code], merci d'y penser

  2. #2
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 083
    Points
    7 083
    Par défaut
    Pas besoin de redéfinir les méthodes getXXXXSize(), tu peux appeler le setter une fois.

    Si tu utilises un layout (petites explications), c'est lui qui se chargera de changer la taille au besoin et également de l'initialiser. C'est également lui gère la taille sur les redimensionements en fonction des tailles minimales, préférées, maximales des différents composants et des contraintes apposées.

    Ensuite la classe JButton permet déjà de mettre une image Et il vaut mieux partir de javax.swing.AbstractButton
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  3. #3
    Invité
    Invité(e)
    Par défaut
    Bonjour, merci de votre réponse. J'ai réussi à obtenir un comportement à peu près semblable à ce que je souhaitais.
    Cependant j'ai un nouveau problème que je n'avais pas avant.
    Désormais ma méthode paintComponent s'appelle en boucle. Avant elle n'était appelée que lorsque la taille de la fenêtre changeait, aujourd'hui elle est appelée sans arrêt ce qui provoque d'énormes problèmes de lags.
    Sauriez vous pourquoi ? J'ai beau remettre mon code comme il l'était antérieurement mais rien ne change.

  4. #4
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 083
    Points
    7 083
    Par défaut
    J'ai constaté ce phénomène quand un développeur a la mauvaise idée de modifier un composant dans l'une des méthodes paint.
    En effet les différentes méthodes paint sont appelées lorsqu'AWT/Swing détecte un changement dans les composants qui nécessitent de le redessiner.

    Quel est le contenu de vos méthodes paint ?
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  5. #5
    Invité
    Invité(e)
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    public void paintComponent(Graphics g) {
    		super.paintComponent(g);
    		//DEBUG On affiche une bordure
    		this.setBorder(BorderFactory.createLineBorder(Color.RED));
    		//On redimensionne l'image
    		BufferedImage drawedImage = Picture.scale(this.character.getAppearance(), this.getWidth(), this.getHeight());
    		//On dessine l'image
    		g.drawImage(drawedImage, (this.getWidth() - drawedImage.getWidth()) / 2, (this.getHeight() - drawedImage.getHeight()) / 2, null);
    	}
    Voila ma méthode paint, à aucun moment le composant n'est modifié dans cette méthode.
    Seule l'image que l'on doit afficher subit un traitement, mais même sans cela, la méthode tourne en boucle. De plus le problème ne vient pas non plus du super.paintComponent(g), puisque si j'enlève aussi celui-la, ça ne règle rien du tout.

  6. #6
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 083
    Points
    7 083
    Par défaut
    Citation Envoyé par sergentrif Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public void paintComponent(Graphics g) {
    		super.paintComponent(g);
    		//DEBUG On affiche une bordure
    		this.setBorder(BorderFactory.createLineBorder(Color.RED));
    		//On redimensionne l'image
    		BufferedImage drawedImage = Picture.scale(this.character.getAppearance(), this.getWidth(), this.getHeight());
    		//On dessine l'image
    		g.drawImage(drawedImage, (this.getWidth() - drawedImage.getWidth()) / 2, (this.getHeight() - drawedImage.getHeight()) / 2, null);
    	}
    Voila ma méthode paint, à aucun moment le composant n'est modifié dans cette méthode.
    Seule l'image que l'on doit afficher subit un traitement, mais même sans cela, la méthode tourne en boucle. De plus le problème ne vient pas non plus du super.paintComponent(g), puisque si j'enlève aussi celui-la, ça ne règle rien du tout.
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  7. #7
    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,


    Ton problème vient de l'appel à setBorder() ! Tu n'as pas à faire cela dans la méthode paintComponent(). Tu dois uniquement te contenter de dessiner ton composant sans changer tes propriétés.

    Ici à chaque fois que tu passes dans paintComponent(), tu changes la bordure du composant, et cela provoque un nouvel appel à paintComponent() (même si tu remet la même bordure à chaque fois).

    Dans paintComponent() tu dois uniquement te contenter de dessiner ton composant !!!

    Si tu veux initialiser certaines valeurs comme la bordure, fais-le dans le constructeur

    a++

    [edit] grillé

  8. #8
    Invité
    Invité(e)
    Par défaut
    Oulala autant pour moi, j'ignorais cela et j'en suis vraiment navré >_<
    Toutes mes excuses, et tous mes remerciements pour cette aide

    Passez tous deux une bonne journée !

  9. #9
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 083
    Points
    7 083
    Par défaut
    Ce qui est marrant c'est qu'il s'agit exactement de la même erreur qu'avait fait le développeur : mettre une bordure rouge sur le composant dans la méthode paintComponent.

    Pas de soucis, AWT/Swing nécessitant un peu d'expérience pour comprendre ces mécanismes, ca peut arriver. Sauf que dans le cas du développeur en question, le type se prenait pour le roi du Java et se permettait de dire aux gars le plus expérimenté "Oui mais je cherche quelqu'un de VRAIMENT calé" ... Le type a fait deux mois.

    Penses au bouton ;-)
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  10. #10
    Invité
    Invité(e)
    Par défaut
    Hop sujet résolu, je n'avais pas trouvé le bouton précédemment.

    Peut être que certaines personnes ne connaissent pas la politesse, mais heureusement que ce n'est pas le cas pour tout le monde.

    En tous cas, merci bien, j'ai honte de cette erreur, que j'aurais pu comprendre seul ^^

  11. #11
    Expert éminent sénior
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    Accessoirement le redimensionnement de l'image dans le paintComponent c'est un peu goret aussi.

    D'autant plus que tu peux le faire directement avec une des variantes de drawImage
    Hey, this is mine. That's mine. All this is mine. I'm claiming all this as mine. Except that bit. I don't want that bit. But all the rest of this is mine. Hey, this has been a really good day. I've eaten five times, I've slept six times, and I've made a lot of things mine. Tomorrow, I'm gonna see if I can't have sex with something.

Discussions similaires

  1. Créer un composant Swing qui bouge
    Par druzy dans le forum AWT/Swing
    Réponses: 6
    Dernier message: 21/01/2013, 19h52
  2. Créer des composants JavaFX pour du Swing
    Par narmataru dans le forum JavaFX
    Réponses: 2
    Dernier message: 13/12/2011, 17h05
  3. [List] Créer mon composant
    Par soad dans le forum Composants
    Réponses: 3
    Dernier message: 02/12/2005, 08h00
  4. [vb.net] Impossible de créer le composant ActiveX [win98]
    Par arnolem dans le forum Windows Forms
    Réponses: 10
    Dernier message: 12/07/2005, 12h09
  5. Intercepter un Message Windows ? Créer un Composant Grille !
    Par TOTO32 dans le forum Composants VCL
    Réponses: 6
    Dernier message: 21/07/2004, 13h41

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