Есть ли альтернатива JPasswordField?
При наборе пароля вроде
yeast bulk seize is shows pain
каждый может услышать нажатие клавиши пробела, поэтому логично также отобразить пробелы в поле пароля. Так что я хотел бы что-то способное показать
***** **** ***** ** ***** ****
вместо
******************************
Это упростит набор текста и вряд ли снизит безопасность.
ОБНОВИТЬ
Подумайте дважды, прежде чем обновлять комментарий Riduidel. Когда Брюс Шнайер пишет:"Пришло время показывать большинство паролей в виде открытого текста", то отображение небольшой его части также должно быть правильным. Особенно показывая часть, которая может быть захвачена просто слушанием.
2 ответа
Вот вариант, который использует setEchoChar()
чтобы сделать пароль видимым в течение заранее определенного времени: например, три секунды.
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://stackru.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);
}
}
Думал JPasswordField
был просто JTextField
просто переопределяя компонент рендерера, но это не так.
Таким образом, вместо смены рендерера (как это было бы в случае, если JTextField
был такой компонент), вам придется использовать JTextField
с обычаем Document
держа две строки:
- Текст пароля как написано пользователем
- Отображаемый пароль
Вы должны убедиться, что все Document
модифицирующие методы изменяют текст пароля, в то время как все методы рендеринга используют отображаемый.