Java swing keyPressed无法正常工作

时间:2018-04-25 17:57:23

标签: java swing keylistener java-2d keyevent

我在Java Swing中制作Arkanoid游戏。当我运行游戏时KeyEvent无效。

为什么游戏没有检测到关键事件?

我的程序中的主类创建一个框架(JFrame)。我还有Manage课程来管理我游戏中的所有课程。

这是代码:Player类是我游戏中的paddle类。

//imports

public class Player extends JPanel implements ActionListener, KeyListener
{

    private int x, y, width, height;
    private Timer timer;
    private int fps = 60;
    private int delay = 1000/fps;

    public Player(int x, int y, int width, int height)
    {
        //setFocusable(true);
        addKeyListener(this);
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;

        timer = new Timer(delay, this);
        timer.start();
    }

    @Override
    public void actionPerformed(ActionEvent e)
    {
        timer.start();

        repaint();
    }

    @Override
    public void keyPressed(KeyEvent e)
    {
        switch (e.getKeyCode())
        {
            case KeyEvent.VK_A:
                if (x <= 0) {
                    x = 0;
                } else {
                    x -= 3;
                }
                break;
            case KeyEvent.VK_D:
                if (x >= 600) {
                    x = 600;
                } else {
                    x += 3;
                }
                break;
        }
    }

    public void paint(Graphics g)
    {
        g.setColor(Color.BLUE);
        g.fillRect(x, y, width, height);
    }

    @Override
    public void keyTyped(KeyEvent e) { }
    @Override
    public void keyReleased(KeyEvent e) { }


}

1 个答案:

答案 0 :(得分:-1)

该代码的主要问题是自定义绘制的组件既不可聚焦也不集中(因此无法接收关键事件)。

此代码修复了这些问题以及更多问题(请查看代码注释以获取详细信息)。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Player extends JPanel implements ActionListener, KeyListener {

    private int x, y, width, height;
    private final Timer timer;
    private final int fps = 60;
    private final int delay = 1000 / fps;

    public Player(int x, int y, int width, int height) {
        addKeyListener(this);
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;

        timer = new Timer(delay, this);
        timer.start();
        // a component must be focusable to get key events!
        setFocusable(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        //timer.start(); // Timer should already be started!

        repaint();
    }

    @Override
    // correct method for custom painting a JComponent is paintComponent!
    public void paintComponent(Graphics g) {
        // call the super method to ensure previous paints are erased!
        super.paintComponent(g);
        g.setColor(Color.BLUE);
        g.fillRect(x, y, width, height);
    }

    @Override
    // a custom painted component should suggest a size to be used by the
    // layout manager
    public Dimension getPreferredSize() {
        return new Dimension(400,100);
    }

    @Override
    public void keyPressed(KeyEvent e) {
        switch (e.getKeyCode()) {
            case KeyEvent.VK_A:
                if (x <= 0) {
                    x = 0;
                } else {
                    x -= 3;
                }
                break;
            case KeyEvent.VK_D:
                if (x >= 600) {
                    x = 600;
                } else {
                    x += 3;
                }
                break;
        }
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyReleased(KeyEvent e) {
    }

    public static void main(String[] args) {
        Runnable r = () -> {
            JFrame f = new JFrame(o.getClass().getSimpleName());
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setLocationByPlatform(true);

            Player player = new Player(2, 2, 5, 20);
            f.setContentPane(player);
            f.pack();
            f.setMinimumSize(f.getSize());

            f.setVisible(true);
            // a component must be focused to detect key events!
            player.requestFocusInWindow(); 
        };
        SwingUtilities.invokeLater(r);
    }
}