简体   繁体   中英

Allow user to redefine hotkeys for Swing during runtime Java

I have a Java application that contains a lot of features, and to make life easier for the user, I have set up numerous mnemonics and accelerators. For instance, I have a JMenuItem that allows the user to save the state of the application, witht he following code:

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

This works as desired, but now I would like to give the user an option to change the hot keys. While CTRL + s would seem like a fairly obvious hot key to stick with, there are many features that use these short cuts, and simply picked Save as an example.

I have a JButton that I have arranged for testing purposes that allows the user to enter in a new shortcut when clicked. I was thinking that I would simply try and capture the keys that the user holds down (InputEvent) and presses (KeyEvent). I also though it might be smart to force the use of an InputMask to avoid complications in Text Fields and the like.

What I am wondering is: What is the best way to capture the new input that the user enters? I have looked up information regarding KeyBindings and they look right for the job, but the main issue I see is actually capturing the keys and saving them.

Sounds like you need to setup a KeyListener . When the user presses/releases a key, it triggers a KeyEvent from which you can retrieve the main key pressed (eg S ) and the mask/modifiers (eg CTRL + SHIFT ).

From there you can create a KeyStroke object and set this as the new accelerator of your menu.

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

The thing is you probably want this key listener to be removed right after the key released event, to avoid multiple keystrokes to be captured. So you could have this kind of logic:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM