java - KeyListener 方法 keyPressed 不起作用

标签 java swing keylistener

我正在尝试使用 java swing 制作一个小游戏,并且已经取得了很大的进展,但现在我的 KeyListener 没有使用 keyPressed 方法。

这是我的一些代码

public class Screen extends JPanel implements Runnable{

private static final int WIDTH = 300, HEIGHT = 300, RIGHT = 0, LEFT = 1, UP = 2, DOWN = 3, STILL = 4;
private Thread thread;
private boolean running = false;
private int direction = DOWN;

   public Screen() {
    setFocusable(true);
    addKeyListener(new Key());
    setPreferredSize(new Dimension(WIDTH, HEIGHT));
    start();
   }

   public void tick(){
     System.out.println(direction)  
   }

   public void start() {
    running = true;
    thread = new Thread(this, "Game Loop");
    thread.start();
}

   public void run() {
     while (running) {
       tick();
       repaint();
    }
}

   private class Key implements KeyListener{
    @Override
    public void keyTyped(KeyEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();

        if (key == KeyEvent.VK_D) {
            direction = RIGHT;
        }

        if (key == KeyEvent.VK_A) {
            direction = LEFT;
        }

        if (key == KeyEvent.VK_W) {
            direction = UP;
        }

        if (key == KeyEvent.VK_S) {
            direction = DOWN;
        }

    }

    @Override
    public void keyReleased(KeyEvent e) {
        // TODO Auto-generated method stub

    }
   }
}

我正在查看控制台,并期望无论我按下什么按钮,输出都会从 3(向下)更改,但它从来没有这样做。一段时间后,我意识到 keyPressed 方法出了问题,我只是不知道是什么。

最佳答案

您不需要单独的“游戏循环”线程。 Swing 是事件驱动的。当用户按下计算机键盘上的某个键时,将调用您的按键监听器代码。

正如MadProgrammer在他的comment to your question中提到的那样

modifying he state of the UI from outside the context of the EDT may cause painting issues

换句话说,Swingsingle threaded该线程称为事件调度线程 (EDT),所有更改 GUI 的代码都应仅在 EDT 上执行。

下面的代码是一个独立的 Swing 应用程序,它显示可聚焦的 JPanel。当您按下相关键盘“方向”键之一(即 A 或 D 或 S 或 W)时,控制台会显示方向。按任何其他键都会导致方向仍然写入控制台。请注意,我使用了 enum对于各个方向,而不是整数常量。

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;

public class Screen01 extends JPanel implements Runnable {
    public enum Directions {RIGHT, LEFT, UP, DOWN, STILL};

    private static final int WIDTH = 300, HEIGHT = 300;
    private Directions direction;

    public Screen01() {
        setPreferredSize(new Dimension(WIDTH, HEIGHT));
        setFocusable(true);
        addKeyListener(new Key());
    }

    public void run() {
        createAndDisplayGui();
    }

    private void createAndDisplayGui() {
        JFrame frame = new JFrame("Screen");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.add(this, BorderLayout.CENTER);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private class Key implements KeyListener {

        @Override
        public void keyTyped(KeyEvent e) {
            // Do nothing.
        }

        @Override
        public void keyPressed(KeyEvent e) {
            int key = e.getKeyCode();
            switch (key) {
                case KeyEvent.VK_D:
                    direction = Directions.RIGHT;
                    break;
                case KeyEvent.VK_A:
                    direction = Directions.LEFT;
                    break;
                case KeyEvent.VK_W:
                    direction = Directions.UP;
                    break;
                case KeyEvent.VK_S:
                    direction = Directions.DOWN;
                    break;
                default:
                    direction = Directions.STILL;
            }
            System.out.println("Direction = " + direction);
        }

        @Override
        public void keyReleased(KeyEvent e) {
            // Do nothing.
        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Screen01());
    }
}

关于java - KeyListener 方法 keyPressed 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61421299/

相关文章:

java - 扩展的 JTree 渲染

java - 未重新绘制的图

java - 获取当前版本号 `tzdata`

java - System.in.read() 不会阻止读取更多输入字符?

Java:将字符串转换为 double\long,除以 100 并将其转换回字符串(SpEL)

java - 按下任何键时鼠标无法移动Java Swing

java - 为什么 KeyEvent 虽然实现了 KeyListener 接口(interface)但不起作用?

java - JTable 上的监听器出现问题(执行代码太多次)

Java MySQL和JFrame连接 "Cannot convert from boolean to connection"

java - 包含 JCheckBoxes 的 JTable 的关键监听器