Comment assigner Enter comme clé de déclenchement de tous les boutons JButton de mon application Java?

StackOverflow https://stackoverflow.com/questions/440209

  •  22-07-2019
  •  | 
  •  

Question

J'écris une application Java Swing à l'aide de l'aspect et de la convivialité de Metal. Chaque fois qu'il y a un bouton JButton dans mon application, l'utilisateur utilise la touche de tabulation pour déplacer le focus sur le bouton, puis appuie sur la touche Entrée. Rien ne se passe! S'il appuie sur la touche Espace, les événements du bouton sont déclenchés. Comment assigner la touche Entrée pour déclencher les mêmes événements que la touche Espace? Merci pour votre aide.

Était-ce utile?

La solution

J'ai trouvé ce qui suit:

http://tips4java.wordpress.com/2008 / 10/25 / enter-key-and-button /

Où Rob Camick écrit que, lorsque vous utilisez JDK5 et versions ultérieures, vous ajoutez simplement ...

UIManager.put("Button.defaultButtonFollowsFocus", Boolean.TRUE);

... à l'application pour résoudre le problème. Cela a fait le tour pour moi! Et je ne peux rien imaginer de plus simple. Cependant, lorsque vous utilisez des versions plus anciennes de Java, vous devrez procéder comme décrit par Richard et Peter dans leurs réponses à cette question.

Autres conseils

Voici un exemple complet. Richard était proche, mais vous devez également mapper la touche ENTER appuyée sur l'action, pas seulement la publier. Pour que cela fonctionne avec TOUS les boutons, j'ai mis cette correspondance sur la carte d'entrée par défaut pour les boutons. Ajouter des importations, et il devrait être exécutable.

public class Main implements Runnable {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Main());
    }

    @Override
    public void run() {
        setupEnterActionForAllButtons();

        JFrame frame = new JFrame("Button test");
        frame.getContentPane().add(createButton(), BorderLayout.NORTH);
        frame.getContentPane().add(createButton(), BorderLayout.SOUTH);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setVisible(true);
    }

    private void setupEnterActionForAllButtons() {
        InputMap im = (InputMap) UIManager.getDefaults().get("Button.focusInputMap");
        Object pressedAction = im.get(KeyStroke.getKeyStroke("pressed SPACE"));
        Object releasedAction = im.get(KeyStroke.getKeyStroke("released SPACE"));

        im.put(KeyStroke.getKeyStroke("pressed ENTER"), pressedAction);
        im.put(KeyStroke.getKeyStroke("released ENTER"), releasedAction);
    }

    private JButton createButton() {
        JButton b = new JButton("press enter");
        b.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Pressed");
            }
        });

        return b;
    }
}

En fait, il s’agit d’un problème d’apparence. C'est (et devrait être) à la hauteur de la touche qui déclenche le bouton ciblé.

Le " bouton par défaut " La solution de contournement fonctionne puisque la L & F que vous utilisez utilise enter pour le bouton par défaut.

La solution de rechange de Peter modifie explicitement l'action & focus "action de mise au point" par défaut de L & F; clé - ce qui est un peu plus convaincant si vous me demandez.

J'ajouterais que je ne pense pas que de nombreux utilisateurs voudraient appuyer sur le bouton, puis appuyer sur Entrée (la plupart des utilisateurs ne remarqueront même pas l'indicateur de focus). Ils souhaitent que l'action par défaut soit la "droite". un et travailler partout où ils appuient sur entrer. Cela ne peut être fait qu'avec des cartes d'entrée, comme le suggère Richard.

Je suggérerais certainement d'obtenir une image très claire de ce que vos utilisateurs veulent et attendent réellement (de préférence en se référant à d'autres applications qu'ils utilisent) avant de modifier quoi que ce soit au niveau mondial.

Vous le faites en affectant une carte d’entrée / action à la touche Entrée. Quelque chose comme ce qui suit:

// save the command mapping for space
Object spaceMap = button.getInputMap.get(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, true));
// add a mapping from enter to the same command.
button.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, true),spaceMap); 

Vous pouvez également définir le " bouton par défaut " au bouton le plus récemment focalisé.

Je l'ai fait sur une application et toutes les méthodes pour le faire sont un cauchemar à maintenir et à déboguer. Le fait est que ce n’est clairement pas ce que les concepteurs de Swing avaient l’intention de faire.

Extension aux réponses ci-dessus pour faire la même chose avec la radio, cases à cocher. Appelé avant la création de composants

void setupEnterAction(String componentName){
    String keyName = componentName + ".focusInputMap";
    InputMap im = (InputMap) UIManager.getDefaults().get(keyName);
    Object pressedAction = im.get(KeyStroke.getKeyStroke("pressed SPACE"));
    Object releasedAction = im.get(KeyStroke.getKeyStroke("released SPACE"));
    im.put(KeyStroke.getKeyStroke("pressed ENTER"), pressedAction);
    im.put(KeyStroke.getKeyStroke("released ENTER"), releasedAction);
}

public void setEnterEvent(){
    setupEnterAction("Button");
    setupEnterAction("RadioButton");
    setupEnterAction("CheckBox");
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top