Внутренние классы в Java - PullRequest
       2

Внутренние классы в Java

5 голосов
/ 30 января 2011

Я делаю клавиатурные кнопки для моей игры в Hangman ( СМОТРИТЕ КАРТИНУ ЗДЕСЬ ), моя проблема в внутренних классах. Я прочитал это LINK о внутренних классах, и там говорится, что вы можете получить доступ только к внешним переменным с типом FINAL. Но если я объявил переменную как таковую, я больше не смогу изменить ее значение ... Поэтому моя проблема в том, что мне нужно изменить значение внутри внутреннего класса. Мой код выглядит следующим образом:

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

Как я могу заново сделать свой код?

Ответы [ 3 ]

3 голосов
/ 30 января 2011

Вы не можете получить доступ к локальным переменным в анонимном внутреннем классе, и это по уважительной причине.Не гарантируется, что метод actionPerformed () будет вызван внутри функции checkLetter ().Он будет вызван позже, возможно (и наиболее вероятно) после выхода из функции, поэтому к этому времени ее локальные переменные будут уничтожены.Следовательно, вновь созданный анонимный класс неявно получает копию этой переменной.Но не было бы никакого смысла увеличивать копию, поэтому только конечные локальные переменные могут быть доступны из методов анонимного класса.

Самый простой обходной путь - просто сделать checker полем внешнегоучебный класс.Но это не имело бы никакого смысла, если бы к нему обращались только внутри функции checkLetter (), если только ему не нужно сохранять свое значение между вызовами checkLetter ().Чтобы узнать верный ответ, вам нужно подумать, почему вы пытаетесь увеличить checker внутри actionPerformed ()?Когда это должно произойти и чего вы пытаетесь достичь, делая это?

3 голосов
/ 30 января 2011

Вы можете объявить checker как поле внешнего класса и получить к нему доступ с помощью некоторого метода, например, increaseChecker().

ОБНОВЛЕНИЕ: Примерно так:

1) Создать поле проверки во внешнем классе:

public class OuterClassName {
    private int checker;

    protected void increaseChecker() {
        checker++;
    }

    void checkLetter() {
        // ...
    }

}

2) Использовать вызов метода increaseChecker() вместо checker++

1 голос
/ 30 января 2011

Почему бы не сохранить анонимный внутренний класс, а вызвать его для вызова метода класса. Таким образом, финал не проблема.

            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!!!!
                        }
                    }
            }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...