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 :

Des Mouse event (clic) oubliés dans mon JPanel


Sujet :

AWT/Swing Java

  1. #1
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Par défaut Des Mouse event (clic) oubliés dans mon JPanel
    Bonjour,

    Voilà j'ai dérivé un JPanel pour afficher plusieurs images sur lesquelles je veux catcher les clics (cf. le code simplifié en dessous).

    Le problème: il arrive plus ou moins régulièrement que certains clics dans mon JPanel ne soient pas 'catchés', ie. processClick() n'est pas appelé.

    C'est (très) ennuyeux. Aurais-je fait un truc de travers ?

    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
     
    public class ImagePanel extends JPanel {
        public ImagePanel () {
            super.addMouseListener(new MouseAdapter() {
                public void mouseClicked(MouseEvent e) {
                    processClick(e);
                }
            });
        }
     
        protected void processClick(MouseEvent e) {
            // pour chaque image de la liste, j'appelle getImageRectangle()
            // je compare avec la coordonnée contenue dans 'e' et ainsi 
            // je sais quelle image a été cliquée ; je préviens des listeners.
        }
        public void paintComponent(Graphics g) {
            // ici j'affiche ma liste d'images
            // en calculant leur pos + taille avec getCardRectangle(...)
            for (int pos = 0 ; pos < m_images.size() ; ++pos) {
                Rectangle rect = getImageRectanle(i);
                g.drawImage(img, rect.x, rect.y, rect.width, rect.height, this);
            }
        }
        public Rectangle getImageRectangle(int pos) {
            // je retourne ici la pos + taille de mon image à afficher.
        }
     
        public static void main(String[] argv) {
            CardsPanel cards = new CardsPanel(CardsPanel.Direction.HORIZONTAL, true);
            //etc...
       }
    }

  2. #2
    Membre éprouvé
    Avatar de Janitrix
    Inscrit en
    Octobre 2005
    Messages
    3 391
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 3 391
    Par défaut
    Pour ce genre de problème, le mieux (je trouve) c'est de mettre des System.out.println("..."); ) chaque étape importante. Donc ça te donne ça :
    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
    public ImagePanel () {
            super.addMouseListener(new MouseAdapter() {
                public void mouseClicked(MouseEvent e) {
                    processClick(e);
    System.out.println("state1");
                }
            });
        }
     
        protected void processClick(MouseEvent e) {
    System.out.println("state2");
            // pour chaque image de la liste, j'appelle getImageRectangle()
            // je compare avec la coordonnée contenue dans 'e' et ainsi 
            // je sais quelle image a été cliquée ; je préviens des listeners.
        }
    Comme ça tu sais où ton évènement est bloqué. Si à chaque clique, il y a state1 écrit dans la console, ton évènement est normal. De plus, essai de voir si le fait d'implémenter toutes les méthodes de MouseAdapter corrige ton problème. Bonne chance.

  3. #3
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Par défaut
    Salut, et merci pour ta réponse.

    En fait, le code présenté ci dessus est raccourci pour montrer le principe ; je n'ai pas copié/collé le code complet pour ne pas surcharger mon post.
    J'ai effectivement déjà ajouté des println un peu partout, et ça donne que les clics non détectés ne passent ni par mouseClicked() ni par processClick()
    Les clics détectés, eux, passent normalement par les deux fonctions.

    essaie de voir si le fait d'implémenter toutes les méthodes de MouseAdapter corrige ton problème.
    J'ai du mal à bien voir l'intérêt de ce genre d'essai : soit mon adapter est bon et j'arrive au moins une fois à avoir une méthode d'appelée (c mon cas), soit l'adapteur n'est jamais appelé (pas mon cas). Je comprends pas à quoi servirait de surcharger des méthodes vides par d'autres méthodes vides. Je cite la JavaDoc:

    The methods in this class are empty. This class exists as convenience for creating listener objects.

  4. #4
    Membre éprouvé
    Avatar de Janitrix
    Inscrit en
    Octobre 2005
    Messages
    3 391
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 3 391
    Par défaut
    Tu surchages ces méthodes afin de voir si l'évènement n'est pas "attrapé" dans ces méthodes, ce qui me semble peu probable, mais on sait jamais. Essai d'enlever le super quand tu fais super.addMouseListener(...). Bonne chance.

  5. #5
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Par défaut
    Alors,

    - J'ai bien enlevé le 'super' (même si logiquement, ça ne change rien puisque ma classe dérive de JPanel)

    - J'ai implémenté les autres méthodes, notamment mousePressed() et MouseReleased().

    Cas d'un clic qui 'marche':
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    mousePressed()
    mouseReleased()
    mouseClicked()
    Cas d'un clic qui 'déconne'
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    mousePressed()
    mouseReleased()
    Donc le problème persiste sachant que quand les clics ne sont pas 'catchés' par mouseClicked(), on catche quand même bien mousePressed() et mouseReleased().

    La solution de facilité serait de se brancher sur MousePressed() en lieu et place de mouseClicked(). Certes, dans mon cas c'est à peu près équivalent (quoique), mais je trouve quand même cela anormal. La JavaDoc précise bien pour mouseClicked() :
    Invoked when the mouse button has been clicked (pressed and released) on a component.
    Donc en toute logique, mouseClicked() devrait être appelé. Bug ou erreur de ma part ?

    EDIT: à noter qu'il semble que les clics non 'catchés' se produisent plus fréquemment pendant ou après une salve de clics rapides.

  6. #6
    Membre éprouvé
    Avatar de Janitrix
    Inscrit en
    Octobre 2005
    Messages
    3 391
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 3 391
    Par défaut
    Je vais peut être dire une connerie, mais l'invocation de mouseClicked() est peut être réalisée en fonction du temps écoulé entre la pression et le release du bouton : genre si il y eu 3 secondes, entre les deux, il fait rien. Il y a rien dans la javadoc à ce sujet ?

  7. #7
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Par défaut
    Ah, j'ai édité mon dernier post pendant que tu répondais, je répète donc, au cas où t'aurais pas vu : "à noter qu'il semble que les clics non 'catchés' se produisent plus fréquemment pendant ou après une salve de clics rapides."

    Non, pas de relation entre les clics oubliés et la durée entre l'enfoncement et le relâchement du bouton. Ca peut se passer avec un clic très rapide, ou un clic lent.
    De plus, après une suite de clics relativement peu espacés, ça merdoie (la plupart du temps). J'attends alors quelques secondes, je re-clique et ça merdoie encore.

    Et non plus: rien dans la Javadoc, même après avoir fouillé. J'avais envisagé que plusieurs clics de suite puissent être interprétés comme un double-clic, mais pas de trace d'évenement de ce type dans le MouseListener. De plus, d'autres sites de développement expliquent comment implémenter un détecteur de double clic à la main. Logiquement, c'est que ça doit pas être géré en standard.

  8. #8
    Membre confirmé
    Inscrit en
    Mars 2007
    Messages
    90
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 90
    Par défaut
    salut
    svp j ai pas bien compris la reponse si vous pouvez m aider sur ton programme

  9. #9
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Par défaut
    salut,

    quelle partie n'as-tu pas compris ?

  10. #10
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Par défaut
    Personne n'a d'idée ?

    J'imagine qu'un MouseListener sur un JPanel est quelque chose de (très) classique, donc d'utilisé relativement régulièrement.
    C'est pourquoi j'imagine que l'erreur vient plutôt de mon côté et que c'est pas un bug du JDK...
    Mais là je vois vraiment plus d'où ça pourrait venir et ce que je pourrais tester :-/

    help...

  11. #11
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Par défaut
    up

  12. #12
    Membre Expert
    Avatar de xavlours
    Inscrit en
    Février 2004
    Messages
    1 832
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 1 832
    Par défaut
    Bon, je tente aussi ...
    As tu traqué les mouseEntered/Exited ? Parce que si la souris sort puis rentre dans le JPanel entre la pression et le relâchement, il n'y aura pas de mouseClicked. Ca peut notamment arriver si il y a des composants à l'intérieur de ton JPanel (JLabels par exemple).
    "Le bon ni le mauvais ne me feraient de peine si si si je savais que j'en aurais l'étrenne." B.V.
    Non au langage SMS ! Je ne répondrai pas aux questions techniques par MP.
    Eclipse : News, FAQ, Cours, Livres, Blogs.Et moi.

  13. #13
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Par défaut
    Merci pour ton idée xavlours.

    Ca ne venait pas de là mais ça m'a quand même globalement mis sur la voie.
    Je pense avoir la réponse du pourquoi du comment:

    En fait, l'event mouseClicked est emis SI ET SEULEMENT SI les coordonnées (x,y) du pointeur entre l'appui sur le bouton et son relâchement SONT strictement EGALES.
    En d'autres termes, il suffit qu'en cliquant sur le bouton de la souris, on fasse légèrement bouger cette dernière (un pixel suffit), quand on relâche on n'obtiendra pas d'événement 'mouseClicked'.
    Ayant une souris paramétrée pour être ultra sensible (oui, je suis un feignant du poignet ), ça doit m'arriver plus fréquemment que la moyenne.

    Je trouve que l'option retenue par Java est un peu tranchée comme façon de faire, mais bon ... Perso, je vais voir pour me faire mon petit manager perso...

    Merci en tout cas pour toutes vos idées et suggestions

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

Discussions similaires

  1. Réponses: 7
    Dernier message: 25/05/2011, 17h08
  2. Réponses: 3
    Dernier message: 22/12/2009, 15h00
  3. incorporer des modèles de feuilles excel dans mon xla
    Par batou22003 dans le forum Excel
    Réponses: 2
    Dernier message: 12/10/2009, 15h15
  4. renvoi des variables de l'url dans mon formulaire
    Par cajoline06 dans le forum Langage
    Réponses: 2
    Dernier message: 22/04/2009, 16h11

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