我的KeyListener无法读取按键输入

时间:2018-07-22 00:35:24

标签: java swing awt keylistener mouselistener

现在,我有一个扩展JPanel并实现KeyListener的类。我已经将该类实例化为另一个在我的循环中运行它的类。 KeyListener类看起来像

public class Keyboard extends JPanel implements KeyListener{


public Keyboard()
{
         this.addKeyListener(this);
}

    public void update()
{

}

@Override
public void keyPressed(KeyEvent e)
{   

            if(keyCode == KeyEvent.VK_S){
                 System.out.println("Made it");
            }
}


@Override
public void keyReleased(KeyEvent e)
{
}

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

我在另一个使用MouseListener类的Game类中实现了这一点。但是由于某种原因,它不会听键盘。

public class Main

{

public static final int WIDTH = 640;
public static final int HEIGHT = 640;
public static final String NAME = "Game";

private static BufferedImage image;
private static Graphics2D g;
private static boolean forceQuit;

private static Game game;
    private static Keyboard keyboard;

    public Main(){

    }

private static void init()
{
    image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
    g = (Graphics2D) image.getGraphics();
    g.setBackground(Color.BLACK);

    game = new Game();
            keyboard = new Keyboard();
}

private static void start()
{
    run();
}

public static void stop()
{
    forceQuit = true;
}

public static void run()
{
    @SuppressWarnings("unused")
    int frames = 0;

    double unprocessedSeconds = 0;
    long lastTime = System.nanoTime();
    double secondsPerTick = 1.0 / 60.0;
    int tickCount = 0;

    while (!forceQuit)
    {
                if(keyboard.isSwampland()){
                    game.setSwampland(true);
                }

        long now = System.nanoTime();
        long passedTime = now - lastTime;
        lastTime = now;
        if (passedTime < 0)
            passedTime = 0;
        if (passedTime > 100000000)
            passedTime = 100000000;

        unprocessedSeconds += passedTime / 1000000000.0;

        boolean ticked = false;
        while (unprocessedSeconds > secondsPerTick)
        {
            game.update();
                            keyboard.update();
            unprocessedSeconds -= secondsPerTick;
            ticked = true;

            tickCount++;
            if (tickCount % 60 == 0)
            {
                // System.out.println("FPS:" + frames);
                lastTime += 1000;
                frames = 0;
            }
        }

        if (ticked)
        {
            game.render(g);

            Graphics gg = game.getGraphics();
            gg.drawImage(image, 0, 0, null);
            gg.dispose();

            frames++;
        }
        else
        {
            try
            {
                Thread.sleep(1);
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
        }



    }
}

public static void main(String[] args)
{
    Main.init();

    JFrame frame = new JFrame(NAME);
    frame.setDefaultCloseOperation(3);
    frame.setContentPane(game);
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);

    Main.start();
}

}

2 个答案:

答案 0 :(得分:1)

好的,所以有很多问题...

简短答案...

使用Key Bindings API,可以克服KeyListener API的缺点

长答案...

KeyListener仅在其注册的组件可聚焦并且具有键盘焦点的情况下才会生成KeyEvent

我在您的代码中看到的问题是...

  • Keyboard实际上没有添加到任何内容,因此它不会显示在屏幕上,因此它永远无法获得焦点。
  • 实际上KeyListener应该直接注册到Game,因为只有较少的组件需要管理
  • 不建议使用getGraphics中的Component,这不是绘画的方法。默认情况下,Swing组件是双缓冲的,因此通常最好使用其内置的绘制过程,如果您真的想控制绘制过程,则应使用CanvasBufferStrategy ,否则将冒着在绘画代码和API现有绘画过程之间生成竞争条件的风险

答案 1 :(得分:0)

我这样做

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;


public class DrawPoints
{
    Frame f;
    KeyBoard key;
    Mouse mouse;
    Paint c;

    public void GUI()
    {
        f = new Frame("DrawPoints");
        f.setSize(300, 300);

        mouse = new Mouse();

        c = new Paint(mouse);
        c.setSize(300, 300);
        c.setBackground(Color.WHITE);

        c.addMouseListener(mouse);
        c.addMouseMotionListener(mouse);

        key = new KeyBoard();
        c.addKeyListener(key);

        f.add(c);
        f.pack();
        f.setVisible(true);

        f.addWindowListener(new WindowAdapter()
        {
            @Override
            public void windowClosing(WindowEvent e)
            {
                System.exit(0);
            }
        });
    }
}

class KeyBoard implements KeyListener
{
    @Override
    public void keyPressed(KeyEvent e)
    {
        int key = e.getKeyCode();
        if(key == KeyEvent.VK_SPACE)
        {
            System.out.println("SPACE");
        }
    }

    @Override
    public void keyTyped(KeyEvent e)
    {
        System.out.println("Typed");
    }

    @Override
    public void keyReleased(KeyEvent e)
    {
        System.out.println("Released");
    }

}

class Main
{

    public static void main(String[] args)
    {
        DrawPoints app = new DrawPoints();
        app.GUI();
    }
}

class Paint extends Canvas
{
    Mouse mouse;

    public Paint(Mouse mouse)
    {
        this.mouse = mouse;
    }

    @Override
    public void paint(Graphics g)
    {
        g.drawRect(mouse.getX(), mouse.getY(), 30, 30);
        repaint();
    }
}

class Mouse implements MouseListener, MouseMotionListener
{   
    private int x;
    private int y;

    public int getX()
    {
        return this.x;
    }

    public int getY()
    {
        return this.y;
    }

    // MouseMotionListener
    @Override
    public void mouseMoved(MouseEvent e)
    {
        x = e.getX();
        y = e.getY();
        //System.out.println(e.getX() + " " + e.getY());
    }

    @Override
    public void mouseDragged(MouseEvent e)
    {
        System.out.println("mouseDragged");
    }

    // MouseListener
    @Override
    public void mouseEntered(MouseEvent e)
    {
        System.out.println("MOUSE Entered");
    }

    @Override
    public void mousePressed(MouseEvent e)
    {
        System.out.println("MOUSE Pressed");
    }

    @Override
    public void mouseReleased(MouseEvent e)
    {
        System.out.println("MOUSE Released");
    }

    @Override
    public void mouseClicked(MouseEvent e)
    {
        System.out.println("MOUSE Clicked");
    }

    @Override
    public void mouseExited(MouseEvent e)
    {
        System.out.println("MOUSE Exited");
    }

}