Java Swing - JDialog 默认焦点

标签 java swing focus jdialog

我找到了 in the Internet这样的信息:

“当 JDialog(或 JFrame)可见时,焦点默认放在第一个可聚焦的组件上。”

让我们考虑这样的代码:

public class MyDialog extends JDialog{
    // Dialog's components:
    private JLabel dialogLabel1 = new JLabel("Hello");
    private JLabel dialogLabel2 = new JLabel("Message");
    private JButton dialogBtn = new JButton("Sample Btn text");

    public MyDialog(JFrame parent, String title, ModalityType modality){
        super(parent, title, modality);
        dialogBtn.setName("Button");    //
        dialogLabel1.setName("Label1"); // - setting names
        dialogLabel2.setName("Label2"); //
        setTitle(title);
        setModalityType(modality);
        setSize(300, 100);
        setLocation(200, 200);
        // adding comps to contentPane
        getContentPane().add(dialogLabel1, BorderLayout.PAGE_START);
        getContentPane().add(dialogBtn, BorderLayout.CENTER);
        getContentPane().add(dialogLabel2, BorderLayout.PAGE_END);
        pack();
    }

    public void showDialog(){
        setVisible(true);
        listComps(rootPane.getComponents());
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    }

    /*
     * Itereates through all subcomps recursively and displays some relevant info
     * OUTPUT FORM:  ComponentName | isFocusable | hasFocus
     */
    private void listComps(Component[] comps){
        if(comps.length == 0) return;  
        for(Component c : comps){       
            JComponent jC = (JComponent)c;
            System.out.println(jC.getName() + " | " + jC.isFocusable() +" | " + jC.hasFocus());
            listComps(jC.getComponents());
        }    
    }

    public static void main(String[] args) {
        final JFrame frame = new JFrame();
        frame.setPreferredSize(new Dimension(300, 400));
        frame.setVisible(true);
        JButton btn = new JButton("Show dialog");
        btn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                    MyDialog dialog = new MyDialog(frame, "Sample title", ModalityType.APPLICATION_MODAL);
                    dialog.showDialog();
            }
        });
        frame.add(btn, BorderLayout.CENTER);
        frame.pack();
    }
}

输出是: 运行:

null.glassPane | true | false
null.layeredPane | true | false
null.contentPane | true | false
Label1 | true | false
Button | true | true
Label2 | true | false

为什么焦点设置到 JButton?它不是第一个可聚焦的组件! 当我删除 JButton 时,焦点未获得任何组件。为什么?默认情况下,所有组合都是可聚焦的...

最佳答案

It is not the first focusable component! When I've removed JButton, focus wasn't gained to any component. Why? All compos are focusable by default.

要回答原因:这是 FocusTraversalPolicy 的决定,尤其是 DefaultFocusTraversalPolicy 中的 accept(..) 最终会回落到虚拟 NullComponentPeer(默认情况下不可聚焦,因为它实际上并不存在 :-)

从您的评论看来,真正的问题可能是“如果 rootPane 没有可聚焦的子项,如何实现 keyBindings”——如果是这样,选项是

  • 使用rootPane的componentInputMap,即WHEN_IN_FOCUSED_WINDOW
  • 强制 rootPane 本身成为可聚焦的(最好只有在没有可聚焦的子级时才这样做)

关于Java Swing - JDialog 默认焦点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17828264/

相关文章:

java - 创建 T 类型的 N 维数组并填充它

java - 如何将ImageIcon的黑色像素更改为白色像素?

java - JComponent 标题边框

delphi - 如何避免对Delphi应用程序的关注?

apache-flex - Flex/AIR,如何将焦点设置在 UI 控件、按钮等上?

java - FTP/数据库连接期间删除文件失败

java - 如何使 JScrollPane 在 JFrame 中居中?

java - 如何在android中设置标记颜色的验证(Google Map API)

java - 无法在服务器套接字文件传输中获取输入流

wpf - 当 DataGrid 接收到键盘焦点时,关注 SelectedItem 的 DataGridCell