在JOptionPane.showOptionDialog()中设置组件焦点

ehs*_*n7b 12 java swing focus joptionpane

为了在输入对话框中有自定义按钮标题,我创建了以下代码:

String key = null;
JTextField txtKey = new JTextField();        
int answerKey = JOptionPane.showOptionDialog(this, new Object[] {pleaseEnterTheKey, txtKey}, decryptionKey, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, new Object[] {okCaption, cancelCaption}, okCaption);        
if (answerKey == JOptionPane.OK_OPTION && txtKey.getText() != null) {
  key = txtKey.getText();
}
Run Code Online (Sandbox Code Playgroud)

如何在显示对话框时将焦点(光标)移动到文本字段?

UPDATE

这对我不起作用,我的意思是文本字段没有焦点:操作系统:Fedora - Gnome

public class Test {
  public static void main(String[] args) {
    String key = null;
    JTextField txtKey = new JTextField();
    txtKey.addAncestorListener(new RequestFocusListener());
    int answerKey = JOptionPane.showOptionDialog(null, new Object[]{"Please enter the key:", txtKey}, "Title", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, new Object[]{"OKKK", "CANCELLLL"}, "OKKK");
    if (answerKey == JOptionPane.OK_OPTION && txtKey.getText() != null) {
      key = txtKey.getText();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

cam*_*ckr 14

Dialog Focus显示如何轻松地将焦点设置在模态对话框中的任何组件上.

  • @ ehsun7b,你发布的代码对我有用,所以也许它们在两个系统之间的事件处理上有所不同.您是否添加了任何输出以确保调用事件侦听器?如果您阅读博客,有人建议也可以使用HierarchyListener.试试看看会发生什么.或者另一种选择是将来自AncestorListener的代码包装在SwingUtltities.invokeLater()中.这将把代码添加到EDT的末尾,以便在焦点放在按钮上之后执行. (2认同)

Fra*_* M. 9

    public static String getPassword(String title) {
        JPanel panel = new JPanel();
        final JPasswordField passwordField = new JPasswordField(10);
        panel.add(new JLabel("Password"));
        panel.add(passwordField);
        JOptionPane pane = new JOptionPane(panel, JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION) {
            @Override
            public void selectInitialValue() {
                passwordField.requestFocusInWindow();
            }
        };
        pane.createDialog(null, title).setVisible(true);
        return passwordField.getPassword().length == 0 ? null : new String(passwordField.getPassword());
    }
Run Code Online (Sandbox Code Playgroud)


ehs*_*n7b 5

传递null作为最后一个参数是解决方案.至少它对我有用.

String key = null;
JTextField txtKey = new JTextField();        
int answerKey = JOptionPane.showOptionDialog(this, new Object[] {pleaseEnterTheKey, txtKey}, decryptionKey, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, new Object[] {okCaption, cancelCaption}, null);        
if (answerKey == JOptionPane.OK_OPTION && txtKey.getText() != null) {
  key = txtKey.getText();
}
Run Code Online (Sandbox Code Playgroud)

但即便是这个解决方案也带来了另

聚焦组件和默认组件是不同的.默认组件或默认按钮是按下它的onclick时触发的按钮ENTER KEY.最后一个参数定义了获取焦点的默认组件,并且传递null会带来没有默认组件的问题!我通过这种方式为我的代码解决了它,但我想这不是最佳实践:

String key = null;
    final JTextField txtKey = new JTextField();
    txtKey.addKeyListener(new KeyAdapter() {

      @Override
      public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();
        if (keyCode == 10) { //enter key
          Container parent = txtKey.getParent();              
          while (!(parent instanceof JOptionPane)) {
            parent = parent.getParent();
          }

          JOptionPane pane = (JOptionPane) parent;
          final JPanel pnlBottom = (JPanel) pane.getComponent(pane.getComponentCount() - 1);
          for (int i = 0; i < pnlBottom.getComponents().length; i++) {
            Component component = pnlBottom.getComponents()[i];
            if (component instanceof JButton) {
              final JButton okButton = ((JButton)component);
              if (okButton.getText().equalsIgnoreCase(okCaption)) {
                ActionListener[] actionListeners = okButton.getActionListeners();
                if (actionListeners.length > 0) {
                  actionListeners[0].actionPerformed(null);
                }
              }
            }
          }
        }
      }

    });
Run Code Online (Sandbox Code Playgroud)


mre*_*mre 1

尝试这个

String key = null;
JTextField txtKey = new JTextField();
Object[] foo = {pleaseEnterTheKey, txtKey};      
int answerKey = JOptionPane.showOptionDialog(this, foo, decryptionKey, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, new Object[] {okCaption, cancelCaption}, foo[1]);        
if (answerKey == JOptionPane.OK_OPTION && txtKey.getText() != null) {
  key = txtKey.getText();
}
Run Code Online (Sandbox Code Playgroud)