JOptionPane, чтобы получить пароль
JOptionPane
может использоваться для получения строковых входов от пользователя, но в моем случае я хочу отобразить поле пароля в showInputDialog
.
То, что мне нужно, - это вводимый пользователем ввод, который должен быть замаскирован, а возвращаемое значение должно быть в char[]
. Мне нужно диалоговое окно с сообщением, полем пароля и двумя кнопками. Это можно сделать? Спасибо.
Ответы
Ответ 1
Да, можно использовать JOptionPane.showOptionDialog()
. Что-то вроде этого:
JPanel panel = new JPanel();
JLabel label = new JLabel("Enter a password:");
JPasswordField pass = new JPasswordField(10);
panel.add(label);
panel.add(pass);
String[] options = new String[]{"OK", "Cancel"};
int option = JOptionPane.showOptionDialog(null, panel, "The title",
JOptionPane.NO_OPTION, JOptionPane.PLAIN_MESSAGE,
null, options, options[1]);
if(option == 0) // pressing OK button
{
char[] password = pass.getPassword();
System.out.println("Your password is: " + new String(password));
}
Ответ 2
Самое простое - использовать метод JOptionPane
showConfirmDialog
и передать ссылку на JPasswordField
; например.
JPasswordField pf = new JPasswordField();
int okCxl = JOptionPane.showConfirmDialog(null, pf, "Enter Password", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
if (okCxl == JOptionPane.OK_OPTION) {
String password = new String(pf.getPassword());
System.err.println("You entered: " + password);
}
Edit
Ниже приведен пример с использованием пользовательского JPanel
для отображения сообщения вместе с JPasswordField
. В последнем комментарии я также (поспешно) добавил код, чтобы позволить JPasswordField
получить фокус при первом отображении диалога.
public class PasswordPanel extends JPanel {
private final JPasswordField passwordField = new JPasswordField(12);
private boolean gainedFocusBefore;
/**
* "Hook" method that causes the JPasswordField to request focus the first time this method is called.
*/
void gainedFocus() {
if (!gainedFocusBefore) {
gainedFocusBefore = true;
passwordField.requestFocusInWindow();
}
}
public PasswordPanel() {
super(new FlowLayout());
add(new JLabel("Password: "));
add(passwordField);
}
public char[] getPassword() {
return passwordField.getPassword();
}
public static void main(String[] args) {
PasswordPanel pPnl = new PasswordPanel();
JOptionPane op = new JOptionPane(pPnl, JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
JDialog dlg = op.createDialog("Who Goes There?");
// Wire up FocusListener to ensure JPasswordField is able to request focus when the dialog is first shown.
dlg.addWindowFocusListener(new WindowAdapter() {
@Override
public void windowGainedFocus(WindowEvent e) {
pPnl.gainedFocus();
}
});
if (op.getValue() != null && op.getValue().equals(JOptionPane.OK_OPTION)) {
String password = new String(pPnl.getPassword());
System.err.println("You entered: " + password);
}
}
}
Ответ 3
Вы можете создать собственный диалог, который расширяет JDialog, а затем вы можете поместить в него все, что хотите.
Ответ 4
Этот диалог выглядит намного лучше, если вы делаете
dlg.setVisible(true);
Без этого вы не можете видеть его вообще.
Кроме
pPnl.gainedFocus();
должен быть
pPnl.gainedFocus();
Кроме того, он отлично работает. Спасибо за код. Спасло время, когда я смотрел на Свинг.
Кроме того, если вы не хотите оставлять диалог в фоновом режиме при каждом его открытии, вам нужно закрыть его с помощью
dlg.dispatchEvent(new WindowEvent(dlg, WindowEvent.WINDOW_CLOSING));
dlg.dispose(); // else java VM will wait for dialog to be disposed of (forever)