等待字符串相等的正确方法

The correct way of waiting for strings to become equal

提问人:yanchenko 提问时间:12/2/2008 最后编辑:deHaaryanchenko 更新时间:9/2/2019 访问量:1336

问:

在 Swing 应用中,只有在用户输入正确答案后,方法才应继续。正确答案存储在 中,用户答案由一个侦听器设置为另一个 。所以,代码是StringString

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

这种方法是否一切正常,或者您会以某种方式重构它?它不会对 CPU 施加额外的惩罚吗? 这是一个有点类似的问题

Java While-loop CPU 周期

评论


答:

0赞 unwind 12/2/2008 #1

如果您的字符串以 GUI 速率来自人类用户,那么针对性能进行优化就没有多大意义了。人类每秒无法输入超过一到三根弦,这对机器来说不算什么。

在这种特殊情况下,您需要做一些事情来获取要测试的输入,我建议使用循环。do-while

2赞 PhiLho 12/2/2008 #2

我不认为我明白那里的逻辑,但它让我想起了旧的 Basic 时代...... :-)我不明白为什么应用程序会强制用户输入已知的内容(除非它是密码或其他东西)。

你写的打字是由一个侦听器观察到的。那么为什么不在那里做测试呢?不要做一个等待事件的循环,让 Java 来做(和其他东西)。如有必要,将逻辑一分为二,并在检测到侦听器中给出了正确的输入时转到第二部分。

我希望这是有道理的...... ;-)

5赞 cletus 12/2/2008 #3

您是UI编程的新手吗?我问的原因是你的答案是基于程序化的编码风格,这不是 UI 的意义所在。它往往是事件驱动的。

在这种情况下,解决方案非常简单:在提交按钮中添加一个事件侦听器 () 并在那里检查结果。如果没问题,请继续。如果没有,请说出来,让他们再试一次。ActionListener

6赞 coobird 12/2/2008 #4

正如其他人所建议的那样,您需要使用“为按钮分配侦听器”,该按钮将在按下按钮时调用。

下面是一个不完整的示例,演示如何使用 ActionListener 并实现其 actionPerformed 方法,该方法在按下按钮时调用:

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

您可能只想在按钮和文本字段所在的类中实现 ActionListener,因此无需将这两个对象声明为 。(我只是使用了一个匿名的内部类来保持示例简短。final

有关更多信息,您可能想看看 Java 教程中的如何编写操作侦听器

此外,有关事件在 Java 中如何工作的一般信息,Lesson: Writing Event Listeners from The Java Tutorials 可能会有所帮助。

编辑:根据 Shiny 先生和 New 的评论的建议,将语句中的表达式从 to 更改为 if was。iftextField.getText().equals("some text")"some text".equals(textField.getText())NullPointerExceptiontextFieldnull

评论

0赞 Mr. Shiny and New 安宇 12/3/2008
我建议做“一些文本”.equals(textField.getText())以防止在getText()返回null时出现null指针异常。每当您将常量与变量进行比较时,都要养成良好的习惯。
0赞 coobird 12/3/2008
啊,谢谢你指出这一点!我已经编辑了答案以考虑您的建议。
0赞 yanchenko 12/5/2008
我当然使用 ActionListeners,只是这种情况超出了微不足道的 ActionListeners(我认为)。更像是一个双向的 ActionListener ;)使用提供 UI 组件的疯狂递归方法。谢谢你的回复。在我的重构之路上。
2赞 OscarRyz 12/3/2008 #5

是的,正如大家在这里所说的那样。

对于 GUI 应用,处理用户输入的最佳方式是等待事件被触发。

然后可以使用一种方法来验证输入,如果成功,您可以继续流,可以转到另一个页面。

这是一个完整(但简单)的登录屏幕示例,它验证用户输入,如果成功,则执行一些操作。

此代码除了在完整的准备运行示例中显示如何应用此概念外,没有其他值。

简单的 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("");
        }
    }
 }

评论

0赞 yanchenko 12/5/2008
Desktop.getDesktop().browse( new URI(“stackoverflow.com”));对我来说,听起来很像 Java 6。:)非常好!