允许用户在运行时为 Swing 重新定义热键 Java

Allow user to redefine hotkeys for Swing during runtime Java

我有一个包含很多功能的 Java 应用程序,为了方便用户使用,我设置了许多助记符和加速器。例如,我有一个 JMenuItem 允许用户使用以下代码保存应用程序的状态:

JMenuItem saveItem = new JMenuItem("Save");
saveItem.setMnemonic('S');
saveItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_MASK)); 

这可以正常工作,但现在我想为用户提供更改热键的选项。虽然 CTRL + s 似乎是一个相当明显的热键,但有许多使用这些快捷方式的功能,并简单地选择保存作为示例。

我为测试目的安排了一个 JButton,它允许用户在单击时输入新的快捷方式。我在想我会简单地尝试捕获用户按住 (InputEvent) 和按下 (KeyEvent) 的键。我也认为强制使用 InputMask 以避免文本字段等的复杂性可能是明智的。

我想知道的是:捕获用户输入的新输入的最佳方式是什么?我已经查找了有关 KeyBindings 的信息,它们看起来很适合这项工作,但我看到的主要问题实际上是捕获密钥并保存它们。

听起来您需要设置一个 KeyListener。当用户 presses/releases 一个键时,它会触发一个 KeyEvent,您可以从中检索按下的主键(例如 S)和 mask/modifiers(例如 CTRL+SHIFT).

从那里您可以创建一个 KeyStroke 对象并将其设置为菜单的新快捷键。

public void keyReleased(KeyEvent e){
   KeyStroke ks = KeyStroke.getKeyStroke(e.getKeyCode(), e.getModifiers());
   menuItem.setAccelerator(ks);
}

问题是您可能希望在键释放事件之后立即删除此键侦听器,以避免捕获多个键击。所以你可以有这样的逻辑:

JButton captureKeyButton = new JButton("Capture key");
JLabel captureText = new JLabel("");
KeyListener keyListener = new KeyAdapter(){
   public void keyReleased(KeyEvent e){
       KeyStroke ks = KeyStroke.getKeyStroke(e.getKeyCode(), e.getModifiers());
       menuItem.setAccelerator(ks);
       captureText.setText("Key captured: "+ks.toString());
       captureKeyButton.removeKeyListener(this);
   }
};
ActionListener buttonClicked = new ActionListener(){
   public void actionPerformed(ActionEvent e){
       captureKeyButton.addKeyListener(keyListener);
       captureText.setText("Please type a menu shortcut");
   }
};
captureKeyButton.addActionListener(buttonClicked);