using keybinding and Action Map in Java for shortcut keys for buttons

帅比萌擦擦* 提交于 2020-01-24 21:51:50

问题


I am making a program where I want to have shortcuts for all the buttons in my program. example ctrl+a executes button 1.

I also want these shortcuts to be user changeable

so this is the code i am using to add a key binding

   InputMap IM = component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);

   IM.put(KeyStroke.getKeyStroke(KeyEvent.VK_B, InputEvent.CTRL_DOWN_MASK | 
          InputEvent.ALT_DOWN_MASK), "BUTTON ONE ID");

  ActionMap actionMap = component.getActionMap();
    actionMap.put("BUTTON ONE ID", new AbstractAction() {
        @Override
        public void actionPerformed(ActionEvent e) {
            actionListener.actionPerformed(e);
        }
    });

Now since i want these to be user changeable, i want to be able to use the "BUTTON ONE ID" on the third line to get its information. I want to be able to know what key i entered for it and whether or not you need to hold ctrl or alt for the shortcut

so i would want the following code

if("BUTTON ONE ID"){
  //print KeyEvent/keyCode info and if we need to hold ctrl, alt or shift?
  //and then i want to be able to change the key bindings 

}

How do I do this using the "BUTTON ONE ID" or is their a better way of doing this. Thanks


回答1:


Okay, this a quick example of how you might allow the user to generate their own key strokes. It basically captures the state of the CTRL, SHIFT, ALT and META keys and records the last none "modifier" key press.

It provides a simple getKeyStroke method to return the key stroked that would be generated by the configured states, in this example, you will find that it prints the KeyStroke when a key is "typed", which is done for debugging

import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;

public class ExampleLKeyConfig {

    public static void main(String[] args) {
        new ExampleLKeyConfig();
    }

    public ExampleLKeyConfig() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new KeyCapturePane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class KeyCapturePane extends JPanel {

        private JToggleButton ctrlKey;
        private JToggleButton altKey;
        private JToggleButton shiftKey;
        private JToggleButton metaKey;
        private JButton strokeKey;

        private int keyCode;

        public KeyCapturePane() {
            setBorder(new EmptyBorder(10, 10, 10, 10));
            setLayout(new GridBagLayout());

            ctrlKey = new JToggleButton(KeyEvent.getModifiersExText(KeyEvent.CTRL_DOWN_MASK));
            altKey = new JToggleButton(KeyEvent.getModifiersExText(KeyEvent.ALT_DOWN_MASK));
            shiftKey = new JToggleButton(KeyEvent.getModifiersExText(KeyEvent.SHIFT_DOWN_MASK));
            metaKey = new JToggleButton(KeyEvent.getModifiersExText(KeyEvent.META_DOWN_MASK));
            strokeKey = new JButton("-");

            updateMetaState(new KeyEvent(this, 0, 0, 0, 0, ' '));

            add(ctrlKey);
            add(altKey);
            add(shiftKey);
            add(metaKey);
            add(strokeKey);

            setFocusable(true);
            addKeyListener(new KeyAdapter() {

                @Override
                public void keyPressed(KeyEvent e) {
                    updateMetaState(e);
                    int code = e.getKeyCode();
                    if (code != KeyEvent.VK_CONTROL && code != KeyEvent.VK_ALT && code != KeyEvent.VK_SHIFT && code != KeyEvent.VK_META) {
                        strokeKey.setText(KeyEvent.getKeyText(code));
                        keyCode = code;
                    }
                }

                @Override
                public void keyReleased(KeyEvent e) {
                }

                @Override
                public void keyTyped(KeyEvent e) {
                    System.out.println(getKeyStroke());
                }

            });

            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    requestFocusInWindow();
                }
            });
        }

        protected int getModifiers() {
            return (ctrlKey.isSelected() ? KeyEvent.CTRL_DOWN_MASK : 0)
                            | (altKey.isSelected() ? KeyEvent.ALT_DOWN_MASK : 0)
                            | (shiftKey.isSelected() ? KeyEvent.SHIFT_DOWN_MASK : 0)
                            | (metaKey.isSelected() ? KeyEvent.META_DOWN_MASK : 0);
        }

        public KeyStroke getKeyStroke() {
            return KeyStroke.getKeyStroke(keyCode, getModifiers());
        }

        protected void updateMetaState(KeyEvent evt) {
            updateMetaState(ctrlKey, evt.isControlDown());
            updateMetaState(altKey, evt.isAltDown());
            updateMetaState(shiftKey, evt.isShiftDown());
            updateMetaState(metaKey, evt.isMetaDown());
        }

        protected void updateMetaState(JToggleButton btn, boolean isPressed) {
            if (isPressed) {
                btn.setSelected(!btn.isSelected());
            }
        }

    }

}

Now, this is rough and ready. I had it print some interesting characters while I was testing so you might want to run through it and see which keys you might want to filter out (hint Caps Lock might be one ;))

Now, with this in hand, you just need to change the InputMap

KeyStroke ks = ...;
IM.put(ks, "BUTTON ONE ID");

and it will automatically update the bindings



来源:https://stackoverflow.com/questions/46985936/using-keybinding-and-action-map-in-java-for-shortcut-keys-for-buttons

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!