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 :

Association de touches spéciales


Sujet :

AWT/Swing Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite
    Avatar de divxdede
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    525
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2004
    Messages : 525
    Par défaut Association de touches spéciales
    Bonjour,

    J'ai une application avec plusieurs JInternalFrame.
    Chacune des JInternalFrame doivent gérer raccourcis de touches que sont
    - PAGE UP
    - PAGE DOWN

    Ces deux touches auront un comportement métier.

    Naïvement je pensais m'en sortir avec un code du style:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    Action    prevAction = ........;
    Action    nextAction = ........;
     
    InputMap  inputMap   = container.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
    ActionMap actionMap  = container.getActionMap();
     
    inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP , 0,"prev");
    inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN , 0,"suiv");
     
    actionMap.put("prev", prevAction );
    actionMap.put("suiv", nextAction );
    Sachant que "container" represente le "ContentPane" d'une JInternalFrame.

    Le problème:
    - Les JScrollPane attrapes avant moi l'evenement liés aux touches PAGE_UP / PAGE_DOWN pour gérer l'avancement des barres de défilements.

    Comment m'en sortir simplement sachant que je ne sais pas d'avance ce qui sera construit "graphiquement" a l'interieur de la JInternalFrame ?

  2. #2
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Par défaut
    Voici un petit lien qui pourra t'être utile.
    Ca t'explique comment fonctionne tout ça, et notamment ce passage :
    If more than one binding exists for the key, only the first valid one found is used. Input maps are checked in this order:

    1) The focused component's WHEN_FOCUSED input map.
    2) The focused component's WHEN_ANCESTOR_OF_FOCUSED_COMPONENT input map.
    3) The WHEN_ANCESTOR_OF_FOCUSED_COMPONENT input maps of the focused component's parent, and then its parent's parent, and so on, continuing up the containment hierarchy. Note: Input maps for disabled components are skipped.
    4) The WHEN_IN_FOCUSED_WINDOW input maps of all the enabled components in the focused window are searched. Because the order of searching the components is unpredictable, avoid duplicate WHEN_IN_FOCUSED_WINDOW bindings!
    Dans ton cas, je pense que les WHEN_FOCUSED input map des scrollbars captent l'évènement avant tout le reste.

    Une solution qui pourrait marcher : désactiver les entrées "Pages prec." et "Page suiv." dans les input map de tes scrollpanes...
    Je m'étais créé cette méthode statique pour ajouter un KeyBinding à un composant quelconque :
    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
     
    	/**
             * Méthode permettant d'ajouter un couple KeyStroke - Action au composant
             * passé en paramètre.
             * Utilisé pour faire du Key Binding.
             * cf http://java.sun.com/docs/books/tutorial/uiswing/misc/keybinding.html
             * 
             * @param KeyStroke ks : la combinaison de touches associée à l'action
             * @param AbstractAction action : l'action à exécuter lors de la combinaison de touches
             * @param inputMapType : le contexte dans lequel on doit exécuter l'action
             * lorsqu'on détecte la combinaison de touches.
             * 
             * Le paramètre inputMapType peut avoir les valeurs :
             *    - JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
             *    - JComponent.WHEN_IN_FOCUSED_WINDOW
             *    - JComponent.WHEN_FOCUSED
             */
    	public static void setKeyStrokeAction(JComponent component, KeyStroke ks, AbstractAction action, int inputMapType) {
    		/** Récupération de l'InputMap correspondant au type passé en paramètre*/
    		InputMap im = component.getInputMap(inputMapType);
     
    		/** Récupération de l'ActionMap de la dialog */
    		ActionMap am = component.getActionMap();
    		if (am == null)
    			am = new ActionMap();
     
    		/** Récupération des Command associées aux KeyStroke qui nous intéressent */
    		Object command = im.get(ks);
    		if (command == null) {
    			command = new Object();
    			im.put(ks, command);
    		}
     
    		/** Ajout du couple KeyStroke - Action */
    		am.put(command, action);
    	}
    Je dirai qu'on peut l'adapter pour enlever un KeyBinding, en faisant quelque chose comme ceci (non-testé...) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    	public static void removeKeyStrokeEntry(JComponent component, KeyStroke ks, int inputMapType) {
    		/** Récupération de l'InputMap correspondant au type passé en paramètre*/
    		InputMap im = component.getInputMap(inputMapType);
     
    		/** Suppression de l'entrée ks */
    		im.remove(ks);
    	}
    En espérant que ça fonctionne...

  3. #3
    Membre émérite
    Avatar de divxdede
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    525
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2004
    Messages : 525
    Par défaut
    Merci beaucoup.
    Cela m'a permis de bien éclaircir le mécanisme général de "key bindings" en swing.

    Cependant j'ai de ce fait essayé ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    Action    prevAction = ........;
    Action    nextAction = ........;
     
    removePageUpAndPageDownKeyBindings( container );
     
    InputMap  inputMap   = container.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
    ActionMap actionMap  = container.getActionMap();
     
    inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP , 0,"prev");
    inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN , 0,"suiv");
     
    actionMap.put("prev", prevAction );
    actionMap.put("suiv", nextAction );


    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
    private static void removePageUpAndPageDownKeyBindings(Container container)
    {
        if( container instanceof JInternalFrame )
        {
            removePageUpAndPageDownKeyBindings( ((JInternalFrame)container).getContentPane() );
            return;
        }
     
        if( container instanceof JComponent )
        {
            System.out.println("Removing PAGE_UP / PAGE_DOWN key bindings on " + container.getClass() + " instance");
     
            JComponent c = (JComponent)container;
            c.getInputMap( JComponent.WHEN_FOCUSED ).remove( KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP , 0 ) );
            c.getInputMap( JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT ).remove( KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP , 0 ) );
            c.getInputMap( JComponent.WHEN_IN_FOCUSED_WINDOW ).remove( KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP , 0 ) );
     
            c.getInputMap( JComponent.WHEN_FOCUSED ).remove( KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN , 0 ) );
            c.getInputMap( JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT ).remove( KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN , 0 ) );
            c.getInputMap( JComponent.WHEN_IN_FOCUSED_WINDOW ).remove( KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN , 0 ) );
        }
     
        /** Remove key bindings on all childs
         */
        for(int i = 0 ; i < container.getComponentCount() ; i++ )
        {
            /** JComponent extends Container
             */
            if( container.getComponent(i) instanceof Container )
                removePageUpAndPageDownKeyBindings( (Container)container.getComponent(i) );
        }
    }
    Ce test est un échec.
    Afin de verifier ma séquence faisant la liaison, j'ai essayé de faire l'association sur PAGE_UP + SHIFT et cela fonctionne correctement.

    Ce qui veut dire que ma tentative de removePageUpAndPageDownKeyBindings ne nettoie pas tout ce qu'il faut...

  4. #4
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Par défaut
    As-tu essayé de rajouter tes 2 KeyStroke dans les autres InputMap de ton container ?

  5. #5
    Membre émérite
    Avatar de divxdede
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    525
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2004
    Messages : 525
    Par défaut
    Citation Envoyé par seiryujay
    As-tu essayé de rajouter tes 2 KeyStroke dans les autres InputMap de ton container ?
    Je viens de faire le test, cela ne fonctionne pas même dans les 3 inputMap.
    Mais si je change le KeyStroke (exemple PAGE_UP + SHIFT) alors ca fonctionne en l'etat (avec le code donné)

  6. #6
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Par défaut
    Si ton container est une JFrame, essaie avec ç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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
    	/**
             * Méthode permettant d'ajouter un couple KeyStroke - Action à la Dialog.
             * Utilisé pour faire du Key Binding.
             * cf http://java.sun.com/docs/books/tutorial/uiswing/misc/keybinding.html
             * 
             * @param KeyStroke ks : la combinaison de touches associée à l'action
             * @param AbstractAction action : l'action à exécuter lors de la combinaison de touches
             * @param inputMapType : le contexte dans lequel on doit exécuter l'action
             * lorsqu'on détecte la combinaison de touches.
             * 
             * Le paramètre inputMapType peut avoir les valeurs :
             *    - JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
             *    - JComponent.WHEN_IN_FOCUSED_WINDOW
             *    - JComponent.WHEN_FOCUSED
             */
    	public void setKeyStrokeAction(KeyStroke ks, AbstractAction action, int inputMapType) {
    		/** Récupération de l'InputMap correspondant au type passé en paramètre*/
    		InputMap im = getRootPane().getInputMap(inputMapType);
     
    		/** Récupération de l'ActionMap de la dialog */
    		ActionMap am = getRootPane().getActionMap();
    		if (am == null)
    			am = new ActionMap();
     
    		/** Ajout du couple KeyStroke - Action */
    		Object command = new Object();
    		im.put(ks, command);
    		am.put(command, action);
    	}
    C'est le code que j'applique pour les JFrame : il faut récupérer l'ActionMap du rootPane...

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 07/11/2007, 10h06
  2. Réponses: 9
    Dernier message: 28/09/2007, 08h54
  3. comment associer la touche Enter à un bouton
    Par cerco1 dans le forum AWT/Swing
    Réponses: 18
    Dernier message: 15/08/2007, 12h44
  4. Intercepter l'appui sur les touches spéciales
    Par Mayhem dans le forum Windows
    Réponses: 1
    Dernier message: 05/01/2006, 20h31

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