2017-05-10 32 views
1

我想使用'w''s''a''d'鍵上下移動白盒。這是我的代碼:Java Swing中面板上的KeyListener。錯誤輸出

static int matrix[][] = { { 1, 1, 1, 1,1,1 }, { 1, 0, 0, 0,0,0 }, { 1, 3, 1, 1,0,0 }, {1,0,1,0,0,0}, {1,0,1,2,2,1}, {1,1,1,1,1,1} }; 
JPanel easyPanel(){ 

    JPanel panel = new JPanel(new GridLayout(6, 6, 0, 0)); 


    int rowNumber = 0; 
    int colNumber = 0; 


    for (int i = 0; i < 36; i++) { 
     if(colNumber == 6){ 
      colNumber = 0; 
      rowNumber++; 
     } 
     JLabel l = new JLabel(); 


     if(matrix[rowNumber][colNumber] == 0){ 
       l.setBackground(Color.pink); 
      } 
     else if(matrix[rowNumber][colNumber]==2){ 
      l.setIcon(new ImageIcon(new ImageIcon("cross.png").getImage().getScaledInstance(70, 70, Image.SCALE_DEFAULT))); 


     } 

else if(matrix[rowNumber][colNumber]==3){ 
       l.setIcon(new ImageIcon(new ImageIcon("icon.png").getImage().getScaledInstance(70, 70, Image.SCALE_DEFAULT))); 
       int row = rowNumber; 
       int col = colNumber; 
       addKeyListener(new KeyListener() { 

       @Override 
       public void keyPressed(KeyEvent ke) { 
        //move(); 
       } 
       @Override 
       public void keyReleased(KeyEvent ke) { 
        //move();. 
       } 
       @Override 
       public void keyTyped(KeyEvent ke) { 
        panel.setVisible(false); 
        matrix[row][col] = 0; 
        move(ke,row,col); 
       } 
      }); 
      } 




    private void move(KeyEvent ke,int row,int col){ 
     if(ke.getKeyChar() == 'w'){ 
      System.out.println("Pressed up"); 
      matrix[row-1][col] = 3; 
      JPanel newGame = easyPanel(); 
      newGame.setVisible(true); 
      add(newGame); 

     } 
     else if(ke.getKeyChar() =='s'){ 
      System.out.println("Pressed down"); 
      matrix[row+1][col] = 3; 
      JPanel newGame = easyPanel(); 
      newGame.setVisible(true); 
      add(newGame); 
     } 
     else if(ke.getKeyChar() == 'a'){ 
      System.out.println("Pressed left"); 
      matrix[row][col-1] = 3; 
      JPanel newGame = easyPanel(); 
      newGame.setVisible(true); 
      add(newGame); 
     } 
     else if(ke.getKeyChar() == 'd'){ 
      System.out.println("Pressed right"); 
      matrix[row][col+1] = 3; 
      JPanel newGame = easyPanel(); 
      newGame.setVisible(true); 
      add(newGame); 
     } 
     else 
      System.out.println("Invalid Input"); 
    } 

但我得到的輸出是這樣的: 默認: enter image description here

第一招 'W' - 正確的: enter image description here

下一步行動 'd' - 移動塊的移動,它移動使兩個塊白色: enter image description here

我在哪裏出錯了? 任何幫助將不勝感激。

+2

首先,我會依靠在'KeyEvent.VK_'在字符代碼常量,但那是我的。我還考慮在KeyListener上使用[Key Bindings API](https://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html),因爲它可以解決與焦點相關的問題 – MadProgrammer

+0

@MadProgrammer好吧,我會給所有這一切看。有關如何修復此程序的任何建議? –

+0

而不是每次都重新創建面板,考慮使用一種可以更新標籤的機制,而不是根據對模型的更改(因此您不必更新UI的整個狀態,只需更改) – MadProgrammer

回答

2

所以在此基礎上...

} else if (matrix[rowNumber][colNumber] == 3) { 
    l.setIcon(new ImageIcon(new ImageIcon("icon.png").getImage().getScaledInstance(70, 70, Image.SCALE_DEFAULT))); 
    int row = rowNumber; 
    int col = colNumber; 
    addKeyListener(new KeyListener() { 

     @Override 
     public void keyPressed(KeyEvent ke) { 
      //move(); 
     } 

     @Override 
     public void keyReleased(KeyEvent ke) { 
      //move();. 
     } 

     @Override 
     public void keyTyped(KeyEvent ke) { 
      panel.setVisible(false); 
      matrix[row][col] = 0; 
      move(ke, row, col); 
     } 
    }); 
} 

每次easyPanel被調用,它在基質中找到3,它增加了一個新的KeyListener,假設你正確地更新矩陣,這意味着第一次被叫,你註冊一個KeyListener,然後下一次你打電話easyPanel,你添加另一個,等等。

KeyListener應該單獨註冊並且只做一次。事實上,我強烈推薦使用而不是KeyListener,因爲它可以解決與焦點相關的問題。

我也會考慮一個不同的更新模型。而不是每次重新創建UI,只需創建另一個基於matrix值的JLabel s矩陣。

然後,您可以更新matrix

matrix[row][col] = 0; 

然後更新標籤

updateUI(row, col); 

可能做這樣的事情......

switch (matrix[row][col]) { 
    case 0: labels[row][col].setIcon(null); 
      break; 
    case 2: labels[row][col].setIcon(crossIcon); 
      break; 
    case 3: labels[row][col].setIcon(playerIcon); 
      break; 
} 
repaint(); 

這將減少開銷的金額並降低閃爍的風險。

你也應該預先緩存和重新使用您的圖標