keylistener 没有响应任何键?

keylistener is not responding to any keys?

我正在尝试为响应 "w" 键的玩家移动脚本编写一个简单的按键事件。我希望最终让它做一些像移动角色这样的事情,但现在我只是想让它做出回应。我对 java 比较陌生,所以请详细说明。另请注意,当我真正开始工作时,播放器不会成为文本区域我只是还不想显示图像和动画。我已经包含了很多评论来解释我在每一行上试图做的事情。希望有帮助!到目前为止,这是我的代码:

import javax.swing.*; //importing swing for gui stuff
import java.awt.*; //importing awt for gui stuff
import java.awt.event.*; //importing awt event so i can add listeners

public class game { //creates the class

    static String player = "Player"; //initializes the variable for text i will put in the text area

    public static void main(String args[]) { //making a function (main) to run automatically and initialize the game

        JFrame f = new JFrame("Javax Swing UI"); //create frame for GUI
        GridLayout l = new GridLayout(2,4);
        f.setSize(300,300); //set the size of the frame in pixels x,y
        JTextArea t = new JTextArea(5,10); //create a text area to act as the player for the game (until i get an image working)
        t.append(player);
        t.setEditable(false); //make it so you cant edit the text area
        f.add(t);
        f.setLayout(l);
        f.setVisible(true); //load the frame and all objects inside it

    }

    public static void movement(JTextArea t) { //creating a method for moving my "character"
        t.addKeyListener(new KeyAdapter() { //adding key listener to my text area
            public void keyPressed(KeyEvent e) { //creating the method to respond to my key listener
                int key = e.getKeyCode(); //getting the key the user types
                if (key == KeyEvent.VK_W) { //checking if the key is "w"
                    System.out.println("if key == w !!! working"); //prints that the if statement is working
                }

            }

        });

    }

}

没有错误,编译正常,运行正常,但键盘监听器没有响应 "w" 键。我认为它与关键代码或我的逻辑语句有关。我稍后会担心格式化,但正如我所说,我只是想让 keyevent 起作用。如果在 java 方面更有经验的人可以提供帮助,那就太好了! (我正在使用 java 8)。

编辑 [已解决]:我已经开始使用 KeyStrokes 编写出@DontKnowMuchButGetting Better 的答案,并且我 运行 解决了这个问题:

