The correct way of waiting for strings to become equal

老子叫甜甜 提交于 2019-12-11 17:06:34

问题


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.


回答1:


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.




回答2:


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.




回答3:


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... ;-)




回答4:


Yes, as everyone said here.

For a gui app the best way to handle user input is to wait for an event to be fired.

Then a method could be used to validate the input and if succeed you can continue with the flow, that could be go to another page.

Here's a complete ( yet simple ) example of a login screen, that validates the user input and if succeed performs some action.

This code has no other value than show in a complete ready to run sample how this concept is applied.

simple gui http://img229.imageshack.us/img229/1532/simplenz0.png

// * used for brevity. Preffer single class per import
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.net.*;
import java.io.*;


public class MatchString{

    private final JTextField password;
    private final JFrame frame;

    public static void main( String [] args ){
        MatchString.show();
    }

    public static void show(){
        SwingUtilities.invokeLater( new Runnable(){
            public void run(){
                new MatchString();
            }
        });
    }

    private MatchString(){
        password = new JPasswordField( 20 );
        frame = new JFrame("Go to www.stackoverflow");
        init();
        frame.pack();
        frame.setVisible( true );
    }


    private void init(){

        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );

        frame.add( new JPanel(){{
            add( new JLabel("Password:"));
            add( password );
        }});

        // This is the key of this question.
        // the password textfield is added an 
        // action listener
        // When the user press enter, the method 
        // validatePassword() is invoked.
        password.addActionListener( new ActionListener(){
            public void actionPerformed( ActionEvent e ) {
                validatePassword();
            }
        });
    }


    private void validatePassword(){            
        // If the two strings match
        // then continue with the flow
        // in this case, open SO site.    
        if ( "stackoverflow".equals(password.getText())) try {
            Desktop.getDesktop().browse( new URI("http://stackoverflow.com"));
            frame.dispose();
        } catch ( IOException ioe ){
            showError( ioe.getMessage() );
        } catch ( URISyntaxException use ){
            showError( use.getMessage() );
        } else {
            // If didn't match.. clear the text.
            password.setText("");
        }
    }
 }



回答5:


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.



来源:https://stackoverflow.com/questions/334038/the-correct-way-of-waiting-for-strings-to-become-equal

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!