我想问个问题
public BallMove()
{
frame=new JFrame();
panel=new JPanel();
panel.setSize(300,300);
         //   control con=new control();
Container c=frame.getContentPane();
c.setLayout(new BorderLayout());
c.add(panel,BorderLayout.CENTER);
        //    c.add(con,BorderLayout.EAST);
frame.setSize(400,350);
frame.setLocation(300,100);
frame.setVisible(true);
frame.addKeyListener(this);
begin();
}
这是我的类的构造函数,我为frame设置了键盘监听,用键盘输入来控制panel上的一个小东西移动,但是我还想加个面板,也就是在frame上左面一个面板,显示我画的东西,右面一个面板,来设置参数,目的是在右面的面板中设置参数后,按键盘输入让左面面板中的东西动起来,如果不加右面的面板完全好用,为什么一加上右面的面板我的键盘输入就不好用了呢

解决方案 »

  1.   

    在最后加上这句试试:frame.requestFocus();
    把你的frame.addKeyListener(this);改成下面这样可以避免窗体失去键盘焦点而不响应键盘事件:
    Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
                public void eventDispatched(AWTEvent e) {
                if (((KeyEvent)e).getID() == KeyEvent.KEY_PRESSED)
                    //your action here
                }
            }, AWTEvent.KEY_EVENT_MASK);
      

  2.   

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    public class EatSnake implements KeyListener{ JFrame frame;
    JPanel panel;
    Snake snake=null;
    public EatSnake()
    {
    frame=new JFrame();
    panel=new JPanel();
    panel.setSize(300,300);
    //control con=new control();
    Container c=frame.getContentPane();
    c.setLayout(new BorderLayout());
    c.add(panel,BorderLayout.CENTER);
    //c.add(con,BorderLayout.EAST);
    frame.setSize(400,350);
    frame.setLocation(300,100);
    frame.setVisible(true);
    frame.addKeyListener(this);
    begin();
    }
    public void keyPressed(KeyEvent e)
    {
    int keyCode=e.getKeyCode();
    if(snake.running==true)
    {
    switch(keyCode)
    {
    case KeyEvent.VK_UP:
    snake.changeDir(Snake.UP);
    break;
    case KeyEvent.VK_DOWN:
    snake.changeDir(Snake.DOWN);break;
    case KeyEvent.VK_LEFT:
    snake.changeDir(Snake.LEFT);break;
    case KeyEvent.VK_RIGHT:
    snake.changeDir(Snake.RIGHT);break;
    }
    }
    begin();
    }
    public void keyReleased(KeyEvent e)
    {}
    public void keyTyped(KeyEvent e)
    {}
    public void repaint()
    {
    Graphics g=panel.getGraphics();
    g.setColor(Color.WHITE);
    g.fillRect(0,0,300,300);
    g.setColor(Color.BLACK);
    int num=snake.list.size();
    for(int i=0;i<num;i++)
    {
    g.fillRect(snake.list.get(i).x*10,snake.list.get(i).y*10,9,9);
    }
    g.setColor(Color.RED);
    g.fillRect(snake.food.x*10,snake.food.y*10,9,9);
    }
    public void begin()
    {
    if(snake==null)
    {
    snake=new Snake(this,30,30);
    Thread th=new Thread(snake);
    th.start();
    }
    }
    public static void main(String [] args)
    {
    new EatSnake();
    }
    /*class control extends JPanel
    {
    private JButton b1;
    public control()
    {

    setLayout(new GridLayout(14, 0));
    b1=new JButton("up");
    add(b1);
    }
    }*/
    }
    第二个类
    import java.util.*;import javax.swing.JOptionPane;
    public class Snake implements Runnable{
    ArrayList<Node> list=new ArrayList<Node>();;
    boolean running=true;
    public static final int UP = 2;
    public static final int DOWN = 4;
    public static final int LEFT = 1;
    public static final int RIGHT = 3;
    int maxx;
    int maxy;
    EatSnake eat;
    int direction = 2;
    Node food;
    boolean [][]mun=new boolean[30][30];
    public Snake(EatSnake eat,int maxx,int maxy)
    {
    this.eat = eat;
    this.maxx=maxx;
    this.maxy=maxy;

    for(int i=0;i<30;i++)
    {
    for(int j=0;j<30;j++)
    {
    mun[i][j]=false;
    }
    }
    for(int h=0;h<10;h++)
    {
    Node node=new Node(15+h,15);
    list.add(node);
    mun[15+h][15]=true;
    }
    food=addFood();
    mun[food.x][food.y]=true;
    }
    public void run()
    {
    while(running==true){
    try{
    Thread.sleep(260);
    }
    catch(Exception e){}
    if(moveon()){eat.repaint();}
    else {JOptionPane.showMessageDialog(
                  null,
                  "笨B!",
                  "Game Over",
                  JOptionPane.INFORMATION_MESSAGE);
              break;
            }
        }
    }
    public void changeDir(int newDir){
        if (direction % 2 != newDir % 2){
          direction = newDir;
        }
      }
    public boolean moveon()
    {
    Node n=(Node)list.get(0);
    int x=n.x;
    int y=n.y;
    switch(direction)
    {
    case UP:
    y--;
    break;
    case DOWN:
    y++;
        break;
    case LEFT:
    x--;
        break;
    case RIGHT:
    x++;
    break;
    }
    if((x>=0&&x<30)&&(y>=0&&y<30))
    {
    if(mun[x][y])
    {
    if((x==food.x)&&(y==food.y))
    {
    list.add(0,food);
    Node temp=addFood();
    mun[temp.x][temp.y]=true;
    return true;
    }
    else return false;

    }
    else
    {
    Node newnode=new Node(x,y);
    mun[newnode.x][newnode.y]=true;
    list.add(0,newnode);
    Node lastnode=list.get(list.size()-1);
    mun[lastnode.x][lastnode.y]=false;
    list.remove(lastnode);

    return true;
    }

    }
    else return false;
    }
    public Node addFood()
    {
    int p=0;
    int q=0;
           do{
            Random r=new Random();
           p=r.nextInt(30);
           q=r.nextInt(30);
           food=new Node(p,q);
           }while(mun[p][q]);
           return new Node(p,q);
    }

    class Node
    {
    int x;
    int y;
    public Node(int x,int y)
    {
    this.x=x;
    this.y=y;
    }
    }
    }
    我不怎么会线程和窗体一起用,所以找了个网上的程序进行了简化改写,但是改的时候我想加个控制台面板,一但加上去就键盘就不好用了
      

  3.   

    在public EatSnake()的最后加上这句吧:frame.requestFocus();并且frame失去键盘输入焦点的时候根据需求请求焦点
    如果没有其他键盘输入事件可以直接把frame.addKeyListener(this);换成Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
    public void eventDispatched(AWTEvent e) {
    if (((KeyEvent)e).getID() == KeyEvent.KEY_PRESSED)
    int keyCode=((KeyEvent)e).getKeyCode();
    if(snake.running==true)
    {
    switch(keyCode)
    {
    case KeyEvent.VK_UP:
    snake.changeDir(Snake.UP);
    break;
    case KeyEvent.VK_DOWN:
    snake.changeDir(Snake.DOWN);break;
    case KeyEvent.VK_LEFT:
    snake.changeDir(Snake.LEFT);break;
    case KeyEvent.VK_RIGHT:
    snake.changeDir(Snake.RIGHT);break;
    }
    }
    begin();
    }
    }, AWTEvent.KEY_EVENT_MASK);