让小球受键盘控制移动,我的程序哪里出错了小球不动

java新手一只。这是我的原程序,java新手一只,求大神解惑

import java.awt.*;

import javax.swing.*;

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

/**坦克大战0.4
*@author 安晔
*代码重构
*定义常量
*/

public class TankClient extends JFrame{
public static final int WIDTH = 800;
public static final int HEIGHT = 600;

/*主函数*/
public static void main(String []args){
    JFrame frm=new JFrame("坦克大战0.4");
    frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frm.setLayout(null);
    Tank tank=new Tank();
    tank.setBounds(0, 0, WIDTH,HEIGHT);
    tank.setBackground(Color.GREEN);
    frm.getContentPane().add(tank);
    frm.setBounds(300, 400, WIDTH,HEIGHT);
    frm.setResizable(false);
    frm.setVisible(true);

}

}

class Tank extends JPanel implements Runnable{
/*定义圆的坐标*/
KeyMonitor k=new KeyMonitor();
public int x=50,y=50;
Thread runner;
/*定义默认构造函数*/
Tank(){
start();
}

public void paint(Graphics g){
    super.paint(g);//刷新屏幕,重绘图像
    g.setColor(Color.RED);
    g.fillOval(x, y, 30, 30);
}
public void start(){
    if(runner==null)
        runner=new Thread(this);
    runner.start();
}
public void run(){
    while(true){
        this.addKeyListener(new KeyMonitor());
        repaint();
        try{
            Thread.sleep(100);
        }catch(InterruptedException e){
            e.printStackTrace();
        }
    }
}

/*双缓存技术解决闪速效果*/
 Image offScreenImage = null;
 public void update(Graphics g) {
        if(offScreenImage == null) {
            offScreenImage = this.createImage(800, 600);
        }
        Graphics gOffScreen = offScreenImage.getGraphics();
        Color c = gOffScreen.getColor();
        gOffScreen.setColor(Color.GREEN);
        gOffScreen.fillRect(0, 0, 800, 600);
        gOffScreen.setColor(c);
        paint(gOffScreen);
        g.drawImage(offScreenImage, 0, 0, null);
    }

 /*定义键盘监听器*/
 private class KeyMonitor extends KeyAdapter {
        public void keyPressed(KeyEvent e) {
            int key = e.getKeyCode();
            switch(key) {
            case KeyEvent.VK_LEFT :
                x -= 5;
                break;
            case KeyEvent.VK_UP :
                y -= 5;
                break;
            case KeyEvent.VK_RIGHT :
                x += 5;
                break;
            case KeyEvent.VK_DOWN :
                y += 5;
                break;
            }
        }

    }

}

监听器对象应该绑定在JFrame上面。

吧监听器绑在jframe上

修正代码main函数如下:

 public class TankClient extends JFrame {
    public static final int WIDTH = 800;
    public static final int HEIGHT = 600;

    /* 主函数 */
    public static void main(String[] args) {
        JFrame frm = new JFrame("坦克大战0.4");
        frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frm.setLayout(null);
        Tank tank = new Tank();
        frm.addKeyListener(tank.getMonitor());
        tank.setBounds(0, 0, WIDTH, HEIGHT);
        tank.setBackground(Color.GREEN);
        frm.getContentPane().add(tank);
        frm.setBounds(300, 400, WIDTH, HEIGHT);
        frm.setResizable(false);
        frm.setVisible(true);
    }

}

修正Tank类添加getKeyMonitor方法,返回监听器对象。

    public KeyMonitor getMonitor(){
        return k;
    }

OK,测试通过,可以正常通过键盘控制圆形的移动了。

while(true){
this.addKeyListener(new KeyMonitor());
不要这么写啊,你要创建多少个监听器啊。

因为你已经在Tank类里创建了键盘监听器,因此你直接用就行了,把上面的 this.addKeyListener(new KeyMonitor())删掉啊。然后将main函数修改为:

 JFrame frm=new JFrame("坦克大战0.4");
    frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frm.setLayout(null);
    Tank tank=new Tank();
    tank.setBounds(0, 0, WIDTH,HEIGHT);
    tank.setBackground(Color.GREEN);
    frm.getContentPane().add(tank);
    frm.setBounds(300, 400, WIDTH,HEIGHT);
    frm.setResizable(false);
        frm.addKeyListener(tank.k);
    frm.setVisible(true);