Java 密钥绑定不起作用
我让JButton通过ActionListener执行一些操作。在我尝试使用Action绑定一个键盘快捷键(如下所示)后,鼠标点击按钮可以工作,但对键盘并没有反应 前代码 在面板中创建的按钮,添加了actionListenerJava 密钥绑定不起作用,java,swing,key-bindings,Java,Swing,Key Bindings,我让JButton通过ActionListener执行一些操作。在我尝试使用Action绑定一个键盘快捷键(如下所示)后,鼠标点击按钮可以工作,但对键盘并没有反应 前代码 在面板中创建的按钮,添加了actionListener private FooActionListener actionListener=new FooActionListener(); buttonLeft=新按钮(“左”); addActionListener(actionListener); 然后,在主类之外的FooA
private FooActionListener actionListener=new FooActionListener();
buttonLeft=新按钮(“左”);
addActionListener(actionListener);
然后,在主类之外的FooActionListener类中执行actionPerformed方法:
public void actionPerformed(ActionEvent e){
对象源=e.getSource();
if(source==buttonLeft){thing.move(Direction.LEFT);}
}
暗号
最后一个字符串leftText=“Left”;
左最终操作=新抽象操作(){
@凌驾
已执行的公共无效操作(操作事件e){
东西。移动(方向。左);
}
};
buttonLeft=新的JButton(左);
按钮left.setText(leftText);
KeyStroke keyLeft=击键.getKeyStroke(KeyEvent.VK_A,0);
buttonLeft.getInputMap(当在聚焦窗口中时buttonLeft.put).put(向左键,
“左”);
按钮Left.getActionMap().put(“左”,左);
更新:我不太确定新代码是否真的能在鼠标上正常运行。让我们假设该对象通过单击移动25个像素,并且在原始代码中确实如此。但是,对于新的操作,它似乎在每次单击时移动两次甚至三次,这表明某个操作有一些奇怪的行为。按钮可能会吸引你,但是,我会稍微改变一下 因为您已经正确地使用了
操作
,所以您的移动逻辑基本上已经集中化了
我只是将映射应用到主容器
public class TestKeybindings01 {
public static void main(String[] args) {
new TestKeybindings01();
}
public TestKeybindings01() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JLabel label;
private JButton left;
private JButton right;
public TestPane() {
label = new JLabel("Make a choice");
label.setHorizontalAlignment(JLabel.CENTER);
LeftAction leftAction = new LeftAction(label);
RightAction rightAction = new RightAction(label);
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0), "left");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0), "right");
ActionMap am = getActionMap();
am.put("left", leftAction);
am.put("right", rightAction);
left = new JButton(leftAction);
right = new JButton(rightAction);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 2;
gbc.anchor = GridBagConstraints.CENTER;
gbc.fill = GridBagConstraints.HORIZONTAL;
add(label, gbc);
gbc.gridy++;
gbc.gridwidth = 1;
add(left, gbc);
gbc.gridx++;
add(right, gbc);
}
}
public abstract class AbstractDirectionAction extends AbstractAction {
private JLabel label;
public AbstractDirectionAction(JLabel label) {
this.label = label;
}
public JLabel getLabel() {
return label;
}
public void setDirection(String text) {
getLabel().setText(text);
}
}
public class LeftAction extends AbstractDirectionAction {
public LeftAction(JLabel label) {
super(label);
putValue(NAME, "<<");
}
@Override
public void actionPerformed(ActionEvent e) {
setDirection("Left");
}
}
public class RightAction extends AbstractDirectionAction {
public RightAction(JLabel label) {
super(label);
putValue(NAME, ">>");
}
@Override
public void actionPerformed(ActionEvent e) {
setDirection("Right");
}
}
}
公共类TestKeybindings01{
公共静态void main(字符串[]args){
新的TestKeybindings01();
}
公共TestKeybindings01(){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
试一试{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}catch(ClassNotFoundException |实例化Exception | IllegalacessException |不支持ookandfeelException ex){
}
JFrame=新JFrame(“测试”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(新的BorderLayout());
frame.add(newtestpane());
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
});
}
公共类TestPane扩展了JPanel{
私人标签;
私人按钮左;
私权;
公共测试窗格(){
标签=新的JLabel(“做出选择”);
标签设置水平对齐(JLabel.CENTER);
LeftAction LeftAction=新的LeftAction(标签);
RightAction RightAction=新的RightAction(标签);
InputMap im=getInputMap(在聚焦窗口中时);
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_A,0),“left”);
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_D,0),“right”);
ActionMap am=getActionMap();
am.put(“左”,左动作);
am.put(“正确”,正确行动);
左=新的JButton(左操作);
右=新的JButton(右操作);
setLayout(新的GridBagLayout());
GridBagConstraints gbc=新的GridBagConstraints();
gbc.gridx=0;
gbc.gridy=0;
gbc.gridwidth=2;
gbc.anchor=GridBagConstraints.CENTER;
gbc.fill=GridBagConstraints.HORIZONTAL;
添加(标签,gbc);
gbc.gridy++;
gbc.gridwidth=1;
添加(左,gbc);
gbc.gridx++;
添加(右,gbc);
}
}
公共抽象类AbstractDirectionAction扩展了AbstractAction{
私人标签;
公共抽象定向操作(JLabel标签){
this.label=标签;
}
公共JLabel getLabel(){
退货标签;
}
公共void setDirection(字符串文本){
getLabel().setText(文本);
}
}
公共类LeftAction扩展了AbstractDirectionAction{
公共LeftAction(JLabel标签){
超级(标签);
putValue(名称“”);
}
@凌驾
已执行的公共无效操作(操作事件e){
设定方向(“右”);
}
}
}
您能否详细说明这些映射的含义?另外,检查问题的更新,看看这是否暗示了什么。那么这个EventQueue.invokeLater业务是关于什么的呢?按钮实现可能正在“吸收”关键事件,这可能是它对助记符支持的一部分,阻止它为关键绑定引发事件。我能想到的重复发生这样的事件的唯一原因是你按下了键。之所以出现EventQueue.invokeLater
,是因为Swing是一个单线程API,对UI的所有更新都必须在事件调度线程中进行。当您执行main
时,可以保证您没有使用EDTA进行重复操作,我现在说的是鼠标点击。我使用与原始代码完全相同的鼠标单击,但它似乎在同一次单击中调用thing.move方法两次。有什么方法可以调试它吗?给你的应用程序添加一些诊断程序,并确定该操作是否执行了一次以上。@theUg