Hi, everybody. I've made a code of a "for" loop. Once i exceeds 4, the loop must stop. The input is in a JTextField. The problem is that the loop never stops although it exceeds 4. Can anybody help me?

The problem is here :

public void compare(int x)
{

     for(int i=0;i<5;i++)
     {

        int n=Integer.parseInt(t.getText());

        if(n==x)
        {
            l2.setText("Astonishing ! The number is really "+n);
            t.setEditable(false);
            break;
        }
        else if(n>x)
        {

            l2.setText("Move towards less values");
            continue;
        }
        else if(n<x)
         {
             l2.setText("Move larger");
               continue;
          }

      }
     t.setText(null);

}

For more details please contact me through the site. Thanks a lot.

Edited 3 Years Ago by Dani: Formatting fixed

One thing I would not do is declare a variable inside of a loop:

...
for (int i = 0; i < 5; i++) {
  int n = Integer.parseInt(t.getText());
...

Put this instead:

public void compare(int x) {
  int n = Integer.parseInt(t.getText());
  for (int i = 0; i < 5; i++) {
    ...
    ...
  }
}

This will cause the program to needlessly re-parse that value in the JTextField. That's just a style pointer though, and doesn't get to the source of the problem.

I'm almost certain the problem lies with those continue; statements. What continue does, is halts the loop at the current step, and forcefully start it from the beginning again.

Take out the continue statements, and see if that changes anything; the loop will continue after any instruction in the if/else/else-if blocks are executed.

I assume you are wanting the user to get 5 guesses at the number before ending. This isn't really what your loop is doing though. It is evaluating the same input 5 times (or less if they got it right) and then exiting.

int n = Integer.parseInt(t.getText());

will not wait for input from the user line a Scanner.nextInt() would. It just reads that field each iteration and keeps going. You will need to move the loop up to a different method (like a "Try Again" button handler) that allows them to enter up to 5 guesses before begin disabled. You could leave the the compare code in your method if you like, but you will need the loop to be separate so that you only read new input when they hit the button (or press enter if you want to use an ActionListener on the test field).

First of all, I'd like to thank you for your participation.Second, ...

This will cause the program to needlessly re-parse that value in the JTextField.

I need to make this as the user'll enter different numbers and the program should compare each number to a randomly generated one. My program does the comparison well, but it doesn't stop after the 5 iterations are completed. I think you are right concerning the "continue" statements. However, it didn't make any difference when I removed them!

Thanks for replying to my question. Adding a "try again" button is a good idea, but I'm restricted to a certain design consisting of : one text field, two labels and only one button. Thanks again!

I need to make this as the user'll enter different numbers and the program should compare each number to a randomly generated one.

That's fine, but having the loop repeatedly call Integer.parseInt() is just going to re-parse the first number it comes across (if they're separated by spaces) or it will just mush all of the integral values together to make one big number.

Please stop me if I'm on the wrong track, but shouldn't the user have to click a button to get it to compare the value they typed in and the number? Every time the user enters a new number, they will have to click a "Compare" button of sorts.

Why does it make 5 iterations?

Could you please describe what exactly you're trying to get your program to do?

EDIT:
Not going to lie, this is starting to sound a little like homework. But don't get me wrong, I have nothing against helping people with homework, I just won't do it for them. I have also found it's much easier to help somebody when they post the assignment verbatim.

Thanks for replying to my question. Adding a "try again" button is a good idea, but I'm restricted to a certain design consisting of : one text field, two labels and only one button. Thanks again!

That's fine. Keep a counter of the number of tries, increment when user hits your button to compare a guess, and when they hit five tries it's over. You really don't even need a loop for anything at all.

Please stop me if I'm on the wrong track, but shouldn't the user have to click a button to get it to compare the value they typed in and the number? Every time the user enters a new number, they will have to click a "Compare" button of sorts.

The comparison should be made automatically by pressing "enter", not through a button as the problem says.

Why does it make 5 iterations?

To grant the user the chance to try guessing the number more than one time.

Could you please describe what exactly you're trying to get your program to do?

*The program is supposed to build a GUI interface of two labels, one text field ,and one button.
*The program should generate a random number from 1 to 1000.
*The user role is to guess the random number through a fixed number of trials (which is 5 here).
*One of the labels is for displaying a certain statement that shouldn't be changed. The other has three states :
1- when the guessed number = the random number.
2- when the guessed number > the random number.
3- when the guessed number < the random number.
*At each state the label changes the statement after every trial.
*At state "1" the text editor becomes uneditable.
*The background color should be changed to "red" when the user get near the random number and changed to "blue" when the user get far from the random number.

CONCERNING THE EDIT PART OF YOUR REPLY :

EDIT:
Not going to lie, this is starting to sound a little like homework. But don't get me wrong, I have nothing against helping people with homework, I just won't do it for them. I have also found it's much easier to help somebody when they post the assignment verbatim.

You are right this is a homework, but I don't like to make somebody to do my work. First I keep trying until I reach. Once I find a problem that I can not handle, I try to get help only with the parts I couldn't solve. I've explained the whole task to make you get the point, but I'm able to solve it except the part I asked about.

For more details :
I've uploaded the code I made on a site by which it can be viewed without downloading and this is the link :
http://rafb.net/p/gqMbip25.html

Sorry, forgot to say that the button is made to start a new game, i mean to generate a new random number and follow the steps from the beginning.

Sweet. :)

Alright. I looked over the code you have, and I would do it much differently than you have done it (while still staying within the requirements).

  1. Get rid of the constructor for the class. Move the contents into the main() function.
  2. I wouldn't implement java.awt.event.ActionListener. Instead, I would use an inline class like so:
    button.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        // do stuff
      }
    });

What you've got is a good start.

What you've got is a good start. Here's how I would do it:

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

public class GuessGame extends JFrame {

 private static JButton button;
 private static JLabel label1, label2;
 private static JTextField textfield;
 private static Color backgroundColor;
 private static Container content;
 
 private int valueToGuess; // Equivalent to "x" in your code.
 private int numberOfTrials = 0;

 public static void main(String[] args) {
  
  initializeComponents();
  
  valueToGuess = randomNumber();  // Initialize valueToGuess.

  finalizeComponents();  

 }

 private static void resetTrialCounter() {
  
  numberOfTrials = 0;

 }

 private static int randomNumber(int min, int max) {
   
  return (min + (int)(Math.random() * b));

 }

 private static void compare(int a, int b) {

  if (numberOfTrials >= 5) return;
 
  if (a == b) {
   label2.setText("Astonishing! The number is actually " + a + "!");
   textfield.setEditable(false);
   resetTrialCounter(); // Set the numberOfTrials back to 0 (zero).
  } else if (a > b) {
   label2.setText("Move towards lesser values.");
   textfield.setText(null);
   numberOfTrials++;
  } else {
   label2.setText("Move towards larger values.");
   textfield.setText(null);
   numberOfTrials++;
  }

 }

 private static void initializeComponents() {

  content = this.getContentPane();
  content.setLayout(new BorderLayout());
  content.setBackground(backgrounColor);
  
  this.setSize(511, 134);

  label1 = new JLabel("I have a number between 1 and 1000. Can you guess my number? Enter your guess:");
  label2 = new JLabel("--------------------------------------------------");
  backgroundColor = new Color(255, 250, 240);

  button = new JButton("New Game");
  button.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent ae) {
    label2.setText("--------------------------------------------------");
    textfield.setText(null);
    x = randomNumber(); // Assign x a new "random" value.
   }
  });

  textfield = new JTextField(20);
  textfield.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent ae) {
    compare(valueToGuess, Integer.parseInt(textfield.getText()));
   }
  });

 }

 private static void finalizeComponents() {
  
  content.add(label1);
  content.add(textfield);
  content.add(label2);
  content.add(button);

  this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  this.setVisible(true);

 }

}

I know you're not dumb, so I'm not going to give you the "don't copy it verbatim" spiel. I haven't written in Java for a while, and I was looking for something to hack out; just scratching an algorithmic itch. Use this as an example. What you had was good, it just wasn't very readable (at least to me). I like to stay away from extends and implements hooks when defining a class (there is a time and a place for them, and this is - sort of - one of them). I find it tends to make things a little harder to figure out.

"Makes things as simple as possible, but no simpler."

Actually, making every method static and running the whole thing through main() is just making a procedural program and misses the whole point of OO. Main should only be used as an entry point to set up the needed class(es).

So?

I learned Java just so I knew at least one, non-Smalltalk-based, OOP language.

I'm still making use of other classes within the program (javax.swing.JFrame, javax.swing.JButton, etc.). I don't see what the big deal is. And my take on that algorithm is *not* avoiding the "point" of OOP. I'm providing a clean, readable program that works.

And thank you for clarifying what main()'s purpose is in this world - here I am thinking it's just some useless, needed function. *rolls eyes*

I think it's stupid to instantiate a class from within itself.

So?

I learned Java just so I knew at least one, non-Smalltalk-based, OOP language.

I'm still making use of other classes within the program (javax.swing.JFrame, javax.swing.JButton, etc.). I don't see what the big deal is. And my take on that algorithm is *not* avoiding the "point" of OOP. I'm providing a clean, readable program that works.

At least you aren't touchy about a suggestion.:-O
Your program certainly does work, it just demonstrates a methodology that a beginner may learn some bad habits from. Making everything static and calling it directly from main() is not a good standard practice.

And thank you for clarifying what main()'s purpose is in this world - here I am thinking it's just some useless, needed function. *rolls eyes*

Well, evidently you do need some clarification, so roll your eyes all you wish - it doesn't make it correct. main() should not directly call state-dependent methods directly inside a class. It should generally be used in a manner like an external driver program to initialize the object and utilize the public methods of that object. The object itself should handle any necessary internal interaction.

I think it's stupid to instantiate a class from within itself.

The object has to come from somewhere. Java only runs .class files and objects don't just pop into being on their own. You shouldn't really think of main() as being part of a class, but rather an entry point to running that class. Use main to set it up and let the object itself take it from there.

I'm sorry if you took my comment as a personal affront, as it wasn't the intention and the code was probably very helpful to the poster. However, those new to Java often aren't yet aware of why things are written the way they are and bad habits can be learned early from sample code they don't fully understand. That was the only reason I felt it necessary to mention the usage of main().

Comments
Spot on.
This question has already been answered. Start a new discussion instead.