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 :

[Design Patterns] Decorator avec Swing ?


Sujet :

AWT/Swing Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert Avatar de herve91
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    1 282
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 282
    Par défaut [Design Patterns] Decorator avec Swing ?
    Bonjour,
    j'ai trouvé sur le site Decorator pattern in Java un exemple intéressant d'utilisation du design pattern decorator pour enrichir dynamiquement un composant Swing (en l'occurrence un bouton). Je vous livre ici un code source réduit permettant d'exposer le problème :
    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    public class DecoDemo extends JFrame implements ActionListener {
     
      public DecoDemo() {
        super("Deco Button");
        JPanel jp = new JPanel();
        getContentPane().add(jp);
     
        jp.add(new SlashDecorator(new JButton("Slash")));
        JButton quit = new JButton("Quit");
        jp.add(quit);
        quit.addActionListener(this);
        pack();
        setVisible(true);
      }
     
      public void actionPerformed(ActionEvent e) {
        System.exit(0);
      }
     
      static public void main(String argv[]) {
        new DecoDemo();
      }
     
      class Decorator extends JComponent {
        public Decorator(JComponent c) {
          setLayout(new BorderLayout());
          add(c, BorderLayout.CENTER);
        }
      }
     
      class SlashDecorator extends Decorator {
        public SlashDecorator(JComponent c) {
          super(c);
        }
     
        public void paint(Graphics g) {
          super.paint(g);
          g.setColor(Color.red);
          g.drawLine(0, 0, getWidth(), getHeight());
        }
      }
    }
    Le bouton s'affiche bien avec la barre rouge. Seulement, dès que la souris passe dessus, ou lorsqu'on clique sur le bouton, la barre rouge disparaît. Pour la faire réapparaître, il est nécessaire de repeindre entièrement la fenêtre (iconification/désiconification par exemple).
    Le problème vient du fait que ce n'est pas la méthode paint() du bouton qui est redéfinie, mais celle du container dans lequel il est inclus.
    D'où ma question, le design pattern decorator est-il utilisable, et si oui comment, afin d'enrichir dynamiquement des composants Swing ?
    Il serait tentant d'enchainer les décorations, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    new CircleDecorator(new SlashDecorator(new JButton("Slash")));
    qui aurait pour effet de décorer le bouton en affichant dessus une barre et un cercle.

  2. #2
    Gfx
    Gfx est déconnecté
    Expert confirmé
    Avatar de Gfx
    Inscrit en
    Mai 2005
    Messages
    1 770
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 770
    Par défaut
    Il faudrait que je regarde plus en detail mais j'ai peur que cela soit un peu complique pour que cela fonctionne correctement. Une solution serait d'utiliser un OverlayLayout ou un JLayeredPane a chaque fois que l'on rajoute un decorateur.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    154
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 154
    Par défaut
    Salut,

    Ne faudrait il pas redéfinir la méthode paintComponent au lieu de la méthode paint?

  4. #4
    Membre Expert Avatar de herve91
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    1 282
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 282
    Par défaut
    Non, c'est pire, aucune barre n'est affichée (la méthode paintComponent n'est pas appelée, dixit les traces)

  5. #5
    Membre éprouvé Avatar de Xavinou
    Inscrit en
    Mai 2005
    Messages
    135
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 135
    Par défaut
    Tu peux rajouter un mouse listener sur le composant décoré, et lancer le repaint lorsque le composant est suceptible d'être repaint.

    Par exemple :
    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
     
    	class SlashDecorator extends Decorator {
    		public SlashDecorator(JComponent c) {
    			super(c);
    			c.addMouseListener(new MouseAdapter() {
    				@Override
    				public void mouseEntered(MouseEvent $e) {
    					repaint();
    				}
    				@Override
    				public void mouseExited(MouseEvent $e) {
    					repaint();
    				}
     
    			});
     
    		}

  6. #6
    Gfx
    Gfx est déconnecté
    Expert confirmé
    Avatar de Gfx
    Inscrit en
    Mai 2005
    Messages
    1 770
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 770
    Par défaut
    Cela ne suffit pas, le repaint doit etre lance par tout un tas d'autres actions, notamment les evenements clavier.

  7. #7
    Membre Expert Avatar de herve91
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    1 282
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 282
    Par défaut
    Bon, au vu des "quelques" réponses, j'en déduis que le pattern decorator n'est pas vraiment applicable aux composants, et qu'il faut donc utiliser la bonne vieille recette de l'héritage
    Merci à tous.

  8. #8
    Membre éclairé
    Inscrit en
    Juillet 2004
    Messages
    306
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 306
    Par défaut
    C très interessant mais comment disparait le slash lorsque le curseur de souris se positionne sur le bouton Slash ?

  9. #9
    Membre éprouvé Avatar de Xavinou
    Inscrit en
    Mai 2005
    Messages
    135
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 135
    Par défaut
    Le slash disparait lorsque la souris passe sur le bouton parce que le bouton est repaint pour changer d'apparence.

    Cela ne suffit pas, le repaint doit etre lance par tout un tas d'autres actions, notamment les evenements clavier.
    On peut rajouter un focus listener, mais c'est vrai qu'on ne peut pas avoir la garantie de traiter tous les repaint, surtout s'ils sont appelés par des objets quelconques du programme.

    j'en déduis que le pattern decorator n'est pas vraiment applicable aux composants
    J'ai quand même l'impression que ça marcherait beaucoup mieux si le decorator se limitait à utiliser les setters définis sur JComponent (par exemple setForeground(), ...). S'il doit redéfinir la méthode paint, effectivement c'est difficile de garantir qu'il pourra toujours se mettre à jour...

  10. #10
    Membre éclairé
    Inscrit en
    Juillet 2004
    Messages
    306
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 306
    Par défaut
    Citation Envoyé par Xavinou
    Le slash disparait lorsque la souris passe sur le bouton parce que le bouton est repaint pour changer d'apparence.
    Et ça, c fait automatiquement alors ?, puisqu'il n'y a pas de mouseListener utilisé

  11. #11
    Membre Expert Avatar de herve91
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    1 282
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 282
    Par défaut
    C'est fait automatiquement avec Java 1.5 avec le L&F Ocean, qui définit une icone "rollover" par défaut sur le bouton. Avec Java 1.4 et le L&F Metal, ça ne se produit pas.

Discussions similaires

  1. POO design pattern Singleton avec Windev
    Par Atsibat dans le forum Contribuez
    Réponses: 2
    Dernier message: 30/11/2012, 13h57
  2. Exemple d'utilisation du design pattern Decorator
    Par cedrix57 dans le forum Design Patterns
    Réponses: 1
    Dernier message: 24/11/2011, 17h59
  3. [EJB3.1] Design pattern decorator
    Par le2tbomi dans le forum Java EE
    Réponses: 1
    Dernier message: 05/11/2010, 12h18
  4. Réponses: 4
    Dernier message: 30/03/2009, 22h06
  5. Implémenter le design pattern Observer avec les services web
    Par Klemsy78 dans le forum Services Web
    Réponses: 1
    Dernier message: 12/02/2008, 16h51

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