KeyListener方法keyPressed不起作用

问题描述 投票:0回答:2

我正在尝试使用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(即DOWN)改变,但是从没有改变。一段时间后,我意识到keyPressed方法出了点问题,我只是不知道是什么。

java swing keylistener
2个回答
0
投票

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

如[[MadProgrammer在他的comment to your question中提到的

从EDT上下文之外修改UI状态可能会导致绘画问题

换句话说,

Swing

single threaded,并且该线程称为Event Dispatch Thread(EDT),并且所有更改GUI的代码都应仅在EDT上执行。” >下面的代码是一个独立的

Swing

应用程序,它显示可聚焦的JPanel。当您按下相关的键盘“方向”键之一,即A或D或S或W时,控制台将显示方向。按下任何其他键会导致STILL方向被写入控制台。请注意,我在各个方向上都使用了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()); } }

0
投票
key bindings API的使用,它将解决此问题以及所有其他与KeyListener相关的问题,而无需对其进行“有时”工作的原因进行过多的黑客干预和抓挠]]

Swing是单线程的。这意味着您应该注意从事件调度线程的上下文外部(直接或间接)更新UI状态,这还包括UI可能依赖的任何状态。

© www.soinside.com 2019 - 2024. All rights reserved.