views:

448

answers:

5

In a Swing app a method should continue only after user enters a correct answer. The correct answer is stored in a String with user answer being set by a listener to another String. So, the code is

while (!correctAnswer.equals(currentAnswer)) {
         // wait for user to click the button with the correct answer typed into the textfield
}
// and then continue

Is everything fine with this approach or would you somehow refactor it? Doesn't it impose extra penalty on CPU? Here's a somewhat similar question.

A: 

If your strings are coming from a human user at GUI rates, there's very little point in optimizing for performance. The human won't be able to enter more than perhaps one to three strings per second, and that's nothing for the machine.

In this particular case, where you need to do stuff to get an input to test, I would suggest using a do-while loop.

unwind
+2  A: 

I don't think I get the logic there, but it reminds me of old Basic times... :-) I don't see why the application forces the user to type something already known (unless it is a password or something).

You write the typing is observed by a listener. So why not do the test there? Don't do a loop waiting for an event, let Java do it (and other stuff). If necessary, break your logic in two, and go to the second part when you detect the correct input is given in the listener.

I hope this makes sense... ;-)

PhiLho
+5  A: 

Are you new to UI programming? The reason I ask is that your answer is predicated on a procedural style of coding, which isn't what UIs are about. It tends to be event-driven.

In this case the solution is pretty easy: add an event listener (ActionListener) to the submit button and check the result there. If its OK, go on. If not, say so and let them try again.

cletus
+6  A: 

As others have suggested, you'll want to use assign a listener to the button, which will be called when the button is pressed.

Here's a incomplete example illustrating how to use an ActionListener and implementing its actionPerformed method which is called when the button is pressed:

...
final JTextField textField = new JTextField();
final JButton okButton = new JButton("OK");
okButton.addActionListner(new ActionListener() {
    public void actionPerformed(ActionEvent e)
    {
        if ("some text".equals(textField.getText()))
            System.out.println("Yes, text matches.");
        else
            System.out.println("No, text does not match.");
    }
});
...

You may just want to implement ActionListener in the class where the button and text field resides, so you don't need to declare the two objects as final. (I just used an anonymous inner class to keep the example short.)

For more information, you may want to take a look at How to Write an Action Listener from The Java Tutorials.

Also, for general information on how events work in Java, the Lesson: Writing Event Listeners from The Java Tutorials may be useful.

Edit: Changed the expression inside if statement from textField.getText().equals("some text") to "some text".equals(textField.getText()) in order to prevent a NullPointerException if textField was null, per suggestion from Mr. Shiny and New's comment.

coobird
I'd recommend doing "some text".equals(textField.getText()) to prevent a null pointer exception if getText() returns null. Good habit to get into whenever you're comparing a constant to a variable.
Mr. Shiny and New
Ah, thank you for pointing that out! I've edited the answer to take your suggestion into account.
coobird
I surely use ActionListeners, it's just that the case is beyond trivial ActionListeners (i think). More of a two-way ActionListener ;) with a crazy recursive method supplying UI components. Thanks for your reply though. On my way of refactoring.
alex
+2  A: 
OscarRyz
Desktop.getDesktop().browse( new URI("http://stackoverflow.com")); sounds so much Java 6 to me. :) Excellent!
alex
heheh it is, it is!..
OscarRyz