我的 KeyListener 无法读取按键输入

Posted

技术标签:

【中文标题】我的 KeyListener 无法读取按键输入【英文标题】:My KeyListener can't read key inputs 【发布时间】:2018-12-29 20:41:29 【问题描述】:

现在,我有一个扩展 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();



【问题讨论】:

【参考方案1】:

好的,有很多问题...

简短的回答...

使用Key Bindings API,它克服了KeyListener API 的缺点

长答案...

KeyListener 只会在它注册到的组件是可聚焦的并且具有键盘焦点时生成 KeyEvents。

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

Keyboard 实际上并没有添加到任何东西上,因此它不会显示在屏幕上,因此它永远无法获得焦点。 KeyListener确实应该直接注册到Game,只是需要管理的组件少了 不推荐使用Component 中的getGraphics,这不是绘画的方式。 Swing 组件默认情况下是双缓冲的,所以通常最好利用它的内置绘画过程,如果你真的想控制绘画过程,你应该使用CanvasBufferStrategy,否则运行在您的绘制代码和现有绘制过程的 API 之间产生竞争条件的风险

【讨论】:

【参考方案2】:

我这样做

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");
    


【讨论】:

以上是关于我的 KeyListener 无法读取按键输入的主要内容,如果未能解决你的问题,请参考以下文章

Java KeyListener:KeyTyped Backspace,Esc 作为输入

键盘事件KeyListener( )

改进我的键盘输入 (KeyListener) Java

单击按钮后keylistener不起作用

KeyListener 如何检测组合键(例如,ALT + 1 + 1)

Java按键事件KeyEvent