【问题标题】:IPhone password field in AWT/SWT?AWT/SWT 中的 iPhone 密码字段?
【发布时间】:2010-11-24 10:32:46
【问题描述】:

我想为我的 eclipse 产品创建一个特殊的密码对话框,它与屏幕键盘一起使用。

如果我可以使用像 iPhone 密码字段这样的组件,那就太好了。在此字段中,添加的字符会显示一秒钟,然后将其转换为“*”字符以隐藏完整的密码。

是否存在 jar/库,这是用 AWT 还是 SWT 实现的?

编辑:

我可以尝试从头开始实现它 (SWT),但为此我必须为密码文本组件创建一个非常特殊且复杂的 KeyListener。我必须捕获 keyReleased 事件并将字符手动设置到字段中。

到目前为止,我无法在网络上找到任何库。 也欢迎提出如何实施的建议

【问题讨论】:

    标签: java iphone passwords swt awt


    【解决方案1】:

    这并不是一个完整的答案,而是一个讨论的开始,我不知道有任何开箱即用的小部件可以做到这一点。

    我的第一个想法是继承 swt Text 小部件并覆盖 setEchoChar 等,但在查看代码后这似乎并不可行,因为这种方法只是一个包装器:

    OS.SendMessage (handle, OS.EM_SETPASSWORDCHAR, echo, 0);
    

    如果有人知道特定于操作系统的低级实现,那可能会有所帮助。

    无论如何,换一种方法。我会避免使用 KeyListener 并在 Text-Widget 上使用 ModifyListener。

    void addModifyListener(ModifyListener listener)
    

    然后您可以构建一个包装器,该包装器使用此侦听器捕获输入的文本,将其附加到本地保存的字符串/字符串缓冲区(或例如 Eclipse Preferencestore)并使用 setText(String s) 将修改后的全文发送到 Text 小部件,用回显字符(例如 *)替换除最后一个字符之外的所有字符。

    myText.setText((s.substring(0, s.length()-1)).replaceAll("[\\s\\S]","*")+s.charAt(s.length()-1));
    

    这有点麻烦,但应该可以。

    不那么直截了当的一点是 1 秒的计时,而不会拖住整个视图...

    【讨论】:

    • 您必须将原始文本存储在某处,并且您必须确保在密码完成后所有内容都显示为“*”。否则总是显示最后一个字符。
    【解决方案2】:

    根据 Jules 所说的,以下代码可以正常工作。 代码又快又快,我希望有一个更线程安全的解决方案。

    originalString = new StringBuffer();
    
    passwordField.addModifyListener(new ModifyListener() {
    
    public void modifyText(ModifyEvent e) {
    
        synchronized (passwordField) {
    
             String s = passwordField.getText();
    
             String newS = s.replaceAll("[\\s\\S]", "*");
             if (newS.equals(s)) {
                 while (originalString.length() > s.length()) {
                     originalString = originalString.deleteCharAt(originalString.length() - 1);
                 }
                 usernameField.setText(originalString.toString());
                 return;
             }
    
            if (originalString.length() < s.length()) {
                originalString.append(s.charAt(s.length() - 1));
            }
    
            try {
                Thread.sleep(500);
            } catch (InterruptedException e1) {
            }
            passwordField.setText(newS);
        }
    
        passwordField.redraw();
    
        passwordField.setSelection(passwordField.getText().length());
        }
    
    });
    

    键事件被缓存,因此您可以添加更多字符,在线程等待时也是如此。 另一个问题是光标处理。设置文本时,光标总是移动到第一个位置。

    我认为当它工作时它非常接近 iphone 解决方案。

    【讨论】:

    • 看起来不错。但有一件事:使用 Thread.sleep() 在概念上是行不通的。侦听器将始终等待 500 毫秒。当再次调用侦听器并且时间还没有到时,您需要找到一种方法来停止等待。我猜你无法避免第二个线程。
    • 您可以根据需要提示任意数量的键。它们是在睡眠完成后添加的。但是你是对的,当一个新角色到来时,睡眠应该包括一个被触发的通知,所以等待停止。
    猜你喜欢
    • 2011-03-02
    • 2012-11-07
    • 1970-01-01
    • 2013-09-10
    • 2016-12-29
    • 2014-08-06
    • 2012-01-27
    • 2015-05-10
    • 2018-04-11
    相关资源
    最近更新 更多