Программа / GUI зависает после добавления цикла while - PullRequest
2 голосов
/ 19 июня 2019

Я пытаюсь добавить цикл while для подсчета количества попыток и добавления его к сообщению в моем графическом интерфейсе. После добавления цикла while программа зависает, но ошибки не выводятся на консоль.

Я протестировал его без графического интерфейса и получил возможность печатать с использованием System.out.print, но не могу даже разрешить второй ввод. Я должен остановить запуск кода, чтобы выйти.

Любой совет будет оценен!

import javax.swing.JFrame;
import javax.swing.JLabel;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.util.*;
import javax.swing.SwingConstants;
import java.awt.Font;
import javax.swing.JTextField;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class GuessingGame extends JFrame {
private JTextField txtGuess;
private JLabel lblOutput;
private int theNumber;
private int attempt;
public void checkGuess() {
    String guessText = txtGuess.getText();
    String message = "";
    try {

        int guess = Integer.parseInt(guessText);
        while(guess!=theNumber) {
            if (guess < 0 || guess >100) {
                message = "Please enter a number between 0 and 100";
                attempt++;
            }
            else if (guess < theNumber) {
                message = guess + " is too low. Try again.";
                attempt++;
            }
            else if (guess > theNumber) {
                message = guess + " is too high. Try again.";
                attempt++;
            }
            else {
                message = guess + " is correct! It took " + attempt+ " attempts. Starting new game.";
                attempt++;
                newGame();
            }
        }
    } 
        catch(Exception e) {
        message= "Enter a whole number between 0 and 100";
    } 
        finally {
            lblOutput.setText(message);
            txtGuess.requestFocus();
            txtGuess.selectAll();
        }
}
public void newGame() {
    theNumber = (int)(Math.random() * 100 + 1);
    }

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

    JLabel lblHiloGuessingGame = new JLabel("Hi-Lo Guessing Game");
    lblHiloGuessingGame.setFont(new Font("Tahoma", Font.BOLD, 15));
    lblHiloGuessingGame.setHorizontalAlignment(SwingConstants.CENTER);
    lblHiloGuessingGame.setBounds(12, 35, 408, 16);
    getContentPane().add(lblHiloGuessingGame);

    JLabel lblGuessANumber = new JLabel("Guess a number between 1 and 100");
    lblGuessANumber.setHorizontalAlignment(SwingConstants.CENTER);
    lblGuessANumber.setBounds(58, 86, 245, 16);
    getContentPane().add(lblGuessANumber);

    txtGuess = new JTextField();
    txtGuess.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            checkGuess();
        }
    });
    txtGuess.setBounds(310, 85, 32, 19);
    getContentPane().add(txtGuess);
    txtGuess.setColumns(10);

    JButton btnGuess = new JButton("Guess!");
    btnGuess.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
        checkGuess();
        }
        });
    btnGuess.setBounds(163, 137, 97, 25);
    getContentPane().add(btnGuess);

    lblOutput = new JLabel("Enter a number and click guess");
    lblOutput.setHorizontalAlignment(SwingConstants.CENTER);
    lblOutput.setFont(new Font("Tahoma", Font.ITALIC, 13));
    lblOutput.setBounds(84, 197, 265, 19);
    getContentPane().add(lblOutput);
}

public static void main(String[] args) {
    GuessingGame theGame = new GuessingGame();
    theGame.newGame();
    theGame.setSize(new Dimension(450,300));
    theGame.setVisible(true);
    }

}

1 Ответ

1 голос
/ 19 июня 2019

Я не думаю, что вам нужен обработчик выполненного действия для текстового поля, потому что выполнение каких-либо действий с текстовым полем не должно считаться попыткой, верно? Только нажатие кнопки «Угадай» считается попыткой.

Так что вы можете удалить это:

txtGuess.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        checkGuess();
    }
});

Теперь checkGuess будет вызываться всякий раз, когда пользователь нажимает кнопку. Прямо сейчас он проанализирует номер из текстового поля и введет цикл while, чтобы проверить этот номер. Однако, поскольку guess никогда не изменяется в цикле while, цикл while никогда не прерывается.

Даже если вы прочитаете guess внутри цикла while, guess все равно не изменится, потому что во время выполнения цикла while пользователь не может взаимодействовать с пользовательским интерфейсом.

Лучший способ сделать это - просто удалить цикл while:

public void checkGuess() {
    String guessText = txtGuess.getText();
    String message = "";
    try {

        int guess = Integer.parseInt(guessText);
        if (guess < 0 || guess >100) {
            message = "Please enter a number between 0 and 100";
            attempt++;
        }
        else if (guess < theNumber) {
            message = guess + " is too low. Try again.";
            attempt++;
        }
        else if (guess > theNumber) {
            message = guess + " is too high. Try again.";
            attempt++;
        }
        else {
            message = guess + " is correct! It took " + attempt+ " attempts. Starting new game.";
            attempt++;
            newGame();
        }
    } 
        catch(Exception e) {
        message= "Enter a whole number between 0 and 100";
    } 
        finally {
            lblOutput.setText(message);
            txtGuess.requestFocus();
            txtGuess.selectAll();
        }
}

Хотя кажется, что вам нужен цикл while, на самом деле это не так. Это связано с тем, что checkGuess будет вызываться каждый раз, когда вы нажимаете кнопку Guess.

В отличие от командной строки, вы не запрашиваете ввода в программе с графическим интерфейсом, вы ждете этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...