我一直在尝试使用箭头键作为我的应用程序的一部分。按照最佳实践,我坚持使用键绑定。我发现arow键不会产生键入事件,所以我使用了这个answer。
但是,我的应用程序有许多组件,我发现如果我的JFrame中有一个JToolbar,则前一个链接中的方法不再有效。为什么这样,我如何使用JToolbar并使用键绑定?
这是SSCCE
public class ArrowTest extends JFrame {
public static void main(final String[] args){
final ArrowTest at = new ArrowTest();
at.setSize(100,200);
final JPanel jp = new JPanel();
jp.setBackground(Color.BLUE);
at.getContentPane().add(jp);
final JToolBar toolbar = new JToolBar();
toolbar.add(new JButton());
//at.add(toolbar);
at.setVisible(true);
}
public ArrowTest() {
super();
this.getContentPane().setLayout(new GridBagLayout());
this.getContentPane().setBackground(Color.BLACK);
this.setKeyBindings();
}
public void setKeyBindings() {
final int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
final ActionMap actionMap = this.getRootPane().getActionMap();
final InputMap inputMap = this.getRootPane().getInputMap(condition);
for (final Direction direction : Direction.values()) {
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_V,0), direction.getText());
inputMap.put(direction.getKeyStroke(), direction.getText());
actionMap.put(direction.getText(), new MyArrowBinding(direction.getText()));
}
}
enum Direction {
UP("Up", KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0)),
DOWN("Down", KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0)),
LEFT("Left", KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0)),
RIGHT("Right", KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0));
Direction(final String text, final KeyStroke keyStroke) {
this.text = text;
this.keyStroke = keyStroke;
}
private String text;
private KeyStroke keyStroke;
public String getText() {
return text;
}
public KeyStroke getKeyStroke() {
return keyStroke;
}
@Override
public String toString() {
return text;
}
}
private class MyArrowBinding extends AbstractAction {
private static final long serialVersionUID = -6904517741228319299L;
public MyArrowBinding(final String text) {
super(text);
putValue(ACTION_COMMAND_KEY, text);
}
@Override
public void actionPerformed(final ActionEvent e) {
final String actionCommand = e.getActionCommand();
System.out.println("Key Binding: " + actionCommand);
}
}
}
答案 0 :(得分:4)
默认情况下,JToolBar
会为KeyStroke的向上/向下/向左/向右注册一个动作,而您添加到JToolBar
的{{1}}会自动抓取焦点,因此您不会绑定到rootpane时会看到任何内容(工具栏会在你之前捕获事件)。
一种解决方案是让JFrame
和JToolBar
无法集中,让您的JButton
可以集中精力(实际上您可以离开JPanel
和{{1请求专注于您的面板,但这也意味着您必须处理面板的焦点管理):
JToolBar
我也通过拨打JButton
import java.awt.Color;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;
public class ArrowTest extends JFrame {
public static void main(final String[] args) {
final ArrowTest at = new ArrowTest();
at.setSize(100, 200);
final JPanel jp = new JPanel();
jp.setBackground(Color.BLUE);
jp.setFocusable(true);
at.getContentPane().add(jp);
final JToolBar toolbar = new JToolBar();
JButton comp = new JButton();
toolbar.add(comp);
at.add(toolbar);
at.setVisible(true);
}
public ArrowTest() {
super();
this.getContentPane().setLayout(new GridBagLayout());
this.getContentPane().setBackground(Color.BLACK);
this.setKeyBindings();
}
public void setKeyBindings() {
for (final Direction direction : Direction.values()) {
MyArrowBinding binding = new MyArrowBinding(direction.getText());
getRootPane().registerKeyboardAction(binding, direction.getText(), direction.getKeyStroke(),
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
}
}
enum Direction {
UP("Up", KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0)), DOWN("Down", KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0)), LEFT("Left",
KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0)), RIGHT("Right", KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0));
Direction(final String text, final KeyStroke keyStroke) {
this.text = text;
this.keyStroke = keyStroke;
}
private String text;
private KeyStroke keyStroke;
public String getText() {
return text;
}
public KeyStroke getKeyStroke() {
return keyStroke;
}
@Override
public String toString() {
return text;
}
}
private class MyArrowBinding extends AbstractAction {
private static final long serialVersionUID = -6904517741228319299L;
public MyArrowBinding(final String text) {
super(text);
putValue(ACTION_COMMAND_KEY, text);
}
@Override
public void actionPerformed(final ActionEvent e) {
final String actionCommand = e.getActionCommand();
System.out.println("Key Binding: " + actionCommand);
}
}
}
的来电
答案 1 :(得分:1)
按照answer中的建议,我使用
解决了这个问题public void setKeyBindings() {
final int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
final ActionMap actionMap = this.getRootPane().getActionMap();
final InputMap inputMap = this.getRootPane().getInputMap(condition);
for (final Direction direction : Direction.values()) {
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_V,0), direction.getText());
inputMap.put(direction.getKeyStroke(), direction.getText());
actionMap.put(direction.getText(), new MyArrowBinding(direction.getText()));
}
condition = JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT;
actionMap = toolbar.getActionMap();
inputMap = toolbar.getInputMap(condition);
for (final Direction direction : Direction.values()) {
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_V,0), direction.getText());
inputMap.put(direction.getKeyStroke(), direction.getText());
actionMap.put(direction.getText(), new MyArrowBinding(direction.getText()));
}
}