< prev index next >

src/java.desktop/share/classes/javax/swing/filechooser/FileSystemView.java

Print this page

        

@@ -27,21 +27,28 @@
 
 
 import javax.swing.*;
 
 import java.awt.Image;
+import java.beans.BeanProperty;
+import java.beans.JavaBean;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.text.MessageFormat;
 import java.util.List;
 import java.util.ArrayList;
 import java.lang.ref.WeakReference;
 import java.beans.PropertyChangeListener;
 import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeSupport;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Objects;
+import sun.awt.OSInfo;
 
 import sun.awt.shell.*;
 
 /**
  * FileSystemView is JFileChooser's gateway to the

@@ -645,10 +652,96 @@
         }
         return shellFolder.isLink() ? shellFolder.getLinkLocation() : null;
     }
 
     /**
+     * A group of essential folder that are intented to appear in a left pane of 
+     * a file chooser. 
+     */
+    @JavaBean(description = "A group of essential folder that are intented to "
+            + "appear in a left pane of a file chooser. ")
+    public static class EssentialFolderSection {
+        
+        public static final String FOLDERS_PROPERTY = "folders";
+        
+        private final PropertyChangeSupport propertyChangeSupport = 
+                new PropertyChangeSupport(this);
+        
+        private List<File> folders = Collections.emptyList();
+
+        /**
+         * Creates a new {@code EssentialFolderSection} with no folders. 
+         */
+        public EssentialFolderSection() {
+        }
+        
+        /**
+         * Creates a new {@code EssentialFolderSection} with the specified 
+         * folders. 
+         * 
+         * @param folders 
+         */
+        public EssentialFolderSection(File... folders) {
+            setFolders(Arrays.asList(folders));
+        }
+
+        
+        /**
+         * Gets a list of the essential folders in this section. 
+         *
+         * @return the value of folders
+         */
+        @SuppressWarnings("ReturnOfCollectionOrArrayField") // already an unmodifiableList or emptyList
+        public List<File> getFolders() {
+            return folders;
+        }
+
+        /**
+         * Updates the list of the essential folders in this section to the specified list. 
+         * 
+         * @param folders 
+         * @throws NullPointerException if the argument is null
+         */
+        @BeanProperty(description = "The folders that are in ", bound = true, visualUpdate =true)
+        public void setFolders(List<File> folders) {
+            Objects.requireNonNull(folders);
+            folders = Collections.unmodifiableList(new ArrayList<>(folders));
+            
+            List<File> oldFolders = this.folders;
+            this.folders = folders;
+            propertyChangeSupport.firePropertyChange(FOLDERS_PROPERTY, oldFolders, folders);
+        }
+
+        /**
+         * Adds a PropertyChangeListener to the listener list. Currently the 
+         * listener will be fired only when the 
+         * {@link #setFolders(java.util.List) folders} property is changed, 
+         * but in the future more properties will be added. 
+         * @param listener the PropertyChangeListener to be added
+         */
+        public void addPropertyChangeListener(PropertyChangeListener listener) {
+            propertyChangeSupport.addPropertyChangeListener(listener);
+        }
+
+        /** 
+         * Removes a PropertyChangeListener from the listener list. If listener is null, 
+         * or was never added, no exception is thrown and no action is taken.
+         * 
+         * @param listener the PropertyChangeListener to be removed (registered using
+         *                 {@link #addPropertyChangeListener(java.beans.PropertyChangeListener)})
+         */
+        public void removePropertyChangeListener(PropertyChangeListener listener) {
+            propertyChangeSupport.removePropertyChangeListener(listener);
+        }
+
+    }
+    
+    public EssentialFolderSection[] getEssentialFolders() {
+        return FileSystemView.getFileSystemView().getEssentialFolders();
+    }
+    
+    /**
      * Throws {@code FileNotFoundException} if file not found or current thread was interrupted
      */
     ShellFolder getShellFolder(File f) throws FileNotFoundException {
         if (!(f instanceof ShellFolder) && !(f instanceof FileSystemRoot) && isFileSystemRoot(f)) {
             f = createFileSystemRoot(f);

@@ -756,10 +849,17 @@
                 return true;
             }
         }
         return false;
     }
