java - 如何在 JOptionPane 中设置默认输入字段

标签 java joptionpane

我有以下代码:

JTextField uname = new JTextField(defaultUser);
JPasswordField passwd = new JPasswordField();
JTextField serverAddress = new JTextField(defaultServer);
JTextField port = new JTextField(Integer.toString(defaultPort));
final JComponent[] inputs = new JComponent[]{new JLabel("Username"), uname, new JLabel("Password"), passwd, new JLabel("Server Address"), serverAddress, new JLabel("Server Port"), port};


int var = JOptionPane.showConfirmDialog(parent, inputs, "Enter Connection Details", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
if (var != 0) {
    return;
}
....

这将创建一个对话框,提示输入一些详细信息以连接到服务器。我想要的是将密码字段设置为默认选择。也就是说,光标默认就在那里,因此您可以在 Pane 出现后立即开始输入,而不必先选择密码框 - 默认情况下,“确定”按钮具有焦点。

我尝试过 passwd.requestFocusInWindow() 但它不起作用(因为我认为在调用它之前该框必须是可见的)。我还尝试用各种内容覆盖 passwd 的 requestFocus 方法,但它也没有成功(可能是因为它无论如何都没有被调用......)

注意:我知道其他一些 JOptionPane 方法具有默认值参数,但它们在布局输入框方面存在问题,因此对我来说没有什么好处。

有人有什么想法吗?这不会破坏交易,所以如果不能轻松完成,我也不会太沮丧。

干杯

最佳答案

尝试将 ComponentListener 添加到密码字段,当它变得可见时,调用 #requestFocusInWindow

更新: JOptionPane 使 [OK] 按钮默认显示在对话框中,并在显示对话框时将其聚焦。所以解决方案并不是那么明显......我们必须添加一个 HierarchyListener 并等到密码字段添加到对话框中,然后检查对话框的 JRootPane 是否有默认值按钮,如果是的话添加一个 FocusListener,最后当按钮获得永久焦点时将焦点切换到密码字段:

import static javax.swing.JOptionPane.OK_CANCEL_OPTION;
import static javax.swing.JOptionPane.PLAIN_MESSAGE;

import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPasswordField;
import javax.swing.JRootPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class FocusPasswordFieldInOptionPaneDemo implements Runnable
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new FocusPasswordFieldInOptionPaneDemo());
    }

    @Override
    public void run()
    {
        JTextField uname = new JTextField("user");
        JPasswordField passwd = new JPasswordField();
        JTextField serverAddress = new JTextField("server");
        JTextField port = new JTextField(Integer.toString(1337));
        final JComponent[] inputs = new JComponent[] {new JLabel("Username"), uname, new JLabel("Password"), passwd,
                new JLabel("Server Address"), serverAddress, new JLabel("Server Port"), port};

        makeSurePasswordFieldGetsFocus(passwd);

        int answer = JOptionPane.showConfirmDialog(null, inputs, "Enter Connection Details", OK_CANCEL_OPTION, PLAIN_MESSAGE);
        System.out.println(answer);
    }

    /**
     * {@link JOptionPane} makes the [OK] button default in the dialog and makes it focused.
     * <p>
     * So via a couple of listeners we can wait until the button gets permanent focus and then switch focus to the password field.
     */
    private void makeSurePasswordFieldGetsFocus(final JPasswordField passwd)
    {
        passwd.addHierarchyListener(new HierarchyListener()
        {
            HierarchyListener hierarchyListener = this;

            @Override
            public void hierarchyChanged(HierarchyEvent e)
            {
                JRootPane rootPane = SwingUtilities.getRootPane(passwd);
                if (rootPane != null)
                {
                    final JButton okButton = rootPane.getDefaultButton();
                    if (okButton != null)
                    {
                        okButton.addFocusListener(new FocusAdapter()
                        {
                            @Override
                            public void focusGained(FocusEvent e)
                            {
                                if (!e.isTemporary())
                                {
                                    passwd.requestFocusInWindow();
                                    passwd.removeHierarchyListener(hierarchyListener);
                                    okButton.removeFocusListener(this);
                                }
                            }
                        });
                    }
                }
            }
        });
    }
}

这个解决方案有效,但有点hacky...另一种方法是创建一个自定义的“DatabaseConnectionDialog”,类似于@syb0rg的答案。

关于java - 如何在 JOptionPane 中设置默认输入字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14096140/

相关文章:

java - 将用户定义的对象转换为数据帧并写入 RDBMS - 如何维护与数据库的映射?

Java 小程序适用于 appletviewer、Safari 和 Firefox,但不适用于 Chrome

Java JOptionPane.showConfirmDialog 热键

java - 如何不混淆 0 和取消按钮 JoptionPane

java - 如何找到最长的回文(java)

java - 保留数组中的默认值?

java - 在swt中设置要为多行文本显示的行数

java - 如何在Android中运行jar文件中的类 Activity ?

java - JOptionPane 和读取整数 - 初学者 Java

java - 我想在 JOptionPane 中显示 for 循环的输出