Is there a simple way to fill the document of a JPasswordField
without creating a String object that contains the password?
I was trying to create a "change password" dialog which takes in the old password and requires the new one to be entered twice (three password fields), where the old password may be known before hand, depending on how the user configured this (password may have been stored). So instead of requiring the user to enter the existing password each time the associated dialog is shown to her, I wanted to fill it out programmatically.
Note that JPasswordField.setText(String)
and the String
constructor are not an option. I'd like to do this using a char
array.
I've been trying to abuse GapContent
which seems to be used by PlainDocument
, but it doesn't seem to work (the chars are in there but the field is corrupted):
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JFrame;
import javax.swing.JPasswordField;
import javax.swing.text.PlainDocument;
import javax.swing.SwingUtilities;
import javax.swing.text.GapContent;
public class FillJPasswordField extends JFrame {
private JPasswordField pass;
public FillJPasswordField() {
setLayout(new GridBagLayout());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
char[] password = new char[]{'p', 'a', 's', 's', 'w', 'o', 'r', 'd'};
PlainDocument doc = new PlainDocument(new MyGapContent(password));
pass = new JPasswordField(doc, null, 20);
// see if the password is in there
System.out.println(new String(pass.getPassword()));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0d;
gbc.insets = new Insets(10, 5, 10, 5);
add(pass, gbc);
pack();
setLocationRelativeTo(null);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new FillJPasswordField().setVisible(true);
}
});
}
private class MyGapContent extends GapContent {
public MyGapContent() {
super();
}
public MyGapContent(int initialLength) {
super(initialLength);
}
public MyGapContent(char[] content) {
this(content.length);
replace(0, 0, content, content.length);
}
}
}
Hmm.. The following seems to work:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JFrame;
import javax.swing.JPasswordField;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
import javax.swing.text.GapContent;
import javax.swing.text.PlainDocument;
public class FillJPasswordField extends JFrame {
private JPasswordField pass;
public FillJPasswordField() {
setLayout(new GridBagLayout());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
char[] password = new char[]{'p', 'a', 's', 's', 'w', 'o', 'r', 'd'};
MyGapContent content = new MyGapContent();
PlainDocument doc = new PlainDocument(content);
try {
content.insertChars(0, password);
} catch (BadLocationException ex) {
}
pass = new JPasswordField(20);
pass.setDocument(doc);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.anchor = GridBagConstraints.PAGE_START;
gbc.weightx = 1.0d;
gbc.insets = new Insets(10, 5, 10, 5);
add(pass, gbc);
System.out.println(new String(pass.getPassword()));
pack();
setLocationRelativeTo(null);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new FillJPasswordField().setVisible(true);
}
});
}
private class MyGapContent extends GapContent {
public MyGapContent() {
super();
}
public MyGapContent(int initialLength) {
super(initialLength);
}
public void insertChars(int where, char[] chars) throws BadLocationException {
if (where > length() || where < 0) {
throw new BadLocationException("Invalid insert", length());
}
replace(where, 0, chars, chars.length);
}
}
}
Previous code didn't seem to like the fact that I was calling replace
inside the constructor of MyGapContent
. Perhaps it requires operations to be done in some sequence.
来源:https://stackoverflow.com/questions/26975275/fill-a-jpasswordfield-programmatically-without-creating-a-string-object