有没有替代JPasswordField?

时间:2011-03-17 13:31:23

标签: java swing passwords

输入密码短语时,如

yeast bulk seize is shows pain

每个人都可以听到轻敲空格键,因此在密码字段中显示空格似乎也是合乎逻辑的。所以我想要能够展示的东西

***** **** ***** ** ***** ****

而不是

******************************

这会使打字更容易,同时几乎不会降低安全性。


更新

在更新Riduidel的评论之前请三思而后行。当Bruce Schneier writes “是时候以明文显示大多数密码”时,显示其中的一小部分也必须正确。特别是通过聆听显示可能被捕获的部分。

2 个答案:

答案 0 :(得分:4)

认为JPasswordField只是简单地覆盖渲染器组件的JTextField,但似乎并非如此。

因此,您不必更改渲染器(如果JTextField具有此类组件就是这种情况),您必须使用JTextField并使用自定义Document两个字符串:

  1. 用户编写的密码文本
  2. 显示密码
  3. 您必须确保所有Document修改方法都更改密码文本,而所有渲染方法都使用显示的方法。

答案 1 :(得分:3)

以下是使用setEchoChar()使密码在预定义时间内可见的变体:例如3秒。

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPasswordField;
import javax.swing.Timer;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

/** @see http://stackoverflow.com/questions/5339702 */
public class PasswordTest {

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }
        });
    }

    private static void createAndShowGui() {
        JFrame jf = new JFrame("Test Password");
        JPasswordField jpwd = new JPasswordField();
        TimedPasswordListener tpl = new TimedPasswordListener(jpwd);
        jpwd.getDocument().addDocumentListener(tpl);
        jf.add(jpwd);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.setLocationRelativeTo(null);
        jf.pack();
        jf.setVisible(true);
    }
}

class TimedPasswordListener implements DocumentListener, ActionListener {

    private Timer timer = new Timer(3000, this);
    private char echoChar;
    private JPasswordField pwf;

    public TimedPasswordListener(JPasswordField jp) {
        pwf = jp;
        timer.setRepeats(false);
    }

    public void insertUpdate(DocumentEvent e) {
        showText(e);
    }

    public void removeUpdate(DocumentEvent e) {
        showText(e);
    }

    public void changedUpdate(DocumentEvent e) {}

    public void showText(DocumentEvent e) {
        if (0 != pwf.getEchoChar()) {
            echoChar = pwf.getEchoChar();
        }
        pwf.setEchoChar((char) 0);
        timer.restart();
    }

    public void actionPerformed(ActionEvent e) {
        pwf.setEchoChar(echoChar);
    }
}