3

默认情况下,JFileChooserinNimbusLookAndFeel不会显示JTextField用户键入文件路径的位置。JFileChooser中的焦点所有者JComboBox如图所示。

JFileChooser (NimbusLookAndFeel) 的屏幕截图

现在,JTextField当用户打开JFileChooser. 我尝试通过requestFocusInWindow()从递归逻辑中JTextField获取它。JFileChooser这是我完成的完整代码。

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class GetFocusForJTextField extends JFrame
{
JButton jb;
JFileChooser jf;

    public GetFocusForJTextField()
    {
        createAndShowGUI();
    }

    private void createAndShowGUI()
    {
        // For NimbusLookAndFeel, JTextField is not
        // the default focus owner in JFileChooser
        try
        {
            UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
        }catch(Exception e){}

        setTitle("Get Focus for JTextField");
        setLayout(new FlowLayout());
        setSize(400,400);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        jb=new JButton("Open JFileChooser");
        jb.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent ae)
            {
                showDialog();
            }
        });

        jf=new JFileChooser();

        add(jb);
    }

    // Loop to find the JTextField, the first
    // JTextField in JFileChooser
    private void grabFocusForTextField(Component[] c)
    {
        for(Component k:c)
        {
            if(k instanceof JTextField)
            {
                JTextField jt=(JTextField)k;
                jt.requestFocusInWindow();
                break;
            }
            else if(k instanceof JPanel)
            {
                JPanel jp=(JPanel)k;
                grabFocusForTextField(jp.getComponents());
            }
        }
    }

    private void showDialog()
    {
        jf.showOpenDialog(this);
        grabFocusForTextField(jf.getComponents());
    }

    public static void main(String args[])
    {
        SwingUtilities.invokeLater(new Runnable(){
            public void run()
            {
                new GetFocusForJTextField();
            }
        });
    }
}

我仍然无法获得焦点。为什么我没有得到这个。

4

1 回答 1

3

这里的东西是在调用时grabFocusForTextField()无法JTextField显示,因此您无法获得焦点JTextField。要让组件获得焦点,组件必须首先存在、可见且可显示、启用且可聚焦。有关更多信息,请参阅文档中的 Focus 子系统

您必须自己注册才能收听HierarchyListener。要么这可能没有正确完成,要么被选为焦点所有者。只要组件是可显示的,只要的层次结构发生变化,就会触发此事件,此时,是可显示的。JFileChooserHierarchyEventNimbusLookAndFeelJComboBoxJFileChooserJTextField

我已经重写了代码来完成这项工作。

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class GetFocusForJTextField extends JFrame
{
JButton jb;
JFileChooser jf;

    public GetFocusForJTextField()
    {
        createAndShowGUI();
    }

    private void createAndShowGUI()
    {
        // For NimbusLookAndFeel, JTextField is not
        // the default focus owner in JFileChooser
        try
        {
            UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
        }catch(Exception e){}

        setTitle("Get Focus for JTextField");
        setLayout(new FlowLayout());
        setSize(400,400);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        jb=new JButton("Open JFileChooser");
        jb.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent ae)
            {
                showDialog();
            }
        });

        jf=new JFileChooser();

        // Even if you add some other JTextField
        // as accessory to JFileChooser
        jf.setAccessory(new JTextField(20));

        jf.addHierarchyListener(new HierarchyListener(){
            public void hierarchyChanged(HierarchyEvent he)
            {
                grabFocusForTextField(jf.getComponents());
            }
        });     

        add(jb);
    }

    // Loop to find the JTextField, the first
    // JTextField in JFileChooser
    // Even if you setAccessory which contains a JTextField
    // or which is JTextField itself, it will not get focus
    private void grabFocusForTextField(Component[] c)
    {
        for(Component k:c)
        {
            if(k instanceof JTextField)
            {
                JTextField jt=(JTextField)k;
                jt.grabFocus();
                break;
            }
            else if(k instanceof JPanel)
            {
                JPanel jp=(JPanel)k;
                grabFocusForTextField(jp.getComponents());
            }
        }
    }

    private void showDialog()
    {
        jf.showOpenDialog(this);
    }

    public static void main(String args[])
    {
        SwingUtilities.invokeLater(new Runnable(){
            public void run()
            {
                new GetFocusForJTextField();
            }
        });
    }
}

您也可以使用requestFocusInWindow()而不是grabFocus()

于 2013-07-15T10:01:22.140 回答