Get Focus for JTextField in JFileChooser in NimbusLookAndFeel

There is a problem, not to mention small or big, after all a problem in the JFileChooser with the NimbusLookAndFeel, my most favorite look and feel in Java. Coming into the question, the problem is that, thee JTextField where the user types in the file name doesn't get focus by default, instead the the combo box on the top gets it as in the below figure.
Solving this problem, isn't that easy. It required quite lengthy code for me (if you can make it short, please let me know by dropping a comment). Here is the code that helps solve the problem.

Solving the focus problem


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();
            }
        });
    }
}
I hope you got the answer, if you enjoy, by the way, you will also enjoy changing the theme in NimbusLookAndFeel using nimbusBase and deleting a file through JFileChooser and also one of my popular posts, creating transparent panels in swing. Feel free to drop a comment, if you have anything to ask or say.

This is a replica of my post in Stackoverflow [I am JavaTechnical!]

No comments: