2011-01-30 53 views
5

我正在爲我的Hang子手遊戲(SEE PICTURE HERE)製作鍵盤式按鈕,我的問題是關於內部類。我讀過關於內部類的LINK,它說您只能使用FINAL類型訪問外部變量。但是,如果我聲明這個變量,我不能再改變它的值了......所以我的問題是我需要改變內部類中的值。我的代碼如下:Java中的內部類

public class MainGame extends JDialog { 

    private String player; 
    private char [] wordChar; 
    private JButton[] buttons; 
    private int level; 
    private int score; 
    private int livesLeft; 
    private int missedGuess; 

void newGame() { 

     level = 0; 
     score = 0; 
     livesLeft = 10; 
     missedGuess = 0; 

     //label1: 
     // while (livesLeft!= 0) { 

      //get random WORD from LIST 
      Word hiddenWord = new Word(); 

      //put random word in Array 
      wordChar = new char[hiddenWord.getHiddenWord().length()]; 
      wordChar = hiddenWord.getHiddenWord().toCharArray(); 

      buttons = new JButton[wordChar.length]; 
      for (int i = 0; i < wordChar.length; i++){ 
       JButton guessWord = new JButton(" "); 
       guessWord.setFont(new Font("Microsoft Sans Serif", 1, 18)); 
       guessWord.setEnabled(false); 

       jPanel3.setLayout(new GridLayout(1, wordChar.length)); 
       jPanel3.add(guessWord); 

       buttons[i] = guessWord; 
      } 
     checkLetter(); 
     } 

    void checkLetter() { 
     int checker = 0; 
     while(checker != wordChar.length){ 
      jPanel1.setLayout(new GridLayout(3, 9, 3, 5)); 
      for (char buttonChar = 'a'; buttonChar <= 'z'; buttonChar++) { 
       String buttonText = String.valueOf(buttonChar); 
       final JButton letterButton = new JButton(buttonText); 
       letterButton.addActionListener(new ActionListener() { 
        public void actionPerformed(ActionEvent e) { 
         String actionCommand = e.getActionCommand(); 
         for (int j = 0; j < wordChar.length; j++){ 
          String text = String.valueOf(wordChar[j]); 
          if(actionCommand.equals(text)){ 
           buttons[j].setText(text); 
           checker++; //THIS CODE IS NOT POSSIBLE!!!! 
          } 
         } 
        } 
       }); 
       jPanel1.add(letterButton); 
      } 
       checker++; 
      } 
     } 

注意:上面的代碼不完整。 的int檢查用於計算有多少正確的字母都已經猜到了,這樣,如果它等於字的長度,我現在就可以進入到一個新的水平enter image description here

我怎樣才能重新做我的代碼?

+0

如果你解釋一下`checker`在做什麼,除了明顯的控制檢查,它可能會幫助人們提出設計方案。 – Carl 2011-01-30 13:51:59

回答

3

您可以聲明checker作爲外部類的字段,並使用某種方法(如increaseChecker())訪問它。

UPDATE:事情是這樣的:

1)外類創建檢查現場:

public class OuterClassName { 
    private int checker; 

    protected void increaseChecker() { 
     checker++; 
    } 

    void checkLetter() { 
     // ... 
    } 

} 

2)使用increaseChecker()方法調用,而不是checker++

+0

我不明白:( – newbie 2011-01-30 13:50:44

+0

請參閱答案 – Kel 2011-01-30 14:00:13

3

你不能訪問一個匿名內部類中的局部變量,這是一個很好的理由。 actionPerformed()方法不保證在checkLetter()函數內被調用。它將在稍後被調用,可能(並且很可能)在函數退出之後調用,因此它的局部變量將在那段時間被銷燬。因此,新創建的匿名類隱式獲取該變量的副本。但是增加副本沒有任何意義,這就是爲什麼只有最後的局部變量可以從匿名類的方法訪問。

最簡單的解決方法就是讓checker成爲外部類的字段。但是,如果僅在checkLetter()函數內訪問它,那麼它就沒有任何意義,除非它需要在checkLetter()調用之間保留其值。爲了找出真正的答案,你需要考慮爲什麼你想在actionPerformed()內部增加checker?什麼時候該發生?你想通過做什麼來達到目的?

1

爲什麼不保留匿名內部類,但讓它調用類的方法。這種方式最終不是問題。

  letterButton.addActionListener(new ActionListener() { 
       public void actionPerformed(ActionEvent e) { 
        letterButtonActionPerformed(e); // create this method 
       } 
      }); 


      //..... 


      // new method 
      private void letterButtonActionPerformed(ActionEvent e) { 
        String actionCommand = e.getActionCommand(); 
        for (int j = 0; j < wordChar.length; j++){ 
         String text = String.valueOf(wordChar[j]); 
         if(actionCommand.equals(text)){ 
          buttons[j].setText(text); 
          checker++; //THIS CODE IS NOT POSSIBLE!!!! 
         } 
        } 
      }