0

Following my previous two posts here and another one here, the following code opens the regular file browser instead of the expanded one:

public class GuiHandler extends javax.swing.JFrame {
    // data members
    private DataParser xmlParser = new DataParser();
    private File newFile;
    JFileChooser jfc = new JFileChooser();

    // more code 

    public void launchFileChooser() {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch(Exception e) {
                    e.printStackTrace();
                }
                jfc.setFileSelectionMode(JFileChooser.FILES_ONLY);
                jfc.setAcceptAllFileFilterUsed(false);
                if (jfc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION)
                    newFile = jfc.getSelectedFile();
            }
        });
    }

    // more code 

    private void XMLfilesBrowserActionPerformed(java.awt.event.ActionEvent evt) {       
        launchFileChooser();
        xmlParser.getNodeListFromFile(newFile);
        // here the code has the below problems 

Problems:

  1. The code opens a regular file browser when I hit a button to open XML file; it still allows me to pick a file.
  2. It throws an exception:
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: File cannot be null
    at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:198)

Why does it open the regular browser if jfc is a data member, and when it's a local variable, the expanded one opens?

Community
  • 1
  • 1
JAN
  • 21,236
  • 66
  • 181
  • 318
  • What happens if the user does not select a file in the dialog? `newFile` is only initialized if `jfc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION`. – Gabriel Negut Jun 06 '12 at 05:15
  • @GabrielNegut but that's still doesn't explain why the expanded file-browser doesn't open ... – JAN Jun 06 '12 at 05:20
  • I tried using the `JFileChooser` both as a local variable and a class member and it looks exactly the same to me... – Gabriel Negut Jun 06 '12 at 05:33
  • @GabrielNegut: Windows platform . thanks . – JAN Jun 06 '12 at 05:39
  • 2
    If you get the Metal L&F when you use the chooser as a class variable, it's because you instantiate it before you set the system L&F. – Gabriel Negut Jun 06 '12 at 06:05

2 Answers2

2

Concerning the regular versus expanded file chooser, make sure to call UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); before calling new JFileChooser();. Actually, unless you allow users to change the look and feel (L&F) during application execution, set the L&F close to the beginning of application execution, like in the main method, before creating any Swing components. From my experience, not doing so can cause some odd UI behavior.

When you have JFileChooser as a local variable in launchFileChooser, UIManager.setLookAndFeel is called before new JFileChooser. When JFileChooser is a class member variable (a.k.a. data member), UIManager.setLookAndFeel is called after new JFileChooser; in the latter case, the JFileChooser is created when an instance of GuiHandler is instantiated.


Concerning the IllegalArgumentException use SwingUtilities.invokeAndWait in launchFileChooser instead of SwingUtilities.invokeLater. Better yet, if you're sure launchFileChooser will always occur on the event dispatch thread, there's no need to call either SwingUtilities.invokeAndWait or SwingUtilities.invokeLater.


You also may want to use a file filter:

jfc.setFileFilter(new FileNameExtensionFilter("XML files (*.xml)", "xml"));

The following is an SSCE that demonstrates the concepts discussed above:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.filechooser.FileNameExtensionFilter;

public class GuiHandler extends JFrame {
    public static void main(String[] args) throws Exception {
        // call UIManager.setLookAndFeel early in application execution
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        JFrame frame = new GuiHandler();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    private final JFileChooser jfc;

    public GuiHandler() {
        this.jfc = new JFileChooser();
        this.jfc.setFileSelectionMode(JFileChooser.FILES_ONLY);
        this.jfc.setFileFilter(new FileNameExtensionFilter("XML files (*.xml)", "xml"));

        final JButton button = new JButton("Open XML file");
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                xmlFilesBrowserActionPerformed();
            }
        });
        add(button);

        pack();
    }

    protected void xmlFilesBrowserActionPerformed() {
        final File xmlFile = getXmlFile();
        if (xmlFile != null) {
            System.out.println(xmlFile); // process XML file
        }
    }

    private File getXmlFile() {
        // At this point we should be on the event dispatch thread,
        // so there is no need to call SwingUtilities.invokeLater
        // or SwingUtilities.invokeAndWait.
        if (this.jfc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
            return this.jfc.getSelectedFile();
        }
        return null;
    }
}
creemama
  • 6,559
  • 3
  • 21
  • 26
  • Thanks a lot , my friend, I've learned a lot from your example . – JAN Jun 06 '12 at 07:03
  • BTW , is it me or if the I hit `open XML` and then change my mind and hit `cancel` , then the exception comes back to life ... ? – JAN Jun 06 '12 at 07:08
  • @ron `jfc.getSelectedFile()` returns `null` on a cancel. Make sure to put `xmlParser.getNodeListFromFile(newFile);` inside an if statement, `if (newFile != null) { xmlParser.getNodeListFromFile(newFile); }`, to prevent the `IllegalArgumentException`. – creemama Jun 06 '12 at 07:19
0

I'm not exactly sure what you mean by 'expanded one' but I assume you are referring to the file filter. In absence of any file filter, I'm guessing it's defaulting to showing all files. Try adding the following code before opening the dialog.

jfc.setFileFilter(new javax.swing.filechooser.FileFilter(){
    public boolean accept(File f){
        return  f.isDirectory() || f.getName().toLowerCase().endsWith(".xml");
    }
    public String getDescription(){
        return "XML File";
    }
})
user845279
  • 2,794
  • 1
  • 20
  • 38
  • No ,I didn't mean to the file filter . I meant that this link shows what I don't want :http://www.java2s.com/Code/Java/Swing-JFC/DemonstrationofFiledialogboxes.htm , and this link shows what I do want http://www.java2s.com/Code/Java/SWT-JFace-Eclipse/FileDialogExample.htm . And I'm keep getting the `first` one instead of the `second` . – JAN Jun 06 '12 at 05:58
  • 1
    @ron There is a lot of stuff on those pages, exactly are you talking about? Are you talking about the lookAndFeel? Your question makes absolutely no reference to that. – user845279 Jun 06 '12 at 06:39
  • I meant to the picture of each `url` on the first page .Both sites show a picture of a file browser . What I'm keep getting every time is the picture here : http://www.java2s.com/Code/Java/Swing-JFC/DemonstrationofFiledialogboxes.htm . But I don't want that kind of file browser , I need this one , the one in the first page :http://www.java2s.com/Code/Java/SWT-JFace-Eclipse/FileDialogExample.htm . Sorry if I mislead you . – JAN Jun 06 '12 at 06:44
  • 1
    Ok, so you are referring to the `LookAndFeel`, please mention that and you'll get much better answers. Anyway @creemama has a good answer for you. You need to set the look and feel before the Frame is initialized. Do you still have the null issue? – user845279 Jun 06 '12 at 06:46
  • I've edited the entire code , took some time but it works - so first big thanks to the both of you .Second : when I hit the `open XML file` and choose a file , the code runs perfectly , but when I hit the button and change my mind and hit `cancel` then I get `Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: File cannot be null` , that's still won't let go . Any ideas how to take care of this ? – JAN Jun 06 '12 at 07:07
  • 1
    @ron I'm not sure what your new code looks like but the best thing to do is to check `xmlFile != null`, before you read the file. This is also in the accepted answer. – user845279 Jun 06 '12 at 07:16