5 Replies - 498 Views - Last Post: 06 April 2013 - 02:45 PM Rate Topic: -----

#1 HGPolumbus  Icon User is offline

  • D.I.C Head

Reputation: 0
  • Posts: 106
  • Joined: 22-March 13

actionPerformed not functioning as expected

Posted 05 April 2013 - 07:26 PM

Hello again!

I've written a program for an assignment that creates a random number that the user tries to guess. My problem is that when I click the try button it seems to skip to clearing the field, and when I try again it does nothing. I'll include the all the code because there's some other minor things I would like to ask. Thank you guys.

public class GuessGame extends JFrame {

	private static final long serialVersionUID = 1L;
	private JFrame guessGameFrame;
	private JButton tryButton;
	private JButton exitButton;
	private JButton newGameButton;
	private JTextField guessField;
	private JTextField highLowField;
	private JLabel guessLabel;
	private JLabel introLabel;

	public GuessGame() {

		guessGameFrame = new JFrame("Guessing Game!");

		tryButton = new JButton("Try the number");
		exitButton = new JButton("Exit");
		newGameButton = new JButton("New Game?");
		guessField = new JTextField(10);
		guessLabel = new JLabel("Enter your guess: ");
		highLowField = new JTextField(50);
		introLabel = new JLabel(
				"I have a number between 1 and 1000.  Can you guess the number?");

		Container guessContainer = guessGameFrame.getContentPane();

		guessContainer.setLayout(new FlowLayout());

		guessContainer.add(introLabel);
		guessContainer.add(guessLabel);
		guessContainer.add(guessField);
		guessContainer.add(tryButton);
		tryButton.setMnemonic('T');
		guessContainer.add(exitButton);
		exitButton.setMnemonic('x');
		guessContainer.add(newGameButton);
		newGameButton.setMnemonic('N');
		newGameButton.setEnabled(false);
		guessContainer.add(highLowField);
		highLowField.setVisible(false);
		highLowField.setEditable(false);

		guessGameFrame.setSize(400, 200);
		guessGameFrame.setLocation(500, 300);

		guessGameFrame.addWindowListener(new WindowAdapter() {

			public void windowClosing(WindowEvent z) {
				System.exit(0);
			}
		});

		TryButtonHandler tbh = new TryButtonHandler();
		tryButton.addActionListener(tbh);

		ExitButtonHandler xbh = new ExitButtonHandler();
		exitButton.addActionListener(xbh);

		NewGameButtonHandler ngbh = new NewGameButtonHandler();
		newGameButton.addActionListener(ngbh);

		guessGameFrame.setVisible(true);

	}

	class ExitButtonHandler implements ActionListener {

		public void actionPerformed(ActionEvent z) {
			System.exit(0);
		}
	}

	class NewGameButtonHandler implements ActionListener {

		public void actionPerformed(ActionEvent z) {
			guessField.setText("");
			guessField.setEditable(true);
			newGameButton.setEnabled(false);

		}

	}

	class TryButtonHandler implements ActionListener {

		int guess;
		int randomNum = (int) Math.floor(Math.random() * 1001);
		int lastDistance = 0;
		int currentDistance = 0;
		int numTries = 0;
		String input;

		public void actionPerformed(ActionEvent z) {

			input = guessField.getText();
			if (input.equals("")) {
				input = ("0");
				guessField.setText("0");
			}

			guess = Integer.parseInt(input);

			if (guess == randomNum) {
				highLowField.setText("Correct!  You guessed the number in "
						+ numTries + " tries.");
				highLowField.setVisible(true);
				guessField.setText(" ");
				guessField.setEditable(false);
				newGameButton.setVisible(true);

			} else if ((guess != randomNum) && (numTries == 0)) {
				if (guess > randomNum) {
					highLowField.setText("    Too High!  Try again. ");
					highLowField.setVisible(true);
				} else {
					highLowField.setText("     Too Low!  Try again. ");
					highLowField.setVisible(true);
				}
				numTries++;

				lastDistance = Math.abs(guess - randomNum);

				guessField.setText("");
				guessField.requestFocus();

			} else if ((guess != randomNum) && (numTries != 0)) {

				currentDistance = Math.abs(guess - randomNum);

				if (currentDistance < lastDistance) {
					highLowField.setBackground(Color.red);
					highLowField.setText("     Wrong, but getting warmer! ");
					lastDistance = currentDistance;
					numTries++;

				} else if (currentDistance > lastDistance) {
					highLowField.setBackground(Color.blue);
					highLowField.setForeground(Color.white);
					highLowField
							.setText("     Wrong, and you're getting colder! ");
					lastDistance = currentDistance;
					numTries++;
				}
			}
		}

	}

