2013-10-08 103 views
1

這裏是我的問題。當我嘗試處理KB事件時,我的程序無能爲力。有些人相信它是因爲忙碌的等待(與主線程對抗的新線程)。我該如何解決它?忙等待在AWT

public class GameCanvas extends Canvas { 
    int myX = 250; 
    int myY = 0; 
    int speedValue = 15; 
    int bottom = 480; 

    GameCanvas() { 
     addKeyListener(new KeyAdapter() { 
      @Override 
      public void keyPressed(KeyEvent event) { 
       switch (event.getKeyCode()) { 
        case KeyEvent.VK_LEFT: 
         if (myX > 5) myX -= 5; 
         break; 
        case KeyEvent.VK_RIGHT: 
         if (myX < 480) myX += 5; 
         break; 
       } 
       repaint(); 
      } 
     }); 

     new Thread(new Runnable() { 
      @Override 
      public void run() { 
       while (true) { 
        setGameSpeed(speedValue); 
        if (myY < bottom) { 
         myY += 5; 
        } else { 
         bottom -= 20; 
         myY = 0; 
        } 
        repaint(); 
       } 
      } 
     }).start(); 
    } 

    public void setGameSpeed(int value) { 
     try { 
      sleep(value); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public void paint(Graphics g) { 
     g.setColor(Color.darkGray); 
     g.fillRect(myX, myY - 5, 25, 25); 
     buildGameBottom(g); 
    } 

    void buildGameBottom(Graphics g){ 
     g.setColor(Color.WHITE); 
     g.fillRect(0, bottom + 20, 500, bottom + 20); 
    } 

    public static void main(String[] args) throws InterruptedException { 
     JFrame frame = new JFrame(); 
     GameCanvas gameCanvas = new GameCanvas(); 
     gameCanvas.setSize(new Dimension(500, 500)); 
     gameCanvas.setBackground(Color.LIGHT_GRAY); 
     gameCanvas.requestFocus(); 
     frame.add(gameCanvas); 
     frame.pack(); 
     frame.setResizable(false); 
     frame.setVisible(true); 
    } 
} 

回答

2

這裏的問題不是在忙着等待(你在這裏沒有忙着等待)。

唯一的問題是KeyListener連接到CanvasFrame有輸入焦點。試着點擊Canvas,它會工作。

此外,如果您使用的是重繪循環,你不需要調用重繪在KeyListener

,請利用SwingUtilities.invokeLater從不同的線程調用的Swing/AWT功能。

移動requestFocus調用設置框架可見應該解決您的問題(因爲你不能給的東西,是沒有可見的焦點)之後。