Windows look and feel for JFileChooser

chama picture chama · Feb 17, 2010 · Viewed 31.4k times · Source

I'm trying to generate a JFileChooser that has the Windows look-and-feel. I couldn't find a method to change it, so I created a base class that extends JFileChooser that changes the UI with the following code:

public FileChooser(){
  this(null);
}
public FileChooser(String path){
   super(path);
   try {
      UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");

    } catch (Exception e) { System.err.println("Error: " + e.getMessage()); }

Then, in another class, I call

FileChooser chooser = new FileChooser(fileName);
int val = chooser.showOpenDialog(null);

but the dialog box that comes up has the Java look and feel. Any thoughts on how to change this? Is there a method of the JFileChooser class that I can use instead of this extended class?

Thank you!

Answer

Riquochet picture Riquochet · Dec 3, 2010

I know you can set the look and feel for the whole application, but what do you do if you like the cross platform look and feel but want the System Look and Feel for the JFileChoosers. Especially since the cross platform doesn't even have the right file icons (and looks completely cheesy.)

Here is what I did. It is definitely a hack...

public class JSystemFileChooser extends JFileChooser{
   public void updateUI(){
      LookAndFeel old = UIManager.getLookAndFeel();
      try {
         UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
      } 
      catch (Throwable ex) {
         old = null;
      } 

      super.updateUI();

      if(old != null){
         FilePane filePane = findFilePane(this);
         filePane.setViewType(FilePane.VIEWTYPE_DETAILS);
         filePane.setViewType(FilePane.VIEWTYPE_LIST);

         Color background = UIManager.getColor("Label.background");
         setBackground(background);
         setOpaque(true);

         try {
            UIManager.setLookAndFeel(old);
         } 
         catch (UnsupportedLookAndFeelException ignored) {} // shouldn't get here
      }
   }



   private static FilePane findFilePane(Container parent){
      for(Component comp: parent.getComponents()){
         if(FilePane.class.isInstance(comp)){
            return (FilePane)comp;
         }
         if(comp instanceof Container){
            Container cont = (Container)comp;
            if(cont.getComponentCount() > 0){
               FilePane found = findFilePane(cont);
               if (found != null) {
                  return found;
               }
            }
         }
      }

      return null;
   }
}