	public static void main(String args[]) {

		new GuessGame();
	}
}



The other thing I wanted to ask is if this is the correct way to get a random number in the 1-1000 range, and if I'm doing it in the right spot (line 88)

int randomNum = (int) Math.floor(Math.random() * 1001);

Also should I be using a loop to get the number over and over again? When I tried to put one in it seems to lock up the GUI on the button click so I think that I don't, but I'm not sure. New to guis.

Thanks again.

This post has been edited by HGPolumbus: 05 April 2013 - 07:28 PM


Is This A Good Question/Topic? 0
  • +

Replies To: actionPerformed not functioning as expected

#2 GregBrannon  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2205
  • View blog
  • Posts: 5,239
  • Joined: 10-September 10

Re: actionPerformed not functioning as expected

Posted 06 April 2013 - 12:26 AM

Since you're turning components "off" and "on" in the JFrame, you need to validate() the container at the end of the actionPerformed() method. Add the statement,

guessGameFrame.validate();

at the end of the actionPerformed() method.

You'll also find that you set the highLowField too wide. Crank it down to 30 and adjust from there.

The "Wrong but getting warmer" logic isn't helpful the way it's currently programmed.

I hope you take this project and play around with other layouts a bit. You might also try setting the frame's preferred size and then pack()ing the JFrame just to see what that does for you. FlowLayout is simple, easy to use, and a quick way to show multiple components, but it's so clumsy and limited.
Was This Post Helpful? 1
  • +
  • -

#3 HGPolumbus  Icon User is offline

  • D.I.C Head

Reputation: 0
  • Posts: 106
  • Joined: 22-March 13

Re: actionPerformed not functioning as expected

Posted 06 April 2013 - 12:45 PM

View PostGregBrannon, on 06 April 2013 - 12:26 AM, said:

Since you're turning components "off" and "on" in the JFrame, you need to validate() the container at the end of the actionPerformed() method. Add the statement,

guessGameFrame.validate();

at the end of the actionPerformed() method.

You'll also find that you set the highLowField too wide. Crank it down to 30 and adjust from there.

The "Wrong but getting warmer" logic isn't helpful the way it's currently programmed.

I hope you take this project and play around with other layouts a bit. You might also try setting the frame's preferred size and then pack()ing the JFrame just to see what that does for you. FlowLayout is simple, easy to use, and a quick way to show multiple components, but it's so clumsy and limited.


guessGameFrame.validate(), this made aaaaalll the difference :bananaman:

We hadn't learned about the validate() method. :( The worst part is that I sent this code to my teach and he sent it back without that in it. No way it works without it. Changing my highLowField to 30 made it nice too. I keep thinking it means pixels but I know that it doesn't.

Other than that I had to clean up my logic some and how I handled the number of tries and the distances. It works though. I do have one more question. To do a second game, I have the newGame button enable, and then it clears the fields and resets everything.

class NewGameButtonHandler implements ActionListener {

		public void actionPerformed(ActionEvent z) {
			guessField.setText("");
			guessField.setEditable(true);
			highLowField.setText("");
			lastDistance = 0;
			highLowField.setVisible(false);
			newGameButton.setEnabled(false);
			randomNum = (int) (Math.random()*1001);
		}

	}


How can I uninitialize currentDistance so that when I put in the first guess of the second round it goes back to the plain Too High and Too Low and not a color with warmer or colder? DO I need to right a method to go get it. I wouldn't know what to put since those classes don't make objects.

Thanks Mr. Brannon you are the best.
Was This Post Helpful? 0
  • +
  • -

#4 GregBrannon  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2205
  • View blog
  • Posts: 5,239
  • Joined: 10-September 10

Re: actionPerformed not functioning as expected

Posted 06 April 2013 - 01:28 PM

If the instructor won't let you use validate(), then change your design to not toggle the visibility of the components in the frame. There's nothing wrong with displaying the components either empty/inactive or with instructions, like "Guess the random value and press the try button." or similar.