+
+    @Override
+    public EssentialFolderSection[] getEssentialFolders() {
+        return new EssentialFolderSection[]{
+            new EssentialFolderSection(getChooserComboBoxFiles())
+        };
+    }
 }
 
 
 /**
  * FileSystemView that handles some specific windows concepts.

@@ -870,11 +970,50 @@
                 path += "\\";
             } else if (path.charAt(2) != '\\') {
                 path = path.substring(0, 2) + "\\" + path.substring(2);
             }
         }
-        return super.createFileObject(path);
+        return (File) ShellFolder.get("parseDisplayName " + path);
+    }
+
+    private static final String CLSID_NETWORK = "{F02C1A0D-BE21-4350-88B0-7367FC96EF3C}";
+    private static final String CLSID_COMPUTER = "{20d04fe0-3aea-1069-a2d8-08002b30309d}";
+    private static final String CLSID_HOMEGROUP = "{67CA7650-96E6-4FDD-BB43-A8E774F73A57}";
+    private static final String CLSID_FAVORITES = "{323CA680-C24D-4099-B94D-446DD2D7249E}";
+    private static final String CLSID_LIBRARIES = "{031E4825-7B94-4dc3-B131-E946B44C8DD5}";
+    private static final String CLSID_QUICK_ACCESS = "{679f85cb-0220-4080-b29b-5540cc05aab6}";
+    private static final String CLSID_HOMEGROUP_WIN10 = "{B4FB3F98-C1EA-428d-A78A-D1F5659CBA93}";
+    
+    private static final EssentialFolderSection[] ESSENTIAL_FOLDERS = createEssentialFolders();
+    
+    private static EssentialFolderSection[] createEssentialFolders() {
+        List<File> folders = new ArrayList<>();
+        if (OSInfo.getWindowsVersion().compareTo(OSInfo.WINDOWS_7) <= 0) {
+            folders.add((File) ShellFolder.get(CLSID_FAVORITES));
+            folders.add((File) ShellFolder.get(CLSID_LIBRARIES));
+            folders.add((File) ShellFolder.get(CLSID_HOMEGROUP));
+            folders.add((File) ShellFolder.get(CLSID_COMPUTER));
+            folders.add((File) ShellFolder.get(CLSID_NETWORK));
+        } else {
+            folders.add((File) ShellFolder.get(CLSID_QUICK_ACCESS));
+            folders.add((File) ShellFolder.get(CLSID_COMPUTER));
+            folders.add((File) ShellFolder.get(CLSID_NETWORK));
+
+            // for some unknown reason, adding both Quick Access and Home Group 
+            // on Windows 10 results in all folders in the FilePane (!) with 
+            // default icon switched their icon to a green person icon. 
+        }
+
+        return new EssentialFolderSection[]{
+          new EssentialFolderSection(folders.toArray(new File[0]))
+        };
+    }
+    
+    
+    @Override
+    public EssentialFolderSection[] getEssentialFolders() {
+        return Arrays.copyOf(ESSENTIAL_FOLDERS, ESSENTIAL_FOLDERS.length);
     }
 
     @SuppressWarnings("serial") // anonymous class
     protected File createFileSystemRoot(File f) {
         // Problem: Removable drives on Windows return false on f.exists()

@@ -914,6 +1053,13 @@
             }
         }
         return newFolder;
     }
 
+    @Override
+    public EssentialFolderSection[] getEssentialFolders() {
+        return new EssentialFolderSection[]{
+            new EssentialFolderSection(getChooserComboBoxFiles())
+        };
+    }
+
 }
< prev index next >