Не удается сделать кнопку видимой в Java Swing

#java

#java

Вопрос:

У меня есть кнопка под названием «Играть снова!», Которую я хочу скрыть, а затем показать, когда пользователь выигрывает или проигрывает и хочет играть снова.

Это моя функция:

 public void checkGuess() {
    String guessText = txtGuess.getText();
    txtGuess.setText("");// Empties the contents of the text field.
    String message = "";
    try {
        int guess = Integer.parseInt(guessText);
        if (numberOfTries == 0) {
            message = "You Lost! A new game has begun and you have 8 guesses remaining.";
        }
        else if (guess < theNumber) {
            message = guess   " is too low. Try again. You have "   numberOfTries   " tries left!";

        }
        else if (guess > theNumber) {
            message = guess   " is too high. Try again. You have "   numberOfTries   " tries left!";
        }
        else {
            message = guess   " is correct. Let's play again!";
        }
    } catch (Exception e) {
        message = "Enter a whole number between 1 and 100.";
    } finally {
        lblOutput.setText(message);
        txtGuess.requestFocus();
        txtGuess.selectAll();
        
    }
    decrementNumberOfTries();
}
 

Если я покажу кнопку, когда она будет создана, кнопка будет видна. Это всего лишь демонстрационная версия, я хочу скрыть ее при запуске программы, добавив строки:

     JButton btnPlayAgain = new JButton("Play Again");
    btnPlayAgain.setVisible(true);
 

введите описание изображения здесь

Обычно это начиналось бы как скрытое:

     JButton btnPlayAgain = new JButton("Play Again");
    btnPlayAgain.setVisible(false);
 

Вот как должно выглядеть окно, когда кнопка скрыта:

введите описание изображения здесь

Если я установлю кнопку видимой там, где я хочу, чтобы она была в моей функции, кнопка не станет видимой, а другие сообщения (например, «Вы потеряли …») вообще не появятся на экране :

 public class GuessingGame extends JFrame {
    private static final long serialVersionUID = 1L;
    private JLabel lblOutput;
    private int theNumber;
    private JTextField txtGuess;
    private int numberOfTries = 8;
    private JButton btnPlayAgain;
    
    public void checkGuess() {
        String guessText = txtGuess.getText();
        txtGuess.setText("");// Empties the contents of the text field.
        String message = "";
        try {
            int guess = Integer.parseInt(guessText);
            if (numberOfTries == 0) {
                message = "You Lost! A new game has begun and you have 8 guesses remaining.";
                btnPlayAgain.setVisible(false);
                
            }
            else if (guess < theNumber) {
                message = guess   " is too low. Try again. You have "   numberOfTries   " tries left!";

            }
            else if (guess > theNumber) {
                message = guess   " is too high. Try again. You have "   numberOfTries   " tries left!";
            }
            else {
                message = guess   " is correct. Let's play again!";
                btnPlayAgain.setVisible(false);
            }
        } catch (Exception e) {
            message = "Enter a whole number between 1 and 100.";
        } finally {
            lblOutput.setText(message);
            txtGuess.requestFocus();
            txtGuess.selectAll();
            
        }
        decrementNumberOfTries();
    }
 

Я объявляю кнопку в верхней части моего класса:

 private JButton btnPlayAgain;
 

Это мои decermentNumberOfTries() newGame() методы и:

 public void newGame() {
    numberOfTries = 8;
    theNumber = (int) (Math.random() * 100   1);
}

public void decrementNumberOfTries() {
    --numberOfTries;        
}
 

И это функция, которая создает окно:

 public GuessingGame() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setTitle("Tim's Hi-Lo Guessing Game");
    getContentPane().setLayout(null);

    JLabel lblTitle = new JLabel("Tim's Hi-Lo Guessing Game");
    lblTitle.setFont(new Font("Tahoma", Font.BOLD, 15));
    lblTitle.setHorizontalAlignment(SwingConstants.CENTER);
    lblTitle.setBounds(-10, 15, 436, 32);
    getContentPane().add(lblTitle);

    JLabel lblGuessANumber = new JLabel("Guess a number between 1 and 100:");
    lblGuessANumber.setBackground(new Color(240, 240, 240));
    lblGuessANumber.setHorizontalAlignment(SwingConstants.RIGHT);
    lblGuessANumber.setBounds(83, 57, 215, 13);
    getContentPane().add(lblGuessANumber);

    txtGuess = new JTextField();
    txtGuess.addActionListener((ActionEvent e) -> {
        checkGuess();
    });
    txtGuess.setHorizontalAlignment(SwingConstants.RIGHT);
    txtGuess.setBounds(239, 85, 27, 19);
    getContentPane().add(txtGuess);
    txtGuess.setColumns(10);

    JButton btnGuess = new JButton("Guess!");
    btnGuess.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            checkGuess();
        }
    });
    btnGuess.setBounds(146, 84, 85, 21);
    getContentPane().add(btnGuess);

    lblOutput = new JLabel("Enter a number above and click Guess!");
    lblOutput.setHorizontalAlignment(SwingConstants.CENTER);
    lblOutput.setBounds(-40, 152, 500, 13);
    getContentPane().add(lblOutput);
    
    JButton btnPlayAgain = new JButton("Play Again");
    btnPlayAgain.setVisible(false);
    btnPlayAgain.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            newGame();
        }
    });
    btnPlayAgain.setBounds(146, 115, 132, 21);
    getContentPane().add(btnPlayAgain); 
    
}
 

Мои вопросы: почему кнопка не становится видимой, когда я устанавливаю значение visible в true?

Если я попытаюсь установить видимую в операторе if, подобном этому:

         if (numberOfTries == 0) {
            message = "You Lost! A new game has begun and you have 8 guesses remaining.";
            btnPlayAgain.setVisible(false);
            
        }
 

Почему message не отображается?

Как я могу правильно настроить видимость кнопки?

Это весь мой код, на случай, если это поможет: полный код

Комментарии:

1. Я думаю, что проблема не связана с логикой отображения сообщения. Не могли бы вы добавить логику метода «decrementNumberOfTries»?

2. Хорошо, спасибо. Я добавил эту функцию в OP и разместил весь свой код в виде вставки.

Ответ №1:

Проблема заключается в исключении NullPointerException при попытке сделать видимой кнопку.

 if (numberOfTries == 0) {
    message = "You Lost! A new game has begun and you have 8 guesses remaining.";
    btnPlayAgain.setVisible(false); //This is null
    
}
 

Чтобы устранить эту проблему, вам необходимо изменить объявление btnPlayAgain. В вашем коде в основном было объявлено так:

 JButton btnPlayAgain = new JButton("Play Again");
 

Попробуйте изменить на это:

 btnPlayAgain = new JButton("Play Again");