问题
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