Prompting the User in a Java Event Driven GUI Program

Sometimes you want to prompt the user with some text and then pick up the user's response to the prompt. The following does NOT work in Java.

TextField inText, inInt; 
String nameS, ageS;
public void paint (Graphics g) 
{	g.drawString ("Name and age",1,40); 
nameS = inText.getText (); ageS = inInt.getText (); int age = Integer.parseInt (ageS); g.drawString ("Your name is " + nameS,10,70); g.drawString ("Your age is " + age,10,90); }

The reason that it doesn't work is that the system doesn't block on the getText instruction while waiting for the user to enter a string. It immediately grabs whatever is already in the TextField (probably nothing) and returns that.

Your solution needs to be more subtle. You need to be able to do two distinct things; you need to be able to display the text and you need to be able to get the user's response whenever the user chooses to provide it. This means that the user will probably need to do something special to indicate that the input is ready. This could be pressing a button, or it could be pressing the return/enter key at the end of typing--or both.

First, let's write paint like this.

TextField inText, inInt; 

String nameS, ageS;
public void paint (Graphics g) 
{	g.drawString ("Name and age",1,40); 
	if(nameButton.replyAvailable())
{ String nameS = nameButton.getReply(); g.drawString ("Your name is " + nameS,10,70); } if(ageButton.replyAvailable()) { String ageS = ageButton.getReply(); int age = Integer.parseInt (ageS); g.drawString ("Your age is " + age,10,90); } }

Next we need to give the user a way to enter the data. To do this we build a new (possibly inner) class that extends Button and implements ActionListener:

class ResponseButton extends Button implements ActionListener
{	public ResponseButton(String name, TextField controls)
	{	super(name);
		addActionListener(this);
		this.controls = controls;
	}
	
	public void actionPerformed(ActionEvent e)
	{	controls.getText();		
	}

	public String getReply(){return reply;}

	public boolean replyAvailable(){return !reply.equals("");}

	private TextField controls;
	private String reply = "";
}

We will also need some declarations like:

ResponseButton  nameButton = new ResponseButton("Name", inText),
		ageButton  = new ResponseButton("Age", inInt);

You could also add these buttons as listeners to the TextFields that they control, so that if the user types the enter key at the end of the response in the field, the action would be the same as thet provided by a button press:

inText.addActionListener(nameButton);
inInt.addActionListener(ageButton);

Notice that the ResponseButton listens for its own events. This is a useful pattern to apply in general.

Here is an applet that implements these ideas. Note that if the ResponseButton class were inner to the main class, the third parameter of the constructor (in the version used in the applet) would not be needed. The Applet and its fields and methods (repaint) would be visible to the button.