# HG changeset patch # User rupashka # Date 1227620530 -10800 # Node ID 63e684c4ed2f5ba019657f0c9cb1991f243c0bc5 # Parent bdfe33408ed8a9cbd07f91d31a7f84e80b8dae77 6698013: JFileChooser can no longer navigate non-local file systems. Summary: ShellFolder is used only if possible Reviewed-by: peterz diff -r bdfe33408ed8 -r 63e684c4ed2f src/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java --- a/src/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java Tue Nov 18 15:59:36 2008 +0900 +++ b/src/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java Tue Nov 25 16:42:10 2008 +0300 @@ -1132,7 +1132,7 @@ private void changeDirectory(File dir) { JFileChooser fc = getFileChooser(); // Traverse shortcuts on Windows - if (dir != null && File.separatorChar == '\\' && dir.getPath().endsWith(".lnk")) { + if (dir != null && FilePane.usesShellFolder(fc)) { try { File linkedTo = ShellFolder.getShellFolder(dir).getLinkLocation(); if (linkedTo != null && fc.isTraversable(linkedTo)) { diff -r bdfe33408ed8 -r 63e684c4ed2f src/share/classes/sun/swing/FilePane.java --- a/src/share/classes/sun/swing/FilePane.java Tue Nov 18 15:59:36 2008 +0900 +++ b/src/share/classes/sun/swing/FilePane.java Tue Nov 25 16:42:10 2008 +0300 @@ -1961,6 +1961,16 @@ } } + /** + * Returns true if specified FileChooser should use ShellFolder + */ + public static boolean usesShellFolder(JFileChooser chooser) { + Boolean prop = (Boolean) chooser.getClientProperty("FileChooser.useShellFolder"); + + return prop == null ? chooser.getFileSystemView().equals(FileSystemView.getFileSystemView()) + : prop.booleanValue(); + } + // This interface is used to access methods in the FileChooserUI // that are not public. public interface FileChooserUIAccessor { diff -r bdfe33408ed8 -r 63e684c4ed2f test/javax/swing/JFileChooser/6698013/bug6698013.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/swing/JFileChooser/6698013/bug6698013.html Tue Nov 25 16:42:10 2008 +0300 @@ -0,0 +1,8 @@ + + + +1. Go into 'subdir' folder via double click +2. Return to parent directory +3. Go into 'subdir' folder: select 'subdir' folder and press the 'Open' button + + diff -r bdfe33408ed8 -r 63e684c4ed2f test/javax/swing/JFileChooser/6698013/bug6698013.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/swing/JFileChooser/6698013/bug6698013.java Tue Nov 25 16:42:10 2008 +0300 @@ -0,0 +1,174 @@ +/* @test %W% %E% + @bug 6698013 + @summary JFileChooser can no longer navigate non-local file systems. + @author Pavel Porvatov + @run applet/manual=done bug6698013.html +*/ + +import javax.swing.*; +import javax.swing.filechooser.FileSystemView; +import java.io.File; + +public class bug6698013 extends JApplet { + + final static VirtualFile root = new VirtualFile("testdir", true); + + final static VirtualFile rootFile = new VirtualFile("testdir/test.txt", false); + + final static VirtualFile subdir = new VirtualFile("testdir/subdir", true); + + final static VirtualFile subdirFile = new VirtualFile("testdir/subdir/subtest.txt", false); + + public static void main(String[] args) { + JFileChooser chooser = new JFileChooser(new VirtualFileSystemView()); + chooser.setCurrentDirectory(root); + chooser.showSaveDialog(null); + } + + public void init() { + JFileChooser chooser = new JFileChooser(new VirtualFileSystemView()); + chooser.setCurrentDirectory(root); + chooser.showSaveDialog(null); + } +} + +class VirtualFileSystemView extends FileSystemView { + + public boolean isRoot(File dir) { + return bug6698013.root.equals(dir); + } + + public File createNewFolder(File dir) { + return null; + } + + public File[] getRoots() { + return new File[]{bug6698013.root}; + } + + public boolean isDrive(File dir) { + return false; + } + + public boolean isFloppyDrive(File dir) { + return false; + } + + public File getParentDirectory(File dir) { + if (dir == null) { + return null; + } + + return new VirtualFile(dir.getPath(), true).getParentFile(); + } + + public File[] getFiles(File dir, boolean hide_hidden) { + if (dir.equals(bug6698013.root)) { + return new File[]{bug6698013.rootFile, bug6698013.subdir}; + } + + if (dir.equals(bug6698013.subdir)) { + return new File[]{bug6698013.subdirFile}; + } + + return null; + } + + public File getHomeDirectory() { + return bug6698013.root; + } + + public File getDefaultDirectory() { + return getHomeDirectory(); + } + + public String getSystemDisplayName(File file) { + return file.getName(); + } + + public Boolean isTraversable(File file) { + return Boolean.valueOf(file.isDirectory()); + } +} + +/** + * A Virtual File. Contains a path and a directory flag that + * represents the location of a virtual file to be contained in the + * Virtual FileSystemView. + */ +class VirtualFile extends File { + + private static final long serialVersionUID = 0L; + + private String path; + + private boolean directory; + + public VirtualFile(String path, boolean directory) { + super(path); + this.path = path; + this.directory = directory; + } + + public File getParentFile() { + int index = path.lastIndexOf('/'); + + if (index == -1) { + return null; + } + + return new VirtualFile(path.substring(0, index), true); + } + + public File getCanonicalFile() { + return this; + } + + public String getParent() { + File parent_file = getParentFile(); + + return parent_file == null ? null : parent_file.getPath(); + } + + public String getName() { + int index = path.lastIndexOf('/'); + + return index == -1 ? path : path.substring(index + 1); + } + + public String getPath() { + return path; + } + + public String getAbsolutePath() { + return path; + } + + public String getCanonicalPath() { + return path; + } + + public String toString() { + return path; + } + + public boolean equals(Object obj) { + return obj instanceof VirtualFile && path.equals(obj.toString()); + } + + public int hashCode() { + return path.hashCode(); + } + + public boolean canWrite() { + return true; + } + + public boolean isDirectory() { + return directory; + } + + public boolean exists() { + return true; + } +}