10

I am trying to make key bindings in Java on a JPanel. I want a certain action to execute when I press the 'w' button. I follow the Java tutorial on making bindings, but the actionPerformed method does not execute (i.e. no text prints out). The following is the entirety of the code for my test GUI, with the relevant part highlighted:

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;

@SuppressWarnings("serial")
public class Test extends JFrame{

private JPanel panel;

public Test(){
    super();
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setSize(500,500);
    setLayout(new BorderLayout());
    setVisible(true);        
    panel = new JPanel();

    // HERE ARE THE KEY BINDINGS
    panel.getInputMap().put(KeyStroke.getKeyStroke('w'),"forward");
    panel.getActionMap().put("forward", new AbstractAction(){
        @Override
        public void actionPerformed(ActionEvent e){
            System.out.println("test");
        }
    });
    // END OF KEY BINDINGS

    add(panel, BorderLayout.CENTER);
}

public static void main(String[] args){
    new Test();     
}

}

The text "test" is never printed. I have tried many times with many different variants, different keys, and I make sure the panel is in focus, but no luck. What am I doing wrong?

4

1 回答 1

20

问题是您查找KeyStroke. KeyStroke.getKeyStroke('w')将返回typed w,由于某种原因,它不会触发关键事件。这就是为什么我倾向于避免这种方法。而是使用

panel.getInputMap().put(KeyStroke.getKeyStroke("W"),"forward");

或者

panel.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0),"forward");

此外,您可能希望为 定义焦点约束InputMap,例如

panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)...

会更安全......但您需要确定您希望从哪个级别触发击键

有关更多详细信息,请参阅JComponent以及如何使用键绑定

更新了示例

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test extends JFrame {

    private JPanel panel;

    public Test() {
        super();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(500, 500);
        setLayout(new BorderLayout());
        setVisible(true);
        panel = new JPanel();

        // HERE ARE THE KEY BINDINGS
        panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), "forward");
        panel.getActionMap().put("forward", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("test");
            }
        });
        // END OF KEY BINDINGS

        add(panel, BorderLayout.CENTER);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                new Test();
            }
        });
    }
}
于 2013-08-01T03:48:10.503 回答