Подтвердить что ты не робот

JOptionPane, чтобы получить пароль

JOptionPane может использоваться для получения строковых входов от пользователя, но в моем случае я хочу отобразить поле пароля в showInputDialog.

То, что мне нужно, - это вводимый пользователем ввод, который должен быть замаскирован, а возвращаемое значение должно быть в char[]. Мне нужно диалоговое окно с сообщением, полем пароля и двумя кнопками. Это можно сделать? Спасибо.

4b9b3361

Ответ 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)