2011-07-13 42 views
5

这可能看起来微不足道,但我无法弄清楚如何在此对话框中输入密码框。我怎样才能给这个密码字段焦点?

import javax.swing.JOptionPane; 
import javax.swing.JPasswordField; 

public class PasswordBox { 
    @SuppressWarnings("unused") 
    public String prompt() { 
     JPasswordField pass = new JPasswordField(10); 
     int action = JOptionPane.showConfirmDialog(null, pass,"Enter Password",JOptionPane.OK_CANCEL_OPTION); 
     return new String(pass.getPassword()); 
    } 
} 

我调用它从其他类这样的:String tmpPASS = new PasswordBox().prompt();

出于某种原因,当对话框出现时,“确定”按钮获得焦点。

堆栈跟踪(见Eng.Fouad的答案):

at javax.swing.JComponent.addNotify(Unknown Source) 
at PasswordBox$1.addNotify(PasswordBox.java:14) 
at java.awt.Container.addNotify(Unknown Source) 
+0

http://stackoverflow.com/questions/6251665/setting-component -focus-in-joptionpane-showoptiondialog/21426340# –

回答

7

查核在Dialog Focus提出的解决方案。

编辑:

使用方法,通过工程福阿德建议我相信代码应该是:

JPasswordField pass = new JPasswordField(10)   
{ 
    public void addNotify()    
    {     
     super.addNotify(); 
     requestFocusInWindow();    
    }   
}; 

EDIT2:

在“对话焦点”博客条目的链接有评论并有一个适用于Linux的建议。

+0

我用AncestorListener试过这个解决方案。不幸的是,回调并没有被调用,所以代码不起作用。怎么了? – AlexR

+0

我在XP上的JDK6_7上测试过它。也许这是一个版本/平台问题?其中一条评论建议使用HierarchyListener。试试看看会发生什么。 – camickr

+0

Dialog Focus链接中提供的解决方案适用于我! :) –

0

问题是,JOptionPane是完全自包含的,似乎没有办法指定哪个GUI组件获得初始焦点。一种解决方案是编写自己的Dialog子类 - 这将使您能够精确控制布局并适当地设置焦点。

您也可以尝试一个javax.swing.SwingWorker。您可以创建其中之一并在显示密码对话框之前启动它。在doInBackground()方法中,休眠一小段时间,在done()方法中使用SwingUtilties.invokeLater()并在该Runnable内发出pass.requestFocusInWindow()。

1
import javax.swing.JOptionPane; 
import javax.swing.JPasswordField; 

public JOptionPane pane; 

public class PasswordBox 
{ 
    @SuppressWarnings("unused") 
    public String prompt() 
    { 
     pane = new JOptionPane(); 
     JPasswordField pass = new JPasswordField(10) 
     { 
      public void addNotify() 
      { 
       pane.addNotify(); 
       requestFocus(); 
      } 
     }; 
     int action = pane.showConfirmDialog(null, pass,"Enter Password",JOptionPane.OK_CANCEL_OPTION); 
     return new String(pass.getPassword()); 
    } 
} 

或这里是另一种方式来做到这一点:

JPanel panel = new JPanel(); 
JPasswordField pass = new JPasswordField(10) 
{ 
    public void addNotify() 
    { 
     panel.addNotify(); 
     requestFocus(); 
    } 
}; 
panel.add(pass); 
JOptionPane pane = new JOptionPane(); 
JButton btnOK = new JButton("OK"); 
JButton btnCancel = new JButton("Cancel"); 
Object[] options = {btnOK, btnCancel}; 
pane.showOptionDialog(null, panel, "Enter the password", JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, null); 

编辑(由camickr,随意删除,如果这是不正确的)。我相信代码应该是:

JPasswordField pass = new JPasswordField(10)   
{ 
    public void addNotify()    
    {     
     super.addNotify(); 
     requestFocusInWindow();    
    }   
}; 
+0

我无法得到这个工作。除非我错过了一些东西。 – n0pe

+0

@MaxMackie查看更新,我希望这可以工作 –

+0

不得不添加“最终”窗格的声明,但它仍然无法正常工作。感谢您的帮助,虽然,这是赞赏:) – n0pe