【问题标题】:addKeyListener() doesn't work for JPaneladdKeyListener() 不适用于 JPanel
【发布时间】:2012-01-19 20:29:18
【问题描述】:

我正在尝试制作游戏引擎。我已经制作了 Game 类,但错误存在于 KeyBoard 类中。这里我留下一些代码。

类:: 游戏

package transfer2pc.co.cc.game.tileengine;

import java.awt.Graphics;
import java.util.HashMap;

import javax.swing.JPanel;

import transfer2pc.co.cc.game.tileengine.input.KeyBoard;

public abstract class Game extends JPanel implements Runnable {

   /**
    * 
    */
    private static final long serialVersionUID = 640206679500196209L;

    HashMap<String, ?> maps = null;

    KeyBoard keyBoard = null;

    public Game(){
        super();
        keyBoard = new KeyBoard(this);
        setKeyBoard(keyBoard);
        Thread th = new Thread(this);
        th.start();
    }

    public void run(){
        while(true){
            repaint();
            try {
                Thread.sleep(30);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void paint(Graphics g){

    }

    public void addMap(){

    }

    public void setMap(){

    }

    public abstract void keyPressed(int code);

    public abstract void keyReleased(int code);

    public abstract void keyTyped(int code);

    public void setKeyBoard(KeyBoard key){
        addKeyListener(key);
    }

}

类:: 键盘

package transfer2pc.co.cc.game.tileengine.input;

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import transfer2pc.co.cc.game.tileengine.Game;

public class KeyBoard extends KeyAdapter implements KeyListener {

    Game game = null;

    public KeyBoard(Game gm){
        this.game = gm;
    }

    @Override
    public void keyPressed(KeyEvent e) {
        System.out.println("KeyPressed");
        game.keyPressed(e.getKeyCode());
    }

    @Override
    public void keyReleased(KeyEvent e) {
        game.keyReleased(e.getKeyCode());
    }

    @Override
    public void keyTyped(KeyEvent e) {
        game.keyTyped(e.getKeyCode());
    }

    public static char getChar(int key){
        return (char)key;
    }

}

类:: KeyTest

package transfer2pc.co.cc.game.tileengine.test;

import java.awt.Graphics;

import javax.swing.JFrame;

import transfer2pc.co.cc.game.tileengine.Game;
import transfer2pc.co.cc.game.tileengine.input.KeyBoard;

public class KeyTest extends Game {

    /**
     * 
     */
    private static final long serialVersionUID = 8557676950779023327L;

    char pressed;

    public KeyTest(){
        super();
        addKeyListener(new KeyBoard(this));
    }

    @Override
    public void keyPressed(int code) {
        pressed = KeyBoard.getChar(code);
    }


    @Override
    public void keyReleased(int code) {

    }


    @Override
    public void keyTyped(int code) {

    }

    @Override
    public void paint(Graphics g){
        g.drawString("You pressed: "+pressed, 20, 20);
    }

    public static void main(String[] args){
        JFrame frame = new JFrame("KeyTest");
        frame.setSize(640, 480);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.add(new KeyTest());
        frame.setVisible(true);
    }

}

但是错误是没有抛出异常并且没有读取输入。谁能告诉我这样做的正确方法..

【问题讨论】:

  • 1) 为了尽快获得更好的帮助,请发帖 SSCCE。 2) 组件在监听关键事件之前需要具有焦点。 3)如果面板包含树或表格之类的东西,这些组件将消耗关键事件。 4) 通常建议在KeyListener 上使用键绑定。 5) Thread.sleep(30); 不要那样做。在过去的两天里,我一定已经讨论过 3 次了。搜索我的帖子和 cmets 以了解原因。

标签: java swing jpanel keylistener


【解决方案1】:

您可以将关键侦听器添加到 JFrame,这是我过去做过的事情。 但是,如果 JFrame 中有其他组件,这可能不是一个好主意。

【讨论】:

  • 我在框架中没有任何组件,但 jpanels 适合我,因为它们可以在小程序中使用。
  • 我相信您也可以将其添加到 Applet/JApplet,但我理解您为什么要将代码保留在 JPanel 中
【解决方案2】:

简单地说,您的面板需要具有焦点。在您创建面板的任何位置添加:

panel.setFocusable(true);
panel.requestFocusInWindow();

这是SSCCE(我建议以后用其中一个提问):

import java.awt.Dimension;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class SimpleKeyTest {

    public static void main(String[] args) {

        Runnable r = new Runnable() {

            @Override
            public void run() {
                JFrame frame = new JFrame();
                JPanel panel = new JPanel();

                frame.getContentPane().add(panel);

                panel.addKeyListener(new KeyListener() {

                    @Override
                    public void keyTyped(KeyEvent e) {}

                    @Override
                    public void keyReleased(KeyEvent e) {}

                    @Override
                    public void keyPressed(KeyEvent e) {
                        System.out.println("Pressed " + e.getKeyChar());
                    }
                });

                panel.setFocusable(true);
                panel.requestFocusInWindow();

                frame.setSize(new Dimension(300, 300));
                frame.setVisible(true);
            }

        };

        SwingUtilities.invokeLater(r);

    }
}

另外,https://www.google.com/search?q=jpanel+keylistener

【讨论】:

  • "你能说什么是sscce吗"我可以,但是我说了很多次,最后我把它放到了一个网页上。同一个网页已在此线程中链接两次。按照文档的链接。全部阅读。询问是否有任何不清楚的地方。
猜你喜欢
  • 1970-01-01
  • 2020-08-03
  • 2018-07-07
  • 1970-01-01
相关资源
最近更新 更多