Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is wrong with this Java GUI code?

I've just started learning Java GUI and faced this problem while practicing event handling. Here's the initial window

When I enter a number inside the text field it's supposed to say whether the guessed number is higher, lower or matched. If not matched it'd prompt for another number. But the window just hangs. After entering data

I'm guessing it falls in an infinite loop. Here's the code. Help me figure out where the problem is. Thanks.

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");
    }

}
like image 441
Fatiul Huq Sujoy Avatar asked Jan 13 '16 08:01

Fatiul Huq Sujoy


People also ask

Is Java GUI still used?

Majority of existing GUI java codebases are Swing and likely will stay that way until the codebase rots and nobody maintains it anymore.

What should I use for GUI in Java?

It is made up of graphical components (e.g., buttons, labels, windows) through which the user can interact with the page or application. To make graphical user interfaces in Java, use either Swing (older applications) or JavaFX.

What is the best way to create GUI in Java?

Swing and JavaFX are two commonly used applications to create GUIs in Java.


3 Answers

you don´t need a loop in your actionPerformed method. Just let it execute once, and check if it was guessed right afterwards. You are basicly just stuck in the loop when a wrong number was entered by the user. In order to get it more smooth, create the random number only when guessed is true and just execute the guess and the conditions once.

// 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?");
        }
    }
}
like image 100
SomeJavaGuy Avatar answered Sep 23 '22 05:09

SomeJavaGuy


The GUI framework has its own event loop, and its event handling (including responding to text input, button presses etc) will be blocked while user code is executing. You want your own event handler to finish as quickly as possible.

Structure it as, every time the button is pressed, the current guess is evaluated, messages are shown, and the handler ends. In between button presses, the program maintains the guess count, number to guess etc.

like image 26
Vlad Avatar answered Sep 26 '22 05:09

Vlad


You shouldnt read what the user writes on a cycle. Your event listener on the guess button should just check if the number is higher lower or equal once and then stop. It will be called again everytime the user presses the button. The way it is right now, aside from other problems there may be, is that it checks it once and stays on a loop checking forever untill its right. Its not pratical and bad programming because it will consume a lot of cpu being on an active wait like that.

like image 34
sharp_c-tudent Avatar answered Sep 24 '22 05:09

sharp_c-tudent