java:9: error: ';' expected
                       public void actionPerformed(ActionEvent e) {

java:9: error: ';' expected
                       public void actionPerformed(ActionEvent e) {
                                                                ^
2 errors

抛出错误的代码看起来有点像这样:

public class move extends AbstractAction {

        public static void main(int right, int down) {

            int right = right;
            int down = down;

            @Override
            public void actionPerformed(ActionEvent e) {

                x += right * 4;
                y += down * 4;
                repaint();
            }

        }


    }

编辑: 解决了上次编辑,做了一些工作,我现在收到这些错误:

game.java:39: error: cannot find symbol
                String whenfocused = WHEN_IN_FOCUSED_WINDOW;
                                     ^
  symbol:   variable WHEN_IN_FOCUSED_WINDOW
  location: class game
game.java:40: error: cannot find symbol
                InputMap inputs = InputMap(whenfocused);
                                  ^
  symbol:   method InputMap(String)
  location: class game
game.java:41: error: cannot find symbol
                ActionMap actions = ActionMap();
                                    ^
  symbol:   method ActionMap()
  location: class game
game.java:44: error: Action is abstract; cannot be instantiated
                m = new Action();
                    ^
game.java:46: error: incompatible types: game.move cannot be converted to Action
                actions.put(key.toString(), m);
                                            ^
game.java:62: error: cannot find symbol
                        g.repaint();
                         ^
  symbol:   method repaint()
  location: variable g of type Graphics
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
6 errors

这是我的新代码:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
import java.applet.Applet;



public class game { //creates the class
    public static final int ph = 300;
    public static final int pw = 300;
    public final int w = 20;
    public final int h = 20;

    public int x = (pw - w) / 2;
    public int y = (ph - h) / 2;
    public void main(String args[]) { //making a function (main) to run automatically and initialize the game

        JFrame f = new JFrame("Javax Swing UI"); //create frame for GUI
        f.setSize(ph, pw); //set the size of the frame in pixels x,y
        f.setBackground(Color.WHITE);
        f.setVisible(true); //load the frame and all objects inside it

        KeyStroke left = KeyStroke.getKeyStroke(KeyEvent.VK_A, 0);
        KeyStroke down = KeyStroke.getKeyStroke(KeyEvent.VK_S, 0);
        KeyStroke right = KeyStroke.getKeyStroke(KeyEvent.VK_D, 0);
        KeyStroke up = KeyStroke.getKeyStroke(KeyEvent.VK_W, 0);

        keyAdd(up, -1, 0);
        keyAdd(down, 0, 1);
        keyAdd(right, 1, 0);
        keyAdd(left, -1, 0);

    }

    public void keyAdd(KeyStroke key, int right, int down) {
        String whenfocused = WHEN_IN_FOCUSED_WINDOW;
        InputMap inputs = InputMap(whenfocused);
        ActionMap actions = ActionMap();

        move m = new move(right, down);
        m = new Action();
        inputs.put(key, key.toString());
        actions.put(key.toString(), m);
    }

    private class move {
        private int down;
        private int right;
        public move(int right, int down) {
            this.right = right;
            this.down = down;

        }

        public void actionPerformed(ActionEvent e, int down, int right, Graphics g) {

            x += right * 4;
            y += down * 4;
            g.repaint();
        }




    }



    protected void paintComponent(Graphics g,int x,int y,int w,int h, Color color) {
        g.setColor(color);
        g.fillRect(x, y, w, h);

    }


}









如果您想根据已按下的击键移动 "player",请根据我对您的原始 post 的评论,使用键绑定,而不是 KeyListener。一方面,即使绑定的组件没有焦点,Key Bindings 也可以工作,这可以通过传递给 JComponent#getInputMap(...) 方法的条件 int 来控制。在下面的示例中,我传入了 JComponent.WHEN_IN_FOCUSED_WINDOW,这意味着如果组件位于具有焦点的 window 中,即使实际键盘焦点位于该 [= 持有的另一个组件上,绑定也会响应28=].

键绑定教程可以在这里找到:How to Use Key Bindings

这是一个移动红色小矩形的演示程序,我的 "sprite" 基于用户按下箭头键:

请查看代码注释以了解有关此代码的作用的更多信息

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;

@SuppressWarnings("serial")
public class MoveSomething extends JPanel {
    private static final int PANEL_WIDTH = 800;
    private static final int PANEL_HEIGHT = 600;
    private static final Color SPRITE_COLOR = Color.RED;
    private static final int SPRITE_W = 20;
    public static final int DELTA = 4;

    private int spriteX = (PANEL_WIDTH - SPRITE_W) / 2;
    private int spriteY = (PANEL_HEIGHT - SPRITE_W) / 2;

    public MoveSomething() {
        setPreferredSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT));
        setBackground(Color.WHITE);

        // keystrokes that the program will respond to
        // you can use the "w" key as well, simply via KeyEvent.VK_W
        KeyStroke upStroke = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0);
        KeyStroke downStroke = KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0);
        KeyStroke leftStroke = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0);
        KeyStroke rightStroke = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0);

        // submit the key stroke for binding along with two int parameters
        // the right parameter that tells us if the key stroke should move things right (+1) or left (-1)
        // and the down parameter for moving sprite down (+1) or up (-1)
        submitKeyBinding(upStroke, 0, -1);
        submitKeyBinding(downStroke, 0, 1);
        submitKeyBinding(leftStroke, -1, 0);
        submitKeyBinding(rightStroke, 1, 0);
    }

    private void submitKeyBinding(KeyStroke keyStroke, int right, int down) {
        // set key bindings:
        int condition = WHEN_IN_FOCUSED_WINDOW;
        InputMap inputMap = getInputMap(condition);
        ActionMap actionMap = getActionMap();

        inputMap.put(keyStroke, keyStroke.toString());
        actionMap.put(keyStroke.toString(), new MoveAction(right, down));
    }

    // action used by the bindings to do the actual movement
    private class MoveAction extends AbstractAction {
        private int right;
        private int down;

        public MoveAction(int right, int down) {
            this.right = right;
            this.down = down;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            spriteX += right * DELTA;
            spriteY += down * DELTA;
            repaint(); // redraw the GUI
        }
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(SPRITE_COLOR);
        g.fillRect(spriteX, spriteY, SPRITE_W, SPRITE_W);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }

    private static void createAndShowGui() {
        MoveSomething mainPanel = new MoveSomething();
        JFrame frame = new JFrame("MoveSomething");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}