提交 03078b2f 编写于 作者: R rupashka

6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser,...

6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
Summary: now sun.awt.shell.ShellFolder#sort uses system sorting instead of alphabetical
Reviewed-by: loneid, peterz
上级 6baf66b2
......@@ -196,7 +196,7 @@ public class BasicDirectoryModel extends AbstractListModel implements PropertyCh
}
protected void sort(Vector<? extends File> v){
ShellFolder.sortFiles(v);
ShellFolder.sort(v);
}
// Obsolete - not used
......
......@@ -25,6 +25,7 @@
package sun.awt.shell;
import javax.swing.*;
import java.awt.Image;
import java.awt.Toolkit;
import java.io.*;
......@@ -37,6 +38,10 @@ import java.util.*;
*/
public abstract class ShellFolder extends File {
private static final String COLUMN_NAME = "FileChooser.fileNameHeaderText";
private static final String COLUMN_SIZE = "FileChooser.fileSizeHeaderText";
private static final String COLUMN_DATE = "FileChooser.fileDateHeaderText";
protected ShellFolder parent;
/**
......@@ -268,8 +273,45 @@ public abstract class ShellFolder extends File {
// Override File methods
public static void sortFiles(List files) {
shellFolderManager.sortFiles(files);
public static void sort(List<? extends File> files) {
if (files == null || files.size() <= 1) {
return;
}
// Check that we can use the ShellFolder.sortChildren() method:
// 1. All files have the same non-null parent
// 2. All files is ShellFolders
File commonParent = null;
for (File file : files) {
File parent = file.getParentFile();
if (parent == null || !(file instanceof ShellFolder)) {
commonParent = null;
break;
}
if (commonParent == null) {
commonParent = parent;
} else {
if (commonParent != parent && !commonParent.equals(parent)) {
commonParent = null;
break;
}
}
}
if (commonParent instanceof ShellFolder) {
((ShellFolder) commonParent).sortChildren(files);
} else {
Collections.sort(files, FILE_COMPARATOR);
}
}
public void sortChildren(List<? extends File> files) {
Collections.sort(files, FILE_COMPARATOR);
}
public boolean isAbsolute() {
......@@ -356,18 +398,131 @@ public abstract class ShellFolder extends File {
}
public static ShellFolderColumnInfo[] getFolderColumns(File dir) {
return shellFolderManager.getFolderColumns(dir);
}
ShellFolderColumnInfo[] columns = null;
public static Object getFolderColumnValue(File file, int column) {
return shellFolderManager.getFolderColumnValue(file, column);
if (dir instanceof ShellFolder) {
columns = ((ShellFolder) dir).getFolderColumns();
}
if (columns == null) {
columns = new ShellFolderColumnInfo[]{
new ShellFolderColumnInfo(COLUMN_NAME, 150,
SwingConstants.LEADING, true, null,
FILE_COMPARATOR),
new ShellFolderColumnInfo(COLUMN_SIZE, 75,
SwingConstants.RIGHT, true, null,
DEFAULT_COMPARATOR, true),
new ShellFolderColumnInfo(COLUMN_DATE, 130,
SwingConstants.LEADING, true, null,
DEFAULT_COMPARATOR, true)
};
}
return columns;
}
public ShellFolderColumnInfo[] getFolderColumns() {
return null;
}
public static Object getFolderColumnValue(File file, int column) {
if (file instanceof ShellFolder) {
Object value = ((ShellFolder)file).getFolderColumnValue(column);
if (value != null) {
return value;
}
}
if (file == null || !file.exists()) {
return null;
}
switch (column) {
case 0:
// By default, file name will be rendered using getSystemDisplayName()
return file;
case 1: // size
return file.isDirectory() ? null : Long.valueOf(file.length());
case 2: // date
if (isFileSystemRoot(file)) {
return null;
}
long time = file.lastModified();
return (time == 0L) ? null : new Date(time);
default:
return null;
}
}
public Object getFolderColumnValue(int column) {
return null;
}
/**
* Provides a default comparator for the default column set
*/
private static final Comparator DEFAULT_COMPARATOR = new Comparator() {
public int compare(Object o1, Object o2) {
int gt;
if (o1 == null && o2 == null) {
gt = 0;
} else if (o1 != null && o2 == null) {
gt = 1;
} else if (o1 == null && o2 != null) {
gt = -1;
} else if (o1 instanceof Comparable) {
gt = ((Comparable) o1).compareTo(o2);
} else {
gt = 0;
}
return gt;
}
};
private static final Comparator<File> FILE_COMPARATOR = new Comparator<File>() {
public int compare(File f1, File f2) {
ShellFolder sf1 = null;
ShellFolder sf2 = null;
if (f1 instanceof ShellFolder) {
sf1 = (ShellFolder) f1;
if (sf1.isFileSystem()) {
sf1 = null;
}
}
if (f2 instanceof ShellFolder) {
sf2 = (ShellFolder) f2;
if (sf2.isFileSystem()) {
sf2 = null;
}
}
if (sf1 != null && sf2 != null) {
return sf1.compareTo(sf2);
} else if (sf1 != null) {
// Non-file shellfolders sort before files
return -1;
} else if (sf2 != null) {
return 1;
} else {
String name1 = f1.getName();
String name2 = f2.getName();
// First ignore case when comparing
int diff = name1.compareToIgnoreCase(name2);
if (diff != 0) {
return diff;
} else {
// May differ in case (e.g. "mail" vs. "Mail")
// We need this test for consistent sorting
return name1.compareTo(name2);
}
}
}
};
}
......@@ -27,8 +27,6 @@ package sun.awt.shell;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;
import javax.swing.SwingConstants;
/**
* @author Michael Martak
......@@ -36,10 +34,6 @@ import javax.swing.SwingConstants;
*/
class ShellFolderManager {
private static final String COLUMN_NAME = "FileChooser.fileNameHeaderText";
private static final String COLUMN_SIZE = "FileChooser.fileSizeHeaderText";
private static final String COLUMN_DATE = "FileChooser.fileDateHeaderText";
/**
* Create a shell folder from a file.
* Override to return machine-dependent behavior.
......@@ -107,142 +101,4 @@ class ShellFolderManager {
}
return (dir.getParentFile() == null);
}
public void sortFiles(List files) {
Collections.sort(files, fileComparator);
}
private Comparator fileComparator = new Comparator() {
public int compare(Object a, Object b) {
return compare((File)a, (File)b);
}
public int compare(File f1, File f2) {
ShellFolder sf1 = null;
ShellFolder sf2 = null;
if (f1 instanceof ShellFolder) {
sf1 = (ShellFolder)f1;
if (sf1.isFileSystem()) {
sf1 = null;
}
}
if (f2 instanceof ShellFolder) {
sf2 = (ShellFolder)f2;
if (sf2.isFileSystem()) {
sf2 = null;
}
}
if (sf1 != null && sf2 != null) {
return sf1.compareTo(sf2);
} else if (sf1 != null) {
return -1; // Non-file shellfolders sort before files
} else if (sf2 != null) {
return 1;
} else {
String name1 = f1.getName();
String name2 = f2.getName();
// First ignore case when comparing
int diff = name1.toLowerCase().compareTo(name2.toLowerCase());
if (diff != 0) {
return diff;
} else {
// May differ in case (e.g. "mail" vs. "Mail")
// We need this test for consistent sorting
return name1.compareTo(name2);
}
}
}
};
public ShellFolderColumnInfo[] getFolderColumns(File dir) {
ShellFolderColumnInfo[] columns = null;
if (dir instanceof ShellFolder) {
columns = ((ShellFolder)dir).getFolderColumns();
}
if (columns == null) {
columns = new ShellFolderColumnInfo[]{
new ShellFolderColumnInfo(COLUMN_NAME, 150,
SwingConstants.LEADING, true, null,
fileComparator),
new ShellFolderColumnInfo(COLUMN_SIZE, 75,
SwingConstants.RIGHT, true, null,
ComparableComparator.getInstance(), true),
new ShellFolderColumnInfo(COLUMN_DATE, 130,
SwingConstants.LEADING, true, null,
ComparableComparator.getInstance(), true)
};
}
return columns;
}
public Object getFolderColumnValue(File file, int column) {
if (file instanceof ShellFolder) {
Object value = ((ShellFolder)file).getFolderColumnValue(column);
if (value != null) {
return value;
}
}
if (file == null || !file.exists()) {
return null;
}
switch (column) {
case 0:
// By default, file name will be rendered using getSystemDisplayName()
return file;
case 1: // size
return file.isDirectory() ? null : new Long(file.length());
case 2: // date
if (isFileSystemRoot(file)) {
return null;
}
long time = file.lastModified();
return (time == 0L) ? null : new Date(time);
default:
return null;
}
}
/**
* This class provides a default comparator for the default column set
*/
private static class ComparableComparator implements Comparator {
private static Comparator instance;
public static Comparator getInstance() {
if (instance == null) {
instance = new ComparableComparator();
}
return instance;
}
public int compare(Object o1, Object o2) {
int gt;
if (o1 == null && o2 == null) {
gt = 0;
} else if (o1 != null && o2 == null) {
gt = 1;
} else if (o1 == null && o2 != null) {
gt = -1;
} else if (o1 instanceof Comparable) {
gt = ((Comparable) o1).compareTo(o2);
} else {
gt = 0;
}
return gt;
}
}
}
......@@ -306,7 +306,7 @@ final class Win32ShellFolder2 extends ShellFolder {
* <code>java.io.File</code> instead. If not, then the object depends
* on native PIDL state and should not be serialized.
*
* @returns a <code>java.io.File</code> replacement object. If the folder
* @return a <code>java.io.File</code> replacement object. If the folder
* is a not a normal directory, then returns the first non-removable
* drive (normally "C:\").
*/
......@@ -605,10 +605,10 @@ final class Win32ShellFolder2 extends ShellFolder {
// parent so we have an IShellFolder to query.
long pIShellFolder = getIShellFolder();
// Now we can enumerate the objects in this folder.
ArrayList list = new ArrayList();
ArrayList<Win32ShellFolder2> list = new ArrayList<Win32ShellFolder2>();
long pEnumObjects = getEnumObjects(pIShellFolder, includeHiddenFiles);
if (pEnumObjects != 0) {
long childPIDL = 0;
long childPIDL;
int testedAttrs = ATTRIB_FILESYSTEM | ATTRIB_FILESYSANCESTOR;
do {
if (Thread.currentThread().isInterrupted()) {
......@@ -635,7 +635,7 @@ final class Win32ShellFolder2 extends ShellFolder {
} while (childPIDL != 0);
releaseEnumObjects(pEnumObjects);
}
return (ShellFolder[])list.toArray(new ShellFolder[list.size()]);
return list.toArray(new ShellFolder[list.size()]);
}
......@@ -648,7 +648,7 @@ final class Win32ShellFolder2 extends ShellFolder {
long pIShellFolder = getIShellFolder();
long pEnumObjects = getEnumObjects(pIShellFolder, true);
Win32ShellFolder2 child = null;
long childPIDL = 0;
long childPIDL;
while ((childPIDL = getNextChild(pEnumObjects)) != 0) {
if (getAttributes0(pIShellFolder, childPIDL, ATTRIB_FILESYSTEM) != 0) {
......@@ -983,7 +983,7 @@ final class Win32ShellFolder2 extends ShellFolder {
? SwingConstants.CENTER
: SwingConstants.LEADING);
column.setComparator(new ColumnComparator(i));
column.setComparator(new ColumnComparator(getIShellFolder(), i));
notNullColumns.add(column);
}
......@@ -1002,22 +1002,29 @@ final class Win32ShellFolder2 extends ShellFolder {
private native Object doGetColumnValue(long parentIShellFolder2, long childPIDL, int columnIdx);
private native int compareIDsByColumn(long pParentIShellFolder, long pidl1, long pidl2, int columnIdx);
private static native int compareIDsByColumn(long pParentIShellFolder, long pidl1, long pidl2, int columnIdx);
private class ColumnComparator implements Comparator {
public void sortChildren(List<? extends File> files) {
Collections.sort(files, new ColumnComparator(getIShellFolder(), 0));
}
private static class ColumnComparator implements Comparator<File> {
private final long parentIShellFolder;
private final int columnIdx;
public ColumnComparator(int columnIdx) {
public ColumnComparator(long parentIShellFolder, int columnIdx) {
this.parentIShellFolder = parentIShellFolder;
this.columnIdx = columnIdx;
}
// compares 2 objects within this folder by the specified column
public int compare(Object o, Object o1) {
public int compare(File o, File o1) {
if (o instanceof Win32ShellFolder2
&& o1 instanceof Win32ShellFolder2) {
// delegates comparison to native method
return compareIDsByColumn(getIShellFolder(),
return compareIDsByColumn(parentIShellFolder,
((Win32ShellFolder2) o).getRelativePIDL(),
((Win32ShellFolder2) o1).getRelativePIDL(),
columnIdx);
......
......@@ -234,11 +234,11 @@ public class Win32ShellFolderManager2 extends ShellFolderManager {
// Add third level for "My Computer"
if (folder.equals(drives)) {
File[] thirdLevelFolders = folder.listFiles();
if (thirdLevelFolders != null) {
Arrays.sort(thirdLevelFolders, driveComparator);
for (File thirdLevelFolder : thirdLevelFolders) {
folders.add(thirdLevelFolder);
}
if (thirdLevelFolders != null && thirdLevelFolders.length > 0) {
List<File> thirdLevelFoldersList = Arrays.asList(thirdLevelFolders);
folder.sortChildren(thirdLevelFoldersList);
folders.addAll(thirdLevelFoldersList);
}
}
}
......@@ -362,27 +362,6 @@ public class Win32ShellFolderManager2 extends ShellFolderManager {
return false;
}
private Comparator driveComparator = new Comparator() {
public int compare(Object o1, Object o2) {
Win32ShellFolder2 shellFolder1 = (Win32ShellFolder2) o1;
Win32ShellFolder2 shellFolder2 = (Win32ShellFolder2) o2;
// Put drives at first
boolean isDrive1 = shellFolder1.getPath().endsWith(":\\");
if (isDrive1 ^ shellFolder2.getPath().endsWith(":\\")) {
return isDrive1 ? -1 : 1;
} else {
return shellFolder1.getPath().compareTo(shellFolder2.getPath());
}
}
};
public void sortFiles(List files) {
Collections.sort(files, fileComparator);
}
private static List topFolderList = null;
static int compareShellFolders(Win32ShellFolder2 sf1, Win32ShellFolder2 sf2) {
boolean special1 = sf1.isSpecial();
......@@ -418,19 +397,9 @@ public class Win32ShellFolderManager2 extends ShellFolderManager {
return compareNames(sf1.getAbsolutePath(), sf2.getAbsolutePath());
}
static int compareFiles(File f1, File f2) {
if (f1 instanceof Win32ShellFolder2) {
return f1.compareTo(f2);
}
if (f2 instanceof Win32ShellFolder2) {
return -1 * f2.compareTo(f1);
}
return compareNames(f1.getName(), f2.getName());
}
static int compareNames(String name1, String name2) {
// First ignore case when comparing
int diff = name1.toLowerCase().compareTo(name2.toLowerCase());
int diff = name1.compareToIgnoreCase(name2);
if (diff != 0) {
return diff;
} else {
......@@ -439,14 +408,4 @@ public class Win32ShellFolderManager2 extends ShellFolderManager {
return name1.compareTo(name2);
}
}
private Comparator fileComparator = new Comparator() {
public int compare(Object a, Object b) {
return compare((File)a, (File)b);
}
public int compare(File f1, File f2) {
return compareFiles(f1, f2);
}
};
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册