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

允许用户在Java运行时重新定义Swing热键,java,swing,key-bindings,Java,Swing,Key Bindings,我有一个包含很多特性的Java应用程序,为了让用户的生活更轻松,我设置了许多助记符和加速器。例如,我有一个JMenuItem,它允许用户使用以下代码保存应用程序的状态: JMenuItem saveItem = new JMenuItem("Save"); saveItem.setMnemonic('S'); saveItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_MASK)); 这可以根据需

我有一个包含很多特性的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)的键。我还认为强制使用输入掩码可能是明智的,以避免文本字段等方面的复杂性


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

听起来您需要设置一个。当用户按下/释放一个键时,它会触发一个
KeyEvent
,您可以从中检索按下的主键(例如S)和掩码/修改器(例如CTRL+SHIFT)

从那里,您可以创建一个
击键
对象,并将其设置为菜单的新加速器

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

为什么不创建一个简单的“更改密钥绑定”对话框呢。然后使用InputEvent和KeyEvent的组合框显示当前助记符和加速器。然后,用户可以通过从组合框中选择不同的值来更改绑定。对于包含自定义键绑定的所有操作,您甚至可以使用简单的表格式执行此操作,这样用户可以一次更改所有值并查看当前值以避免混淆。@camickr,谢谢您的建议。我在考虑我可以采用的不同方法,并决定通过倾听用户的输入来提示用户输入他们想要使用的快捷方式,主要是为了遵守惯例。我正在开发的应用程序是一个游戏(或者至少是一个编辑器),我认为最好使用与其他游戏相同的方法。我喜欢反弹跳逻辑。:-)这本书中的概念是完美的。为了满足我的具体需求,我对它进行了一些研究,但这实际上只是在对象如何连接方面。谢谢你,这绝对是我想要的。