How to Use Password Fields(密码框的使用)
JPasswordField — JTextField类的子类,提供了专门的文本输入框作为密码的入口。出于安全的考虑,密码框并不会显示用户所输入的内容。相反,密码框显示的却是和输入不同的字符,例如’*’。作为另外一个安全的机制,密码框是以字符数组来存储内容,而不是字符串。像普通的文本框一样,当用户想要结束输入时,例如按下回车键,密码框会发出一个action类型的事件。
下图是一个打开一个小窗口,并且提示用户输入密码的示例程序的截图:
源程序如下:
import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.Arrays; public class PasswordDemo extends JPanel implements ActionListener { private static String OK = "ok"; private static String HELP = "help"; private JFrame controllingFrame; // 模态对话框所“挡住”的窗口 private JPasswordField passwordField; // 密码框 public PasswordDemo(JFrame frame) { controllingFrame = frame; // 创建密码框及设置 passwordField = new JPasswordField(10); passwordField.setActionCommand(OK); passwordField.addActionListener(this); JLabel label = new JLabel("Enter the password: "); label.setLabelFor(passwordField); JComponent buttonPane = createButtonPanel(); // 放置组件 JPanel textPane = new JPanel(new FlowLayout(FlowLayout.TRAILING)); textPane.add(label); textPane.add(passwordField); add(textPane); add(buttonPane); } protected JComponent createButtonPanel() { JPanel p = new JPanel(new GridLayout(0, 1)); JButton okButton = new JButton("OK"); JButton helpButton = new JButton("Help"); okButton.setActionCommand(OK); helpButton.setActionCommand(HELP); okButton.addActionListener(this); helpButton.addActionListener(this); p.add(okButton); p.add(helpButton); return p; } public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); // 处理输入的密码 if (OK.equals(cmd)) { char[] input = passwordField.getPassword(); if (isPasswordCorrect(input)) { JOptionPane.showMessageDialog(controllingFrame, "Success! You typed the right password."); } else { Toolkit.getDefaultToolkit().beep(); // 发出声音以警示 JOptionPane.showMessageDialog(controllingFrame, "Invalid password. Try again.", "Error Message", JOptionPane.ERROR_MESSAGE); } // 将刚刚输入的密码清空,出于安全考虑 Arrays.fill(input, '0'); // 全部选中密码框中内容,并使其获得焦点 passwordField.selectAll(); resetFocus(); } else { // 显示帮助对话框 JOptionPane.showMessageDialog(controllingFrame, "You can get the password by searching this example's/n" + "source code for the string /"correctPassword/"./n" + "Or look at the section How to Use Password Fields in/n" + "the components section of The Java Tutorial."); } } // 判断输入的密码是否正确 // 当要从此方法中返回时,你应该将传入的输入数组清空 // 此例正确的密码为:bugaboo private static boolean isPasswordCorrect(char[] input) { boolean isCorrect = true; char[] correctPassword = {'b', 'u', 'g', 'a', 'b', 'o', 'o'}; if (input.length != correctPassword.length) { isCorrect = false; } else { isCorrect = Arrays.equals(input, correctPassword); } // 清空正确的密码数组 Arrays.fill(correctPassword, '0'); return isCorrect; } // 获取焦点的方法必须在事件派发线程中调用 protected void resetFocus() { passwordField.requestFocusInWindow(); } private static void createAndShowGUI() { // 创建并设置窗口的默认退出动作 JFrame frame = new JFrame("PasswordDemo"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 创建并设置内容面板 final PasswordDemo newContentPane = new PasswordDemo(frame); newContentPane.setOpaque(true); // 内容面板必须是不透明的 frame.setContentPane(newContentPane); // 不论窗口什么时候被赋予了焦点,都将此焦点发送给正确的组件 // (这里是密码框) frame.addWindowListener(new WindowAdapter() { public void windowActivated(WindowEvent e) { newContentPane.resetFocus(); } }); frame.pack(); frame.setVisible(true); } public static void main(String[] args) { // 为事件派发线程分配一个任务 // 创建并显示应用程序的UI SwingUtilities.invokeLater(new Runnable() { public void run() { UIManager.put("swing.boldMetal", Boolean.FALSE); createAndShowGUI(); } }); } }
其中创建并设置密码框的代码如下:
passwordField = new PasswordField(10);
passwordField.setActionCommand(OK);
passwordField.addActionListener(this);
传给JPasswordField类的构造方法的参数指示了密码输入框的预设大小,此例是10列宽。默认情况下,每输入一个字符,密码框就显示一个点号。假如你想改变回显的字符,可以调用setEchoChar方法。上面的代码中然后为密码框增加了一个事件监听器,用以检测用户输入的内容,具体见上面的actionPerformed方法。
安全提示:
尽管JPasswordField类继承了getText方法,但你应该用getPassword方法替代它。不仅仅是getText方法不够安全,而且更近一步说,它可能会显示当前密码框中的可视字符串(例如:”******”)而不是真正键入的字符串。
为了更进一步增强安全性,一旦你不再使用从getPassword方法返回的字符数组,你应该将其没一个元素都设置为0。
一个使用密码框的程序通常会在结束任何需要密码的操作之前都会更新密码。这个程序调用了一个私有方法,isPasswordCorrect,用来将从getPassword方法返回的值和存储在字符数组中的值相比对。具体代码如下:
private static boolean isPasswordCorrect(char[] input) {
boolean isCorrect = true;
char[] correctPassword = {'b', 'u', 'g', 'a', 'b', 'o', 'o'};
if (input.length != correctPassword.length) {
isCorrect = false;
} else {
isCorrect = Arrays.equals(input, correctPassword);
}
// 清空正确的密码数组
Arrays.fill(correctPassword, '0');
return isCorrect;
}
总结:相对来说密码框的使用较为容易,但要考虑很多安全性的问题,要注意。