As for your warmer/colder logic: start by coding a "too high" (red) and "too low" (blue) message. An intelligent guesser will guess half way between the previous guess and the indicated direction. Initially, in a range of 1000, the user will guess 500. Your program should respond, "Too High" or "Too Low". The user will then guess half way in the appropriate direction, either 250 or 750. When you consider that is the typical approach, the warmer/colder indication to the user is not helpful.

For example, if the user guesses 750 when the guess should have been 250, what does "colder" mean compared to the first guess? Are they further away from the target number, did they guess the wrong direction, or both? What if the target number is 375 and the user's second guess is 250? Is the user warmer or colder? More importantly, if the user is told they're warmer or colder (either is possible), what are they supposed to do with that info, guess higher or lower? They don't know.
Was This Post Helpful? 1
  • +
  • -

#5 HGPolumbus  Icon User is offline

  • D.I.C Head

Reputation: 0
  • Posts: 106
  • Joined: 22-March 13

Re: actionPerformed not functioning as expected

Posted 06 April 2013 - 02:11 PM

View PostGregBrannon, on 06 April 2013 - 01:28 PM, said:

If the instructor won't let you use validate(), then change your design to not toggle the visibility of the components in the frame. There's nothing wrong with displaying the components either empty/inactive or with instructions, like "Guess the random value and press the try button." or similar.

As for your warmer/colder logic: start by coding a "too high" (red) and "too low" (blue) message. An intelligent guesser will guess half way between the previous guess and the indicated direction. Initially, in a range of 1000, the user will guess 500. Your program should respond, "Too High" or "Too Low". The user will then guess half way in the appropriate direction, either 250 or 750. When you consider that is the typical approach, the warmer/colder indication to the user is not helpful.


Yeah I understood what you meant about my wrong but getting warmer. I just assume that once they've made a guess, if they guess in the wrong direction it will tell them colder. If I just keep telling them higher or lower there's no point in the colors or anything. I did change it up quite a bit.

class TryButtonHandler implements ActionListener {

		int guess;
		int currentDistance = 0;
		String input;

		public void actionPerformed(ActionEvent z) {
			//JOptionPane.showMessageDialog(null, randomNum);//
			input = guessField.getText();
			if (input.equals("")) {
				input = ("0");
				guessField.setText("0");
			}

			guess = Integer.parseInt(input);
			highLowField.setVisible(true);//
			
			if (guess == randomNum) {
				highLowField.setBackground(Color.green);
				highLowField.setForeground(Color.black);
				highLowField.setText("Correct!  You guessed the number in "
						+ numTries + " tries.");
				//highLowField.setVisible(true);
				guessField.setText(" ");
				guessField.setEditable(false);
				newGameButton.setEnabled(true);
				return;//
			}
			if (guess > randomNum) {
					highLowField.setText("    Too High!  Try again. ");
					//highLowField.setVisible(true);
			} else {
					highLowField.setText("     Too Low!  Try again. ");
					//highLowField.setVisible(true);
			}
			
			numTries++;//
			guessField.setText("");
			guessField.requestFocus();
				
			if (numTries == 1) {
				lastDistance = Math.abs(guess - randomNum);
				}
			else{
				
				currentDistance = Math.abs(guess - randomNum);
				
				if (currentDistance < lastDistance) {
					highLowField.setBackground(Color.red);
					highLowField.setForeground(Color.white);
					highLowField.setText("You guessed " + guess + ", wrong, but getting warmer! ");
					lastDistance = currentDistance;
					//numTries++;

				} else if (currentDistance > lastDistance) {
					highLowField.setBackground(Color.blue);
					highLowField.setForeground(Color.white);
					highLowField
							.setText("You guessed " + guess + ", wrong, and you're getting colder! ");
					lastDistance = currentDistance;
					//numTries++;
				}
			}
			guessGameFrame.validate();
		}
	}


So it all works as per the requirements of the assignment. I'm just working on the new game part now. Infinite thanks.

This post has been edited by HGPolumbus: 06 April 2013 - 02:13 PM

Was This Post Helpful? 0
  • +
  • -

#6 HGPolumbus  Icon User is offline

  • D.I.C Head

Reputation: 0
  • Posts: 106
  • Joined: 22-March 13

Re: actionPerformed not functioning as expected

Posted 06 April 2013 - 02:45 PM

Oh! I only needed to reset the number of tries for it to work like I wanted.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1