Java Key Bindings Not Working

隐身守侯 提交于 2019-12-30 08:26: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?


回答1:


The problem is the way in which you are looking up the KeyStroke. KeyStroke.getKeyStroke('w') will return typed w, which for some reason, doesn't trigger a key event. This is why I tend to avoid this method. Instead use

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

or

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

Also, you may want to define the focus constraint for the InputMap, something like

panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)...

Would be safer...but you will need to decided at what level you want the key strokes to triggered from

See JComponent and How to use Key Bindings for more details

Updated with example

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();
            }
        });
    }
}


来源:https://stackoverflow.com/questions/17984912/java-key-bindings-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!