2011-01-30 41 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!!!! 
         } 
        } 
      }