[英]Application wide keyboard shortcut - Java Swing
I would like to create an application wide keyboard shortcut for a Java Swing application.我想为 Java Swing 应用程序创建一个应用程序范围的键盘快捷键。 Looping over all components and adding the shortcut on each, has focus related side effects, and seems like a brute force solution.
遍历所有组件并在每个组件上添加快捷方式,具有与焦点相关的副作用,并且看起来像是蛮力解决方案。
Anyone has a cleaner solution?有人有更清洁的解决方案吗?
For each window, use JComponent.registerKeyboardAction
with a condition of WHEN_IN_FOCUSED_WINDOW
.对于每个 window,使用条件为
WHEN_IN_FOCUSED_WINDOW
的JComponent.registerKeyboardAction
。 Alternatively use:或者使用:
JComponent.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(keyStroke, command);
JComponent.getActionMap().put(command,action);
as described in the registerKeyboardAction API docs .如registerKeyboardAction API 文档中所述。
Install a custom KeyEventDispatcher.安装自定义 KeyEventDispatcher。 The KeyboardFocusManager class is also a good place for this functionality.
KeyboardFocusManager class 也是此功能的好地方。
For people wondering (like me) how to use KeyEventDispatcher, here is an example that I put together.对于想知道(像我一样)如何使用 KeyEventDispatcher 的人,这里是我整理的一个示例。 It uses a HashMap for storing all global actions, because I don't like large
if (key ==..) then.. else if (key ==..) then.. else if (key ==..)..
constructs.它使用 HashMap 来存储所有全局操作,因为我不喜欢大的
if (key ==..) then.. else if (key ==..) then.. else if (key ==..)..
构造。
/** map containing all global actions */
private HashMap<KeyStroke, Action> actionMap = new HashMap<KeyStroke, Action>();
/** call this somewhere in your GUI construction */
private void setup() {
KeyStroke key1 = KeyStroke.getKeyStroke(KeyEvent.VK_A, KeyEvent.CTRL_DOWN_MASK);
actionMap.put(key1, new AbstractAction("action1") {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Ctrl-A pressed: " + e);
}
});
// add more actions..
KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
kfm.addKeyEventDispatcher( new KeyEventDispatcher() {
@Override
public boolean dispatchKeyEvent(KeyEvent e) {
KeyStroke keyStroke = KeyStroke.getKeyStrokeForEvent(e);
if ( actionMap.containsKey(keyStroke) ) {
final Action a = actionMap.get(keyStroke);
final ActionEvent ae = new ActionEvent(e.getSource(), e.getID(), null );
SwingUtilities.invokeLater( new Runnable() {
@Override
public void run() {
a.actionPerformed(ae);
}
} );
return true;
}
return false;
}
});
}
The use of SwingUtils.invokeLater() is maybe not necessary, but it is probably a good idea not to block the global event loop.使用 SwingUtils.invokeLater() 可能不是必需的,但最好不要阻塞全局事件循环。
When you have a menu, you can add global keyboard shortcuts to menu items:当你有一个菜单时,你可以将全局键盘快捷键添加到菜单项:
JMenuItem item = new JMenuItem(action);
KeyStroke key = KeyStroke.getKeyStroke(
KeyEvent.VK_R, KeyEvent.CTRL_DOWN_MASK);
item.setAccelerator(key);
menu.add(item);
A little simplified example:一个简单的例子:
KeyboardFocusManager keyManager;
keyManager=KeyboardFocusManager.getCurrentKeyboardFocusManager();
keyManager.addKeyEventDispatcher(new KeyEventDispatcher() {
@Override
public boolean dispatchKeyEvent(KeyEvent e) {
if(e.getID()==KeyEvent.KEY_PRESSED && e.getKeyCode()==27){
System.out.println("Esc");
return true;
}
return false;
}
});
Use the following piece of code使用下面的一段代码
ActionListener a=new ActionListener(){
public void actionPerformed(ActionEvent ae)
{
// your code
}
};
getRootPane().registerKeyboardAction(a,KeyStroke.getKeyStroke("ctrl D"),JComponent.WHEN_IN_FOCUSED_WINDOW);
Replace "ctrl D" with the shortcut you want.将“ctrl D”替换为您想要的快捷方式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.