【问题标题】:How can I give this password field focus?我怎样才能给这个密码字段焦点?
【发布时间】:2011-10-04 12:52:35
【问题描述】:

这可能看起来微不足道,但我不知道如何在此对话框中设置密码框。

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

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

stacktrace(参见 Eng.Fouad 的回答):

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

【问题讨论】:

标签: java swing passwords joptionpane jpasswordfield


【解决方案1】:

查看Dialog Focus 中提出的解决方案。

编辑:

使用 Eng Fouad 建议的方法,我认为代码应该是:

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

编辑2:

“对话焦点”博客条目中的链接有一条评论,其中包含适用于 Linux 的建议。

【讨论】:

  • 我用 AncestorListener 尝试了这个解决方案。不幸的是,根本没有调用回调,因此代码不起作用。怎么了?
  • 我已经在 XP 的 JDK6_7 上测试过了。也许是版本/平台问题?其中一个 cmets 建议使用 HierarchyListener。试试看会发生什么。
  • 对话焦点链接中提供的解决方案对我有用! :)
  • 使用他在这个答案顶部的对话焦点链接,这对我有用。
【解决方案2】:

问题在于 JOptionPane 是完全独立的,并且似乎无法指定哪个 GUI 组件获得初始焦点。一种解决方案是编写您自己的 Dialog 子类 - 这将使您可以准确控制布局并适当地设置焦点。

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

【讨论】:

    【解决方案3】:
    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();             
        }         
    }; 
    

    【讨论】:

    • 必须在窗格的声明中添加“final”,但它仍然不起作用。不过感谢您的帮助,不胜感激:)
    • @MaxMackie 不需要final,只需将其作为类字段,请参阅更新
    • 我仍然无法让第一个解决方案工作,但第二个解决方案给了我一个堆栈跟踪。我会把它添加到我的问题中。
    【解决方案4】:

    这是一个工作解决方案,重点是密码字段和工作按钮

    https://stackoverflow.com/a/21426340/2110961

    【讨论】:

      猜你喜欢
      • 2012-09-02
      • 1970-01-01
      • 2017-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-04
      • 1970-01-01
      相关资源
      最近更新 更多