这个 Java GUI 代码有什么问题?

What is wrong with this Java GUI code?

我刚开始学习 Java GUI,在练习事件处理时遇到了这个问题。 Here's the initial window

当我在文本字段中输入一个数字时,它应该会说出猜测的数字是更高、更低还是匹配。如果不匹配,它会提示输入另一个号码。但是 window 只是挂起 After entering data

我猜它陷入了无限循环。这是代码。 帮我看看问题出在哪里。谢谢

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class RandomNumGame extends JFrame {
    private JLabel promptLabel, resultLabel, answerLabel;
    private int tries=1, randomNum, guessNum;
    private JButton button;
    private JTextField txt; 
    private boolean guessed;

    public RandomNumGame() {
        setLayout(new FlowLayout());

        promptLabel = new JLabel("Guess a number(1-1000): ");
        add(promptLabel);

        txt = new JTextField(7);
        add(txt);

        button = new JButton("Guess!");
        add(button);

        resultLabel = new JLabel("");
        add(resultLabel);

        /*answerLabel = new JLabel("");
        add(answerLabel);
        */

        Event e = new Event();
        button.addActionListener(e);
    }

    private class Event implements ActionListener{
        public void actionPerformed(ActionEvent e){
            randomNum = (int )(Math.random() * 1000 + 1);
            guessed=false;
            do{
                try{
                    guessNum = (int)(Double.parseDouble(txt.getText()));
                    if(guessNum>randomNum){
                        resultLabel.setText("Your number is higher. Try Again");
                    }
                    else if(guessNum<randomNum){
                        resultLabel.setText("Your number is lower. Try Again");
                    }
                    else{
                        resultLabel.setText("Your number matched!");
                        guessed=true;
                    }
                }
                catch(Exception ee){
                    resultLabel.setText("Enter a legit number. What are you stupid?");
                }
            }while(!guessed);

        }
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        RandomNumGame ran = new RandomNumGame();
        ran.setDefaultCloseOperation(EXIT_ON_CLOSE);
        ran.setSize(300, 120);
        //ran.pack();
        ran.setVisible(true);
        ran.setTitle("Random Number Game");
    }

}

您的随机数和文本输入在循环之前将相同。我假设 value 不会落入 guessed 变为 true 的 else 条件。要么您需要在 while 循环本身中添加随机数生成语句。即

do{
randomNum = (int )(Math.random() * 1000 + 1); //It required here
try{
                    guessNum = (int)(Double.parseDouble(txt.getText()));
                    if(guessNum>randomNum){
                        resultLabel.setText("Your number is higher. Try Again");
                    }
                    else if(guessNum<randomNum){
                        resultLabel.setText("Your number is lower. Try Again");
                    }
                    else{
                        resultLabel.setText("Your number matched!");
                        guessed=true;
                    }
                }
                catch(Exception ee){
                    resultLabel.setText("Enter a legit number. What are you stupid?");
                }
            }while(!guessed);

GUI 框架有自己的事件循环,它的事件处理(包括响应文本输入、按钮按下等)将在用户代码执行时被阻塞。您希望自己的事件处理程序尽快完成。

将其构造为,每次按下按钮时,都会评估当前的猜测,显示消息,然后处理程序结束。在按下按钮之间,程序会保持猜测次数、猜测次数等。

你不应该阅读用户在循环中写的内容。您在猜测按钮上的事件侦听器应该只检查数字是更高还是更低或等于一次然后停止。每次用户按下按钮时都会再次调用它。现在的方式是,除了可能存在的其他问题外,它只检查一次并一直循环检查直到正确为止。它不实用且编程不好,因为它会消耗大量 cpu 像那样处于活动等待状态。

您的 actionPerformed 方法中不需要循环。让它执行一次,然后检查它是否被猜对了。当用户输入错误的数字时,您基本上只是陷入了循环。为了更顺利,只在guessedtrue时创建随机数,并且只执行一次猜测和条件。

// Change constructor
public RandomNumGame() {
    ...
    guessed = true; // initialize to true to create a new number when you click
}
private class Event implements ActionListener{
    public void actionPerformed(ActionEvent e){
        if(guessed) { // If the number was guessed, on the next click you get a new random number
            randomNum = (int )(Math.random() * 1000 + 1);
            guessed = false;
        }
        try{
            guessNum = (int)(Double.parseDouble(txt.getText()));
            if(guessNum>randomNum){
               resultLabel.setText("Your number is higher. Try Again");
            }
            else if(guessNum<randomNum){
               resultLabel.setText("Your number is lower. Try Again");
            }
            else{
               resultLabel.setText("Your number matched! Click again for a new Number");
               guessed=true;
            }
        }
        catch(Exception ee){
            resultLabel.setText("Enter a legit number. What are you stupid?");
        }
    }
}

你说的对,就是环路问题。如果您输入的第一个数字与 randomNum 不匹配,变量 guessed 将永远不会设置为 true。我建议您执行以下操作:

  1. 不要在事件处理程序中初始化 randomNum。在构造函数中执行。
  2. 删除 do{...} while(!guessed)。你不需要这里的循环,现在只需拉出你在循环中的逻辑