2012-01-16 13 views
40

JOptionPane có thể được sử dụng để lấy đầu vào chuỗi từ người dùng, nhưng trong trường hợp của tôi, tôi muốn hiển thị trường mật khẩu trong showInputDialog.JOptionPane để lấy mật khẩu

Cách tôi cần là đầu vào do người dùng đưa ra phải được đeo mặt nạ và giá trị trả lại phải nằm trong char[]. Tôi cần một hộp thoại với một tin nhắn, trường mật khẩu và hai nút. Điều đó có thể được thực hiện? Cảm ơn.

Trả lời

60

Có, có thể sử dụng JOptionPane.showOptionDialog(). Một cái gì đó như thế này:

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)); 
} 
+4

JPasswordField (10) không chấp nhận mật khẩu dài hơn 10. Tốt hơn để làm điều này rộng hơn nhiều hoặc sử dụng hàm tạo no-arg như @Adamski bên dưới. Đồng thời, OK nên là tùy chọn mặc định vì nhiều người dùng sẽ thoát khỏi thói quen nhấn Enter sau khi nhập mật khẩu của họ. Nếu Cancel là mặc định thì gõ mật khẩu theo sau là enter sẽ hủy bỏ hộp thoại. – gb96

+0

cái này là tốt nhất, một nhãn với một JPasswordField trong JOptionPane và trong trường hợp của tôi nó chấp nhận mật khẩu dài hơn 10. –

+3

Làm thế nào để bạn cung cấp cho trường mật khẩu tập trung khi hộp thoại xuất hiện? – mjaggard

4

Bạn có thể tạo hộp thoại riêng của mình để mở rộng JDialog và sau đó bạn có thể đặt bất cứ thứ gì bạn muốn vào đó.

32

Điều đơn giản nhất là sử dụng JOptionPane 's showConfirmDialog phương pháp và để vượt qua trong một tham chiếu đến một JPasswordField; ví dụ.

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); 
} 

Sửa

Dưới đây là một ví dụ sử dụng một tùy chỉnh JPanel để hiển thị một thông điệp cùng với JPasswordField. Theo nhận xét gần đây nhất, tôi cũng đã (vội vàng) thêm mã để cho phép JPasswordField lấy tiêu điểm khi hộp thoại được hiển thị lần đầu tiên.

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); 
     } 
    } 
} 
+0

Chỉ là những gì tôi đang tìm kiếm. BTW có cách nào để ** đặt chuỗi tin nhắn/nội dung ** của Hộp thoại đó không? – InamTaj

+0

Cách dễ nhất để tạo JPanel chứa cả JPasswordField cùng với một JLabel chứa văn bản mong muốn. – Adamski

+0

Tôi biết đã nhưng tôi không muốn _open khung khác trong khi ứng dụng đang chạy_. Vì vậy, tôi muốn sử dụng giải pháp của bạn với ** chuỗi tin nhắn **. – InamTaj

3

đối thoại này trông tốt hơn rất nhiều nếu bạn làm

dlg.setVisible(true); 

Nếu không có mà bạn không thể nhìn thấy nó ở tất cả.

Cũng

pPnl.gainedFocus(); 

nên

pPnl.gainedFocus(); 

Ngoài ra nó hoạt động tuyệt vời. Cảm ơn mã. Đã tiết kiệm thời gian cho tôi xoay vòng với Swing.

Ngoài ra, nếu bạn không muốn để lại cuộc đối thoại chạy ở chế độ nền mỗi khi bạn mở nó, bạn sẽ cần phải đóng nó lại bằng một cái gì đó giống như

dlg.dispatchEvent(new WindowEvent(dlg, WindowEvent.WINDOW_CLOSING)); 
dlg.dispose(); // else java VM will wait for dialog to be disposed of (forever)