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

Agents de placement/Fenêtres Java Discussion :

[Debutant]KeyListener sur JFrame ne repond pas


Sujet :

Agents de placement/Fenêtres Java

  1. #1
    Membre confirmé Avatar de Romain93
    Inscrit en
    Septembre 2005
    Messages
    71
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 71
    Par défaut [Debutant]KeyListener sur JFrame ne repond pas
    Bonjour,

    Mon probleme est assez simple: j'ai une application avec une fenetre, et je souhaite recuperer l'evenement keyTyped quand cette fenetre est selectionnee. Voila mon code:

    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
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
     
    public class Test {
     
    	private static JPanel createComponents () {
     
    		JButton Up = new JButton("Up");		
    		JPanel pane = new JPanel (new BorderLayout());
    		pane.add(Up, BorderLayout.NORTH);
     
    		return pane;
    	}
     
        public static void main (String[] args)
        {
        	JFrame frame = new JFrame("Test");
     
        	frame.setContentPane(createComponents());
     
    	frame.setFocusable(true);
        	frame.addKeyListener(new KeyListener() {
        		public void keyTyped (KeyEvent e)
        		{
        			System.out.println("key pressed");
        		}
        		public void keyPressed(KeyEvent e) { }
        		public void keyReleased(KeyEvent e) { }
        	});
     
     
        	frame.addWindowListener(new WindowAdapter() {
        		public void windowClosing (WindowEvent e) { System.exit(0); }
        	    });
        	frame.pack ();
        	frame.setVisible(true);
     
        }
     
     
    }
    L'evenement est bien recupere, jusqu'a ce que je clique une fois sur le boutton "Up", ensuite non. J'ai essaye d'ajouter le gestionnaire d'evenement au JPanel au lieu du JFrame, et le probleme est le meme.

    C'est peut-etre tout simple, mais je debute en swing

    merci d'avance,

    Romain

  2. #2
    Membre chevronné Avatar de broumbroum
    Profil pro
    Inscrit en
    Août 2006
    Messages
    406
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2006
    Messages : 406
    Par défaut
    tu devrais essayez de changer la méthode createComponents en admettant que le JPanel que tu crées est un autre que celui de la fenetre JFrame. Habituellement j'instancie la fenetre puis je recupere le panel avec getContentPane et non l'inverse. C'est peut-être ce qui te fait perdre le focus sur ta fenetre...

  3. #3
    Membre confirmé Avatar de Romain93
    Inscrit en
    Septembre 2005
    Messages
    71
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 71
    Par défaut
    j'ai fait ce que tu disais, j'instancie d'abord ma fenetre, puis j'y ajoute le JPanel, mais ca ne change rien:

    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
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
     
    public class Test {
     
    	private Component createComponents () {
     
    		JPanel pane = new JPanel (new BorderLayout());
    		pane.add(new JButton("Up"), BorderLayout.NORTH);
     
    		return pane;
    	}
     
        public static void main (String[] args)
        {
        	JFrame frame = new JFrame("Test");
     
        	Test app = new Test();
        	Component contents = app.createComponents();
        	frame.getContentPane().add(contents, BorderLayout.CENTER);
     
    	   	frame.setFocusable(true);
        	frame.addKeyListener(new KeyListener() {
        		public void keyTyped (KeyEvent e)
        		{
        			System.out.println("key pressed");
        		}
        		public void keyPressed(KeyEvent e) { }
        		public void keyReleased(KeyEvent e) { }
        	});
     
     
        	frame.addWindowListener(new WindowAdapter() {
        		public void windowClosing (WindowEvent e) { System.exit(0); }
        	    });
        	frame.pack ();
        	frame.setVisible(true);
     
        }
     
     
    }
    Tu parles de changer la methode createComponents. Qu'est-ce que je devrais faire exactement?

    Merci

  4. #4
    Membre chevronné Avatar de broumbroum
    Profil pro
    Inscrit en
    Août 2006
    Messages
    406
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2006
    Messages : 406
    Par défaut
    Eviter un duplication du panel. c tout ce que je pense. sinon je vois pas vraiment ou se situe ton probleme par rapport aux evenements clavier... Ca marche puis ca marche plus???
    Citation Envoyé par Romain93
    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
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
     
    public class Test {
     
    	private Component createComponents (JPanel panel) {
     
    		JPanel pane = panel; pane.setLayout(new BorderLayout());
    		pane.add(new JButton("Up"), BorderLayout.NORTH);
     
    		return pane;
    	}
     
        public static void main (String[] args)
        {
      //...
     
        }
     
     
    }
    Tu parles de changer la methode createComponents. Qu'est-ce que je devrais faire exactement?

    Merci

  5. #5
    Expert éminent
    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
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par broumbroum
    sinon je vois pas vraiment ou se situe ton probleme par rapport aux evenements clavier... Ca marche puis ca marche plus???
    Ce comportement est "normal", puisque pour récupérer les évènements le composant doit avoir le focus. Lorsque la fenêtre s'affiche est a bien le focus, mais dès que tu cliques sur le bouton c'est ce dernier qui prend le focus...

    Quel est l'objectif de ce listener ?


    Sinon un petite remarque : pour quitter l'application lors de la fermeture, tu peux remplacer le WindowListener par cette simple ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    a++

  6. #6
    Membre chevronné Avatar de FredPsy
    Homme Profil pro
    Formateur en informatique
    Inscrit en
    Décembre 2006
    Messages
    285
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Formateur en informatique
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Décembre 2006
    Messages : 285
    Par défaut
    Hello,

    tu devrais implémenter un KeyListener sur ta classe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public class Test implements KeyListener
    {/**Tes méthodes et événements */
    }
    Ensuite tu ajoutes chaque composants au KeyListener avec la méthode
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    composant.addKeyListener(this);
    Je retouche ton code dans la journée pour te montrer.

  7. #7
    Membre chevronné Avatar de FredPsy
    Homme Profil pro
    Formateur en informatique
    Inscrit en
    Décembre 2006
    Messages
    285
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Formateur en informatique
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Décembre 2006
    Messages : 285
    Par défaut
    Voilà le code recrée.
    Compare le avec le tien pour voir les différences. (Quelques changements quand mê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
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
     
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
     
    public class Test extends JFrame implements KeyListener
        {
            /* Déclaration des composants */    
            private JPanel pane;
            private JButton Up;
     
            public static void main(String[] args)
                {
                    SwingUtilities.invokeLater(new Runnable()
                        {
                            public void run()
                                {
                                    Test frame = new Test();// Nouvel objet Test, appel du costructeur.
                                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// Comportement à la fermeture de la JFrame.
                                    frame.pack();
                                    frame.setVisible(true);
                                }
                        });
                }
     
            /** Constructeur de la classe */
            public Test()
                {
                    initialize();// Appel de la méthode.
                }
     
            /**
             * Cette méthode initialise la JFrame this
             * 
             * @return void
             */
            private void initialize()
                {
                    this.setSize(300, 200);// Taille de la Jframe si pack(), non utilisée.
                    this.setTitle("Test");// Titre de la fenêtre.
                    this.setContentPane(getPane());// Affectation du panel
                    this.setLocationRelativeTo(this.getParent());// position au milieu de l'écan
                }
     
            /**
             * Cette méthode initialise le JPanel : pane
             * 
             * @return javax.swing.JPanel
             */
            private JPanel getPane()
                {
                    pane = new JPanel();// Nouvel objet JPanel.
                    pane.setLayout(new BorderLayout());// Affectation du layout.
                    pane.add(getUp(), BorderLayout.CENTER);// le bouton Up est en position centrale.
     
                    /* Ajout du composant à l'écouteur KeyListener */
                    pane.addKeyListener(this);
     
                    return pane;
                }
            /**
             * Cette méthode initialise le Bouton : Up    
             *     
             * @return javax.swing.JButton    
             */
            private JButton getUp()
                {
                    Up = new JButton("Up");// Nouvel Objet JButton.
     
                    /* Ajout du composant à l'écouteur KeyListener */
                    Up.addKeyListener(this);
     
                    return Up;
                }
     
     
        /** Méthode de l'écouteur KeyListener */
        public void keyPressed(KeyEvent e)
            {
                // TODO Raccord de méthode auto-généré
                System.out.println("Key Pressed");
     
                /** Si tu veux qu'il se passe quelque chose selon le composant actif
                 * , utilise cette méthode. Je la laisse en commentaire. */
                /*if (e.getSource() == Up)
                    {
                        System.out.println ("Key pressed sur le bouton UP");
                    }
                if (e.getSource() == pane)
                    {
                        System.out.println("Key pressed sur le Panel pane");
                    }*/        
            }
     
        public void keyReleased(KeyEvent e)
            {
                // TODO Raccord de méthode auto-généré
     
            }
     
        public void keyTyped(KeyEvent e)
            {
                // TODO Raccord de méthode auto-généré
     
            }
     
        }
    Amuses toi bien Romain93.

  8. #8
    Membre confirmé Avatar de Romain93
    Inscrit en
    Septembre 2005
    Messages
    71
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 71
    Par défaut
    Super, ca marche, merci beaucoup. En plus le code est beaucoup plus clair comme ca! Je debute en Swing...

    Merci!

  9. #9
    Membre chevronné Avatar de FredPsy
    Homme Profil pro
    Formateur en informatique
    Inscrit en
    Décembre 2006
    Messages
    285
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Formateur en informatique
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Décembre 2006
    Messages : 285
    Par défaut
    De rien, moi aussi je débute. (Même pas qu'en swing ).
    J'avoue que j'ai galéré un moment avant de commencer à comprendre les mécanismes de ce beau language.

    Pour le développement Swing, j'utilise Eclipse avec le plugin Visual Editor et je pense que c'est très pratique pour comprendre tout ça.

    Bonne continuation.

    Au fait, dans le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    private JButton UP = null;
    le = null ne sert à rien, j'ai omis de l'enlever.

  10. #10
    Membre averti
    Inscrit en
    Janvier 2008
    Messages
    44
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 44
    Par défaut
    Bonjour

    J'ai le même type de soucis que romain93. J'aimerais intercepter la touche "PrintScreen" sur mon interface.
    D'après les réponses, je comprends qu'il faut ajouter le listener à chacun des composants de ma frame principale pour être sûr que l'élément en focus puisse intercepter l'action clavier.
    Cependant, ma frame contient plusieurs centaines de composants (voir plus) et j'ai un peu peur d'alourdir l'ensemble en ajoutant à chacun des composants le listener désiré.

    Qu'en pensez-vous ?
    Y aurait-il une autre solution ?

    Merci d'avance.
    Sophie

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

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    En utilisant l'AWTEventListener

    Ce listener voit passer tous les events de ton applis sans les intercepter

    Il s'utilise de la façon suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Toolkit.getDefaultToolkit().addAWTEventListener(
        new AWTEventListener(){
            public void eventDispatched(AWTEvent event){
                  KeyEvent ke = (KeyEvent)event;
                  if(ke.getID() == KeyEvent.KEY_RELEASED){
                      System.out.println("released");
                  }else if(ke.getID() == KeyEvent.KEY_PRESSED){
                      System.out.println("pressed");
                  }else if(ke.getID() == KeyEvent.KEY_TYPED){
                      System.out.println("typed");
                  }
            }
         }, AWTEvent.KEY_EVENT_MASK);

  12. #12
    Membre averti
    Inscrit en
    Janvier 2008
    Messages
    44
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 44
    Par défaut
    Merci beaucoup Sinok.
    Ca a l'air de bien fonctionner.

    Bonne fin de journée.

    Sophie

  13. #13
    Expert éminent
    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
    Billets dans le blog
    1
    Par défaut
    Salut,


    Pour associer une touche à une action sur toute l'interface il y a plus simple en passant par les InputMap/ActionMap.

    Cela se fait en deux étapes en associant la touches à un identifiant, puis en associant l'identifiant à une Action. Par exemple avec F2 :
    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
    	// On définit un identifiant pour notre action :
    	final String onF2Pressed = "onF2Pressed";
     
    	// On récupère la Map des touches de fonctions qui s'appliquera
    	// à tous les éléments fils lorsqu'ils auront le focus :
    	InputMap inputMap = frame.getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
     
    	// On associe la touche F2 avec un identifiant :
    	inputMap.put(KeyStroke.getKeyStroke("F2"),	onF2Pressed);
     
     
    	// On récupère la Map des actions qui associe une action à un identifiant :
    	ActionMap actionMap = frame.getRootPane().getActionMap();
     
    	// Et on associe notre action à notre identifiant :
    	actionMap.put(onF2Pressed,
    			new AbstractAction() {
    				@Override
    				public void actionPerformed(ActionEvent e) {
    					System.out.println("Print Screen !");
    				}
    			}
    	);
    Par contre cela ne marche pas avec "Print Screen"...
    Si l'identifiant "PRINTSCREEN" retourne bien le code pour la touche, mais elle n'est jamais intercepté ! D'ailleurs je n'arrive pas à l'intercepter même dans un KeyListener...

    Je me demande si ce n'est pas une restriction du système (il faudrait que je teste sous Linux pour voir si j'ai le même comportement).

    a++

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

Discussions similaires

  1. [AC-2007] Les boutons ne repondent pas sur un formulaire
    Par lemzaoui dans le forum IHM
    Réponses: 2
    Dernier message: 08/09/2014, 07h35
  2. Virtualbox ne repond pas sur Machine physique win 2008 r2
    Par Jonibigoudy dans le forum VirtualBox
    Réponses: 9
    Dernier message: 23/06/2011, 10h40
  3. KeyListener sur un JFrame
    Par aphilippartd dans le forum Débuter
    Réponses: 6
    Dernier message: 22/01/2009, 19h16
  4. debutant: un keyListener sur un objet non graphique
    Par ataya dans le forum API standards et tierces
    Réponses: 1
    Dernier message: 18/05/2006, 18h45
  5. [debutant] Questions sur 1 futur projet
    Par cyrull22 dans le forum XML/XSL et SOAP
    Réponses: 3
    Dernier message: 28/04/2003, 21h49

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