在学Java游戏开发的基础。写了两个类,想要实现监听键盘输入,图形在JFrame上移动。但是不知道为什么总是不动请各位高人指导一下。。感谢各位!我在想是不是repaint或者ActionListener出了问题?这是主类:import javax.swing.JFrame;public class Frame extends JFrame{ public Frame(){
this.setSize(500,500);
this.add(new Board());

this.addKeyListener(new Board());
this.setVisible(true);

}
public static void main(String[] args) {
new Frame(); }}
这是第JPanel类:import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;import javax.swing.JPanel;public class Board extends JPanel implements KeyListener{

int x, y,dx,dy;

public Board(){ this.addKeyListener(this);
}
public void paint(Graphics g){

super.paint(g);
this.setBackground(Color.BLACK);
g.setColor(Color.WHITE);
g.fillRect(x+dx,y+dy,50,50);
}


public void keyPressed(KeyEvent e){
if(e.getKeyCode()==KeyEvent.VK_LEFT){
dx--;
}
if(e.getKeyCode()==KeyEvent.VK_RIGHT){
dx++;
}
if(e.getKeyCode()==KeyEvent.VK_UP){
dy--;
}
if(e.getKeyCode()==KeyEvent.VK_DOWN){
dy++;
}
repaint();

}

public void keyReleased(KeyEvent e){

}
public void keyTyped(KeyEvent e){

}


}

解决方案 »

  1.   

    把构造方法:    public Frame() {
            this.setSize(500, 500);
            this.add(new Board());
            this.addKeyListener(new Board());
            this.setVisible(true);
        }改成这样就行了:    public Frame() {
            this.setSize(500, 500);
            Board board=new Board();
            this.add(board);
            this.addKeyListener(board);
            this.setVisible(true);
        }
      

  2.   

    楼主遇到的这个问题是个蛮典型的问题
    我把根源分析一下吧问题一:先看一下你的KeyListener是在哪实现,又在哪添加的?
    仔细看看可以发现,
    你的KeyListener在你的这个Board的类中实现,并添加在了这个JPanel上
    咋一看,感觉不用让Frame监听KeyListener应该也能有反应才对啊
    就是说在Frame的构造方法中没有
    this.addKeyListener(new Board());
    这句话,应该也有方法让Board实现重绘
    那问题就是为什么这个Frame起来后,我们按键没有反应呢?
    那就是焦点问题,JPanel是无法通过鼠标点击获得焦点的
    在你的JFrame起来后,默认的焦点是在JFrame上的,
    而你却怎么样都无法让Board获得焦点
    所以其实只要加一句话,就可以让你的Board实现重绘
    就是这样改:
    public Frame() {
    this.setSize(500, 500);
    Board board = new Board();
    this.add(board);
    this.setVisible(true);
    board.requestFocus();
    }board.requestFocus();
    在JFrame起来后,让你的Board强制获得焦点,才能监听上面的键盘事件问题二:如果焦点在JFrame上,如何也能实现重绘呢?
    那就是1楼的改法了,而这样子你的这个程序的结构就显得不是那么好了
    因为你的KeyListener在Board类中实现,你却是为了让JFrame来监听这个KeyListener
    那为什么不把KeyListener移植到JFrame类中实现呢?
    这样改:
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;import javax.swing.JFrame;public class Frame extends JFrame implements KeyListener { private Board board;

    public Frame() {
    this.setSize(500, 500);
    board = new Board();
    this.add(board);
    this.addKeyListener(this);
    this.setVisible(true);
    } public static void main(String[] args) {
    new Frame();
    } public void keyPressed(KeyEvent e) {
    if (e.getKeyCode() == KeyEvent.VK_LEFT) {
    board.dx--;
    }
    if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
    board.dx++;
    }
    if (e.getKeyCode() == KeyEvent.VK_UP) {
    board.dy--;
    }
    if (e.getKeyCode() == KeyEvent.VK_DOWN) {
    board.dy++;
    }
    repaint();
    } public void keyReleased(KeyEvent e) {} public void keyTyped(KeyEvent e) {}}
    而你的Board类只要简简单单的这样:
    import java.awt.Color;
    import java.awt.Graphics;import javax.swing.JPanel;public class Board extends JPanel { int x, y, dx, dy; public Board() {
    super();
    }

    public void paint(Graphics g) {
    super.paint(g);
    this.setBackground(Color.BLACK);
    g.setColor(Color.WHITE);
    g.fillRect(x + dx, y + dy, 50, 50);
    }
    }问题三:paint方法
    既然使用了Swing组件
    我们建议就不要重写paint了,最好重写paintComponent这个方法
    因为Swing在这个方法中使用了双缓冲机制,在界面刷新的时候,减少“闪动”的感觉
    这是Swing的优势,不用这个太可惜了
    这样子:
    protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    this.setBackground(Color.BLACK);
    g.setColor(Color.WHITE);
    g.fillRect(x + dx, y + dy, 50, 50);
    }