为计数器不工作更新 JLabel 文本输出

Updating JLabel text output for counter not working

所以我正在创建一个数字猜谜游戏。计算机生成一个随机数,用户输入一个猜测,然后计算机让用户知道他们是否赢了,或者猜测是小于还是大于随机数。这一直持续到他们做对为止,或者再次按下播放(重置它)。

我想统计并显示用户每轮的猜测次数。所以我为每个猜测递增 'tallyValue'。我知道它正在正确地计算和递增这些值。但是,例如,如果用户连续两次猜测小于随机数的值,则计数值不会在 .setText 输出上更新。它只会在用户猜测从小于随机数到大于随机数交替时更新。

我错过了什么?我试过删除然后设置文本,但我不明白为什么会这样。

MyFrame() {
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //exit out of app 
        this.setLayout(new FlowLayout());

        //add labels, buttons and input fields
        button = new JButton("Submit");
        button.addActionListener(this); //can just pass in this because we already pass actionlistener above

        JLabel instruction = new JLabel();
        instruction.setText("Input Your Guess (must be between 1 and 100");

        textField = new JTextField();
        textField.setPreferredSize(new Dimension(250,40));

        tally = new JLabel();
        tally.setText("Number of guesses: " + tallyValue);

        outputMessage = new JLabel();
        outputMessage.setText("Take a guess!");

        playAgainButton = new JButton("Play Again");
        playAgainButton.addActionListener(this);

        this.add(instruction);
        this.add(textField);
        this.add(button);
        this.add(playAgainButton);
        this.add(outputMessage);
        this.add(tally);
        this.setTitle("Number Guessing Game");
        this.setVisible(true); //make frame visible
        this.pack(); //frame size adjusts to components

        ImageIcon icon = new ImageIcon("res/game-icon.png"); //creates an image icon
        this.setIconImage(icon.getImage());//changes icon of frame

        System.out.println(randomNumber); //for testing purposes
    }

    //add any unimplemented methods because we are using an interface
    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource()==button) {
            int textFieldValue;

            this.remove(outputMessage);
            try {
                textFieldValue = Integer.parseInt(textField.getText());
                //if guess is correct
                if(textFieldValue == randomNumber) {
                    outputMessage.setText("Congratulations you guessed correctly!");
                    this.add(outputMessage);

                    tallyValue++;
                    
                    displayCount(tallyValue);

                    this.pack();
                    textFieldValue = 0; //reset text field val
                    
                    
                }
                //if guess is less than randomNumber
                if(textFieldValue < randomNumber) {
                    outputMessage.setText("Incorrect - the number I am thinking of is more than that");
                    this.add(outputMessage);

                    tallyValue++;
                    
                    displayCount(tallyValue);
                    
                    this.pack();
                    textFieldValue = 0; //reset text field val
                    
                }
                //if guess is more than randomNumber
                if(textFieldValue > randomNumber) {
                    outputMessage.setText("Incorrect - the number I am thinking of is less than that");
                    this.add(outputMessage);

                    tallyValue++;
                    System.out.println(tallyValue);
                    displayCount(tallyValue);

                    this.pack();
                    textFieldValue = 0; //reset text field val
                    
                }
             }
            catch (NumberFormatException ex){
                outputMessage.setText("You must insert a valid number");
                this.add(outputMessage);
                this.pack();
            }
        }

        if(e.getSource()==playAgainButton) {
            System.out.println("pa");
            this.remove(outputMessage);
            randomNumber = rand.nextInt(101);
            outputMessage.setText("Take a guess!");
            this.add(outputMessage);

            
            tallyValue = 0;
            displayCount(tallyValue);
            
            this.pack();
        }
    }

    private void displayCount (int tv) {
        this.remove(tally);
        tally.setText("Number of guesses:" + tv);
        this.add(tally);
        this.pack();
    }

It will only update when the users guesses alternate from less than the random number to more than the random number.

  1. 无需在 3 个不同的地方递增计数。在您 Integer.parseInt(...) 声明之后,计数应该立即递增。也就是说,无论猜测是什么,它都会在每次猜测时更新。

  2. 然后您只需使用新计数更新理货标签的文本。不需要 remove/add 框架中的标签。不需要 pack() 框架。只需设置文本就会导致标签重新绘制。所以不需要displayCount()方法。

您还应该学习如何正确使用布局管理器。目前您正在使用 FlowLayout 只会使组件显示在一行中,然后换行到下一行。这不是一个非常有效的布局,因为如果调整框架的大小,所有组件都会移动。

阅读 Layout Managers 上的 Swing 教程。您可以嵌套具有不同布局管理器的面板,以实现更灵活的布局。

    textField = new JTextField();
    textField.setPreferredSize(new Dimension(250,40));

不要对组件的大小使用幻数。而是正确使用 API,以便文本字段可以确定自己的首选大小:

    textField = new JTextField(10);

“10”将允许文本字段自行调整大小以在滚动文本之前显示 10 个“W”字符。

此外,您不应为按钮使用共享的 ActionListener。

一种方法是使用 lamba 来分离功能:

//playAgainButton.addActionListener(this);
playAgainButton.addActionListener((e) -> playAgain());

然后您在 class 中创建一个私有方法 playAgain()。现在代码按功能分成方法。