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 :

Un nouveau composant fonctionne dans une Frame mais pas dans une autre. Pourquoi?


Sujet :

AWT/Swing Java

  1. #1
    Membre régulier
    Inscrit en
    Août 2002
    Messages
    132
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 132
    Points : 102
    Points
    102
    Par défaut Un nouveau composant fonctionne dans une Frame mais pas dans une autre. Pourquoi?
    Bonjour à tous !

    Voilà mon problème :
    je crée un composant "Cercle" qui étend la classe Component : je veux qu'un objet Cercle soit dessinable. Pas trop difficile, jusque là. De plus, je veux qu'il soit à l'écoute-souris de lui-même, par exemple pour que quand la souris passe dessus il change sa couleur...

    Voici le code de ma classe Cercle :
    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
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
     
    public class Cercle extends JComponent implements MouseListener, MouseMotionListener{
        int x , y , r;
        boolean couleurSwap;
     
        public Cercle(int _x , int _y , int _r)    {
            addMouseListener(this);
            addMouseMotionListener(this);
            x = _x;//Abscisse du centre
            y = _y;//Ordonnée du centre
            r = _r;
            couleurSwap = true;
        }
     
        public boolean contains(int x,int y){
             return (Math.sqrt((this.x-x)*(this.x-x)+(this.y-y)*(this.y-y))<=r);
        }
     
        public void paint(Graphics g){   
            if( couleurSwap ){
    				g.setColor( Color.BLUE );
    			}
    			else{
    				g.setColor( Color.RED );
    			}         
            g.fillOval(x-r,y-r,2*r,2*r);
        }
     
         //MouseListener
        public void mouseClicked(MouseEvent e){
        }        
        public void mouseEntered(MouseEvent e){
            couleurSwap = ! couleurSwap;
            repaint();
        }
        public void mouseExited(MouseEvent e){
            couleurSwap = ! couleurSwap;
            repaint();
        }    
        public void mousePressed(MouseEvent e){
        }
        public void mouseReleased(MouseEvent e){
        }        
        //MouseListener
     
        //MouseMotionListener
        public void mouseDragged(MouseEvent e){
        }    
        public void mouseMoved(MouseEvent e){
        }            
        //MouseMotionListener    
    }
    A priori, ça marche ... Je le prouve dans ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import javax.swing.*;
     
    public class Ex{
        private JFrame f;
     
        public Ex(){
            f = new JFrame("Prog");
            f.getContentPane().add(new Cercle(100,100,50));
            f.pack();
            f.setVisible(true);
        }
    }
    Le problème arrive ici : en refaisant quasi la même chose que le code ci-dessus, si ce n'est que le dessin se fait dans une autre classe : Panneau (qui étend JPanel). Et puis le contentPane de la Frame est un objet Panneau :

    Classe Panneau :
    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
    import javax.swing.*;
    import java.awt.*;
     
    public class Panneau extends JPanel{
        Cercle c;
     
        public Panneau(){
            c = new Cercle(100,100,65);
            add(c);
            repaint();
        }
     
        public void paint(Graphics g){
            super.paint(g);
            c.paint(g);
        }
    }
    Classe ExAvecPanneau :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import javax.swing.*;
     
    public class ExAvecPanneau{
        private JFrame f;
     
        public ExAvecPanneau(){
            f = new JFrame("Prog");
            f.setContentPane(new Panneau());
            f.pack();
            f.setVisible(true);
        }
    }

    Pourquoi cela ne marche-t-il pas dans ce code ?
    En fait, l'objet Cercle qui est dans le Panneau (= contentPane de la Frame) n'est pas écouté! Pourquoi ?

    Merci !

  2. #2
    Membre régulier
    Inscrit en
    Août 2002
    Messages
    132
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 132
    Points : 102
    Points
    102
    Par défaut
    Up !

    Personne n'a de réponse à mon problème ?

    Ça ne parait bizarre à personne que le premier exemple fonctionne mais pas le 2ème ?

    J'ai sans doute louper un gros truc, mais ... j'espère que quelqu'un prendra quelques minutes pour me l'expliquer!

    D'avance ... Merci !

  3. #3
    Membre averti
    Homme Profil pro
    Inscrit en
    Juillet 2002
    Messages
    705
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 705
    Points : 393
    Points
    393
    Par défaut
    comme pour JComponent jpanel doit implémenter le MouseListener

  4. #4
    Nouveau membre du Club
    Inscrit en
    Mai 2007
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 30
    Points : 28
    Points
    28
    Par défaut
    comme il ta dis tu dois implemeter le MouseListener
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public class panneau exetnds JPanel implements MouseListener, MouseMotionListener{
    c'est l'entete de votre classe ainsi que tu dois ajouter les methodes de l'interface MouseListener.

    bonne chance.

  5. #5
    Membre régulier
    Inscrit en
    Août 2002
    Messages
    132
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 132
    Points : 102
    Points
    102
    Par défaut
    Merci beaucoup!

    Je vais tester ça ce soir (j'ai pas l'occasion de le faire ici...)...

    En attendant ... Je dois simplement dire que la classe Panneau est écoutée, ou bien je dois indiquer du code dans les méthode
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public void mouse***(MouseEvent e){ ... }
    ?

    Le fait que j'écrive
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    ... implements MouseListener,MouseMoveListener
    // et les méthodes VIDES associées à ces interfaces
    suffit pour que l'écoute soit transmise à mon objet cercle?

    Ou alors je dois mettre du code dans les méthode ?

    Encore merci !

    Je teste tout ça ce soir, mais en lisant vos réponses, ces questions me sont venues à l'esprit

    A bientôt !

  6. #6
    Membre régulier
    Inscrit en
    Août 2002
    Messages
    132
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 132
    Points : 102
    Points
    102
    Par défaut
    Me re-voilà ... Tests faits ... Et ... Comme je le craignais, juste le fait de faire écouter le panneau par la souris ne suffit pas ... Voici le nouveau code de mon Panneau :
    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
     
    import javax.swing.*;  import java.awt.*;  import java.awt.event.*;
     
    public class Panneau extends JPanel implements MouseListener,MouseMotionListener{
        Cercle c;
     
        public Panneau() {
            c = new Cercle(100,100,65);
            add(c);
            repaint();
            this.addMouseMotionListener(this);
            this.addMouseListener(this);
        }
     
        public void paint(Graphics g) {
            super.paint(g);
            c.paint(g);
        }
     
        //MouseListener
        public void mouseClicked(MouseEvent e){    }        
        public void mouseEntered(MouseEvent e){    }
        public void mouseExited(MouseEvent e){    }    
        public void mousePressed(MouseEvent e){    }
        public void mouseReleased(MouseEvent e){    }        
     
        //MouseMotionListener
        public void mouseDragged(MouseEvent e){    }    
        public void mouseMoved(MouseEvent e){    }            
    }
    En mettant uniquement ça, je me disais (mais sans trop y croire...) que les objets inclus au Panneau recevraient aussi l'écoute... Ce n'est pas le cas !

    Comment faire passer l'écoute à l'objet Cercle, à partir de la classe Panneau?

    Merci !

    A plus tard

  7. #7
    Membre régulier
    Inscrit en
    Août 2002
    Messages
    132
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 132
    Points : 102
    Points
    102
    Par défaut


    J'ai fait un autre test ... J'espérais que cela ne marche pas (lool) mais ... Evidemment ... Ça marche ...

    Voici le test que j'ai fait :
    J'ai créé une classe MonBouton qui étend JButton, de la même manière que j'avais créé ma classe Cercle... J'ai ajouté un objet "MonBouton" dans mes 2 classes d'exemple, comme c'était fait avec le Cercle : une sans un panneau intermédiaire, directement dans une JFrame, le bouton est bien écouté ; l'autre avec un panneau intermédiaire ... Avec la classe Cercle (qui étend JComponent), ça ne marche pas ... Avec la classe MonBouton, ça marche ... POURQUOI ? ? ?

    Voici mes classes :
    Code MonBouton : 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
     
    import java.awt.event.*;
    import javax.swing.*;
     
    public class MonBouton extends JButton implements MouseListener, MouseMotionListener
    {
        public MonBouton(){
            super("Mon bouton");
            addMouseListener(this);
            addMouseMotionListener(this);
        }
     
        public void mouseClicked(MouseEvent e){
            JOptionPane.showMessageDialog(null,"Click!");
        }        
        public void mouseEntered(MouseEvent e){    }
        public void mouseExited(MouseEvent e){    }    
        public void mousePressed(MouseEvent e){    }
        public void mouseReleased(MouseEvent e){    }        
     
        public void mouseDragged(MouseEvent e){    }    
        public void mouseMoved(MouseEvent e){    }            
    }

    Code Ex (bouton directement dans la Frame, comme pour le Cercle) : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    import javax.swing.*;
     
    public class Ex{
        private JFrame f;
     
        public Ex(){
            f = new JFrame("Prog");
    //         f.getContentPane().add(new Cercle(100,100,80));
             f.getContentPane().add(new MonBouton());
            f.pack();
            f.setVisible(true);
        }
    }

    Code Panneau (dans lequel j'insère un objet MonBouton) : 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
     
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
     
    public class Panneau extends JPanel implements MouseListener,MouseMotionListener{
    //     Cercle c;
        MonBouton mb;    
     
        public Panneau(){
    //         c = new Cercle(100,100,65);
    //         add(c);
            mb = new MonBouton();
            add(mb);
            repaint();
            this.addMouseMotionListener(this);
            this.addMouseListener(this);
        }
     
        public void paint(Graphics g)    {
            super.paint(g);
    //         c.paint(g);
        }
     
        public void mouseClicked(MouseEvent e){}        
        public void mouseEntered(MouseEvent e){}
        public void mouseExited(MouseEvent e){}    
        public void mousePressed(MouseEvent e){}
        public void mouseReleased(MouseEvent e){}        
     
        public void mouseDragged(MouseEvent e){}    
        public void mouseMoved(MouseEvent e){}            
    }

    Et enfin :
    Code ExAvecPanneau (JFrame dans laquelle j'insère un Panneau, idem que pour le Cercle!) : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    import javax.swing.*;
     
    public class ExAvecPanneau{
        private JFrame f;
     
        public ExAvecPanneau(){
            f = new JFrame("Prog");
            f.setContentPane(new Panneau());
            f.pack();
            f.setVisible(true);
        }
    }

    De plus, je viens d'essayer d'enlever les écouteur dans la classe MonPanneau, le bouton est toujours écouté par les événements de la souris ! ! !


    Comment faire pour que les objets de la classe Cercle soient écoutés pas les évènements de la souris, comme un objet qui étend un JButton ? ? ?


    Un grand MERCI à ceux qui prendront le temps de m'expliquer ce qui m'échappe ... (car ya clairement un BIG truc qui m'échappe ! ! ! )

  8. #8
    Membre régulier
    Inscrit en
    Août 2002
    Messages
    132
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 132
    Points : 102
    Points
    102
    Par défaut
    Re !

    Je pense que j'avance ...

    Un premier problème est que l'objet Graphics de l'objet Panneau n'est pas le même que celui de l'objet Cercle. Ce qui fait qu'il n'y a pas correspondance entre les coordonnées de l'objet Cercle avec l'objet Panneau. Je ne sais pas trop pourquoi il n'y a pas correspondance, mais c'est vrai que je dis nulle dans le code qu'ils doivent être les mêmes !

    Un deuxième problème est que, visiblement, lorsque je demande à un objet Cercle de se redessiner, je dois lui dire que son Parent doit se redessiner aussi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this.getParent().repaint();
    Ce deuxième problème est maintenant réglé

    Reste ... le premier ...

    Il faut donc que je transmettre l'objet Graphics lors de la construction d'un Cercle (enfin ... je pense ...)

    Bon ... Je continue mes tests ...

    A plus tard ...

  9. #9
    Membre régulier
    Inscrit en
    Août 2002
    Messages
    132
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 132
    Points : 102
    Points
    102
    Par défaut Le problème venait du Layout
    Salut tout le monde !

    En continuant de chercher, en indiquant les coordonnées de la souris, je me suis rendu compte qu'elles étaient parfois négatives . . .

    En fait, je me suis rendu compte que, pour la souris, sur le JPanel, le zéro horizontal n'était pas à l'extrême gauche, mais au milieu du panneau !

    Pourquoi ? ? ?

    Et bien ... simplement parce que le Layout par défaut d'un JPanel est un FlowLayout, qui centre les composant !

    La solution était donc de changer de Layout... Le plus simple pour moi a été de ne pas en mettre du tout (le panneau ne me servira que pour dessiner!)

    Voilà !

    Il ne faut jamais désespérer (et ... j'étais en train de quand ... PAF ! Tout à coup ... j'ai trouvé )

    Bonne journée à tous !

  10. #10
    Membre éprouvé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2007
    Messages
    697
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Janvier 2007
    Messages : 697
    Points : 1 241
    Points
    1 241
    Par défaut
    Bonsoir,
    public class Panneau extends JPanel implements MouseListener,MouseMotionListener{
    Cercle c;

    public Panneau() {
    c = new Cercle(100,100,65);
    add(c);
    repaint();
    this.addMouseMotionListener(this);
    this.addMouseListener(this);
    }

    public void paint(Graphics g) {
    super.paint(g);
    c.paint(g);
    }
    est une erreur. Tu dois bien ajouter les Mouselistener à ton composant cercle mais seulement à ton composant cercle. De plus
    est à la fois horrible et inutile. car la méthode paint du composant cercle est déjà appelé par le RepaintManager, donc tu le vire. Ensuite il faut récupérer le focus à l'aide de la méthode requestFocusInWindow(). Problème, si tu as plusieurs cercles, tu ne peut pas donner le focus à plusieurs composant à la fois. Donc la bonne stratégie je pense est de dessiner directement tes cercles (drawOvale) sur ton panel qui écoutera les évènements souris et ta classe cercle qui ne heritera plus de JComposant aura une methode draw(Graphics g) que tu appelera dans le paintComponent de ton JPanel
    Par exemple la classe Cercle devient
    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
    43
    44
     
    public class Cercle extends Figure{
        //==================attributs================
        private int rayon;
     
        //================constructeurs==============
        public Cercle(Point x1, Point x2, 
                Color color, boolean full) {
            super();
            this.p1 = x1;
            this.p2 = x2;
            this.color = color;
            this.full = full;
            int y = Math.abs(p1.y - p2.y);
            int x = Math.abs(p1.x - p2.x);
            this.rayon = (int)Math.sqrt((double)(x * x + y * y));
        }
     
        //==============autres methodes===============
        @Override
        public void draw(Graphics g) {
            g.setColor(color);        
            if(full){
                g.fillOval(p1.x - rayon, p1.y - rayon, 2 * rayon, 2 * rayon);            
            }
            else{
                g.drawOval(p1.x - rayon, p1.y - rayon, 2 * rayon, 2 * rayon);            
            }
        }
        @Override
        public void setCoord(Point x1, Point x2) {
            this.p2 = x2;
            int y = Math.abs(p1.y - p2.y);
            int x = Math.abs(p1.x - p2.x);
            this.rayon = (int)Math.sqrt((double)(x * x + y * y));
     
        }
     
        @Override
        public boolean isSelected(Point src) {
            Ellipse2D.Double tmp = new Ellipse2D.Double(p1.x - rayon, p1.y - rayon, 2 * rayon, 2 * rayon);
            return tmp.contains(src.x, src.y);
        }
    }
    et tu dessine ton panel ainsi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            /*to get the focus for the keyboard short cut*/
            this.requestFocusInWindow();
          /*draw all the figure*/
            for(Figure f : model.getFigures()){
                f.draw(g);
            }
     
        }
    Si tu veut la source complète je te l'enverrai ou je l'uploaderai
    ++

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

Discussions similaires

  1. [XL-2010] macro fonctionne dans l'editeur mais pas depuis une feuille
    Par Kanetsugu dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 22/12/2011, 06h56
  2. Réponses: 0
    Dernier message: 03/04/2008, 15h14
  3. Ce qui est dans une table mais pas dans l'autre !
    Par youyoule dans le forum Requêtes
    Réponses: 4
    Dernier message: 30/12/2007, 12h57
  4. [RegEx] Regex qui fonctionne dans un preg_replace mais pas dans un ereg
    Par méphistopheles dans le forum Langage
    Réponses: 4
    Dernier message: 31/03/2007, 11h56
  5. Réponses: 5
    Dernier message: 02/10/2006, 19h24

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