【问题标题】:The correct way of waiting for strings to become equal等待字符串相等的正确方法
【发布时间】:2010-09-24 22:40:02
【问题描述】:

在 Swing 应用程序中,只有在用户输入正确答案后才能继续执行方法。正确答案存储在String 中,用户答案由听众设置为另一个String。所以,代码是

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

这种方法一切正常还是你会以某种方式重构它?它不会对CPU施加额外的惩罚吗? 这里有点similar question

【问题讨论】:

    标签: java while-loop cpu-cycles


    【解决方案1】:

    正如其他人所建议的,您需要为按钮分配一个侦听器,该侦听器将在按下按钮时被调用。

    这是一个不完整的示例,说明如何使用 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。 (我只是使用了一个匿名内部类来保持示例简短。)

    有关更多信息,您可能需要查看How to Write an Action Listener from The Java Tutorials

    此外,有关事件如何在 Java 中工作的一般信息,Java 教程中的 Lesson: Writing Event Listeners 可能会很有用。

    编辑:if 语句中的表达式从textField.getText().equals("some text") 更改为"some text".equals(textField.getText()),以防止NullPointerException 如果textFieldnull,根据先生的建议。 Shiny and New 的评论。

    【讨论】:

    • 如果 getText() 返回 null,我建议执行 "some text".equals(textField.getText()) 以防止出现空指针异常。将常量与变量进行比较时要养成的好习惯。
    • 啊,谢谢你指出这一点!我已编辑答案以考虑您的建议。
    • 我肯定会使用 ActionListeners,只是这种情况超出了琐碎的 ActionListeners(我认为)。更多的双向 ActionListener ;) 具有提供 UI 组件的疯狂递归方法。不过感谢您的回复。在我重构的路上。
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        【解决方案4】:

        是的,正如每个人在这里所说的那样。

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

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

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

        这段代码除了在一个完整的准备运行示例中展示这个概念是如何应用的之外没有其他价值。

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

        【讨论】:

        • Desktop.getDesktop().browse(new URI("stackoverflow.com")); 听起来 Java 6 对我来说太棒了。:) 太棒了!
        【解决方案5】:

        如果您的字符串以 GUI 速率来自人类用户,那么优化性能就没有什么意义了。人类每秒最多只能输入 1 到 3 个字符串,而这对机器来说毫无意义。

        在这种特殊情况下,您需要做一些事情来获得输入进行测试,我建议使用@987654321@ 循环。

        【讨论】:

          猜你喜欢
          • 2015-03-02
          • 2015-11-30
          • 2014-11-15
          • 2018-09-01
          • 2017-09-09
          • 2020-08-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多