12

入力ダイアログにカスタム ボタン キャプションを表示するために、次のコードを作成しました。

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

ダイアログが表示されているときにフォーカス(カーソル) をテキスト フィールドに移動するにはどうすればよいですか?

アップデート

これは私にはうまくいきません。テキストフィールドにフォーカスがないことを意味します: OS: 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();
    }
  }
}
4

8 に答える 8

14

ダイアログ フォーカスは、モーダル ダイアログ内の任意のコンポーネントにフォーカスを簡単に設定する方法を示しています。

于 2011-06-06T14:55:25.220 に答える
12
    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());
    }
于 2014-01-29T08:59:53.933 に答える
6

最後の引数として 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();
}

しかし、この解決策でも別の問題が発生します。

フォーカスされたコンポーネントとデフォルトのコンポーネントは異なります。デフォルト コンポーネントまたはデフォルト ボタンは、 を押すと 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);
                }
              }
            }
          }
        }
      }

    });
于 2011-06-06T13:20:20.357 に答える
4

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5018574での議論に従った後、LinuxでRequestFocusListener()が機能しないという同じ問題が発生しました。今のところ、invokeLaterを追加すると修正されることがわかりました。 ..

public class RequestFocusListener implements AncestorListener
{
public void ancestorAdded(final AncestorEvent e)
{
    final AncestorListener al= this;   
    SwingUtilities.invokeLater(new Runnable(){

        @Override
        public void run() {
            JComponent component = (JComponent)e.getComponent();
            component.requestFocusInWindow();
            component.removeAncestorListener( al );
        }
    });
}

public void ancestorMoved(AncestorEvent e) {}
public void ancestorRemoved(AncestorEvent e) {}
}
于 2011-07-14T06:34:27.290 に答える
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();
}
于 2011-06-06T12:44:59.390 に答える