【问题标题】:How can I requestFocus on component in JOptionPane.showConfirmDialog?如何请求关注 JOptionPane.showConfirmDialog 中的组件?
【发布时间】:2015-12-01 13:52:49
【问题描述】:

使用带有自定义组件 (JPanel) 的 JOptionPane.showConfirmDialog,我喜欢在特定组件 (JPasswordField) 打开时将注意力集中在它上面。如何实现?

代码示例:当对话框打开时JPasswordField pf 应该有焦点...

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;


public class JTestOptionDialog {

  public static void main(String[] args) {  
    JFrame frame = new JFrame("Test showConfirmDialog");
    frame.getContentPane().setLayout(new BorderLayout());
    frame.getContentPane().add(new JPanel());
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
    JLabel label = new JLabel("<html><body>To access insert <b>password</b></body></html>");
    JPasswordField pf = new JPasswordField();
    JPanel panel = new JPanel(new GridBagLayout());
    panel.add(label,new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(2, 2, 2, 2), 0, 0));
    panel.add(pf,new GridBagConstraints(0, 1, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0));
    pf.requestFocus(); //THIS IS WHAT I LIKE TO HAVE FOCOUS WHEN DIALOG OPENS
    int retVal = JOptionPane.showConfirmDialog(frame,panel,"Impostazioni",JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
    System.out.println(retVal);
  }
}

是否有可能以某种方式请求关注我想要的 JPasswordField pf 还是我需要“直接创建和使用 JOptionPane”?

作为我尝试过的注释(看起来合乎逻辑)

pf.addComponentListener(new ComponentAdapter(){
  public void componentShown(ComponentEvent ce){
    pf.requestFocus(); //pf.requestFocusInWindow();
  }
});

但这也没有运气......

【问题讨论】:

标签: java swing focus


【解决方案1】:

我通过添加和删除侦听器找到了一种方法,但我不太喜欢它。我愿意接受更好的解决方案。

pf.addAncestorListener(new AncestorListener() {     

    public void ancestorRemoved(AncestorEvent event) {}

    public void ancestorMoved(AncestorEvent event) {}            

    public void ancestorAdded(final AncestorEvent event) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                event.getComponent().requestFocusInWindow();
                event.getComponent().removeAncestorListener(this);
            }
        });
    }
});

【讨论】:

    【解决方案2】:

    您自己的答案非常接近解决方案。尽管添加/删除很麻烦,但您是对的。这有点整洁。

    试试这个:

    pf.addAncestorListener(new AncestorListener() {
        @Override
        public void ancestorRemoved(AncestorEvent event) {}
    
        @Override
        public void ancestorMoved(AncestorEvent event) {}
    
        @Override
        public void ancestorAdded(AncestorEvent event) {
            event.getComponent().requestFocusInWindow();
        }
    });
    

    并确保在调用JOptionPane.showConfirmDialog()之前输入该代码

    如果您想了解更多信息,我在这里找到了答案Setting component focus in JOptionPane.showOptionDialog()

    【讨论】:

    • 感谢您的回答,我给您一个 +,但选择接受我的,因为它既删除了侦听器(减少内存使用),又在 requestFocus 上实现了 invokeLater...
    • 是的,这很好 :) 我没有意识到有必要将 requestFocus 包装在一个 invokeLater 中,所以我从你那里学到了一些东西 :) +
    猜你喜欢
    • 2017-02-16
    • 2019-04-03
    • 2019-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-06
    • 2023-03-23
    • 2018-06-17
    相关资源
    最近更新 更多