java - 在 Java 中使用键绑定(bind)和操作映射作为按钮的快捷键

标签 java swing key-bindings

我正在制作一个程序,我希望程序中的所有按钮都有快捷方式。示例 ctrl+a 执行按钮 1。

我还希望用户可以更改这些快捷方式

所以这是我用来添加键绑定(bind)的代码

   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);
        }
    });

现在,由于我希望用户可以更改这些内容,因此我希望能够使用第三行上的“BUTTON ONE ID”来获取其信息。我希望能够知道我输入的键是什么以及您是否需要按住 ctrl 或 alt 作为快捷方式

所以我想要以下代码

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 

}

如何使用“BUTTON ONE ID”执行此操作,或者这是一种更好的方法。谢谢

最佳答案

好的,这是一个关于如何允许用户生成自己的击键的快速示例。它基本上捕获 CTRLSHIFTALTMETA 键的状态并记录最后一个无“修饰符” “按键。

它提供了一个简单的 getKeyStroke 方法来返回由配置的状态生成的击键,在本例中,您会发现它在以下情况下打印 KeyStroke “键入”一个键,这是为了调试而完成的

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());
            }
        }

    }

}

现在,一切已经准备就绪。我在测试时让它打印了一些有趣的字符,因此您可能想要运行它并查看您可能想要过滤掉哪些键(提示 Caps Lock 可能是一个;))

现在,有了这个,您只需更改 InputMap

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

它会自动更新绑定(bind)

关于java - 在 Java 中使用键绑定(bind)和操作映射作为按钮的快捷键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46985936/

相关文章:

java - 如何在 JPanel.getComponents() 内循环时获取 JButton 属性

java - keyPressed 监听器产生奇怪的行为

java - Java REST 服务的生命周期和初始化

java - 如何在 Java 中下载 .msi 文件

java - Repaint() 方法不会重新绘制

wpf - 键绑定(bind) RelayCommand

emacs 艺术家模式绑定(bind)右键菜单

java - 具有键绑定(bind)的线程

java - Spring data neo4j 的 Cineasts 示例的错误

java - 如何更新 ConcurrentHashMap 线程安全中的值