< prev index next >

src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolder2.java

Print this page
rev 13901 : Fixes for 8151385. Contains additional fix for 8149453 (upFolder, newFolder, etc. icons)
rev 13629 : 8138838: docs cleanup for java.desktop
Summary: docs cleanup for java.desktop
Reviewed-by: serb
rev 13226 : 8030099: Memory usage of java process increases after pressing start button in test window
Reviewed-by: prr, serb
rev 12267 : 8022057: JFileChooser blocks EDT in Win32ShellFolder2.getIcon
Reviewed-by: serb, ant
rev 12260 : 8017487: filechooser in Windows-Libraries folder: columns are mixed up
Reviewed-by: serb, ant
rev 12117 : 8003399: JFileChooser gives wrong path to selected file when saving to Libraries folder on Windows 7
Reviewed-by: serb, ant
rev 11099 : 8067377: My hobby: caning, then then canning, the the can-can
Summary: Fix ALL the stutters!
Reviewed-by: rriggs, mchung, lancea
rev 10444 : 8054834: Modular Source Code
Reviewed-by: alanb, chegar, ihse, mduigou
Contributed-by: alan.bateman@oracle.com, alex.buckley@oracle.com, chris.hegarty@oracle.com, erik.joelsson@oracle.com, jonathan.gibbons@oracle.com, karen.kinnear@oracle.com, magnus.ihse.bursie@oracle.com, mandy.chung@oracle.com, mark.reinhold@oracle.com, paul.sandoz@oracle.com


 965 
 966     // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
 967     private static native int getIconIndex(long parentIShellIcon, long relativePIDL);
 968 
 969     // Return the icon of a file system shell folder in the form of an HICON
 970     private static native long getIcon(String absolutePath, boolean getLargeIcon);
 971 
 972     // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
 973     private static native long extractIcon(long parentIShellFolder, long relativePIDL,
 974                                            boolean getLargeIcon, boolean getDefaultIcon);
 975 
 976     // Returns an icon from the Windows system icon list in the form of an HICON
 977     private static native long getSystemIcon(int iconID);
 978     private static native long getIconResource(String libName, int iconID,
 979                                                int cxDesired, int cyDesired,
 980                                                boolean useVGAColors);
 981                                                // Note: useVGAColors is ignored on XP and later
 982 
 983     // Return the bits from an HICON.  This has a side effect of setting
 984     // the imageHash variable for efficient caching / comparing.
 985     private static native int[] getIconBits(long hIcon, int iconSize);
 986     // Dispose the HICON
 987     private static native void disposeIcon(long hIcon);
 988 
 989     static native int[] getStandardViewButton0(int iconIndex);

 990 
 991     // Should be called from the COM thread
 992     private long getIShellIcon() {
 993         if (pIShellIcon == -1L) {
 994             pIShellIcon = getIShellIcon(getIShellFolder());
 995         }
 996 
 997         return pIShellIcon;
 998     }
 999 
1000     private static Image makeIcon(long hIcon, boolean getLargeIcon) {
1001         if (hIcon != 0L && hIcon != -1L) {
1002             // Get the bits.  This has the side effect of setting the imageHash value for this object.
1003             int size = getLargeIcon ? 32 : 16;
1004             int[] iconBits = getIconBits(hIcon, size);

1005             if (iconBits != null) {
1006                 BufferedImage img = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
1007                 img.setRGB(0, 0, size, size, iconBits, 0, size);
1008                 return img;
1009             }
1010         }
1011         return null;
1012     }
1013 
1014 
1015     /**
1016      * @return The icon image used to display this shell folder
1017      */
1018     public Image getIcon(final boolean getLargeIcon) {
1019         Image icon = getLargeIcon ? largeIcon : smallIcon;
1020         if (icon == null) {
1021             icon =
1022                 invoke(new Callable<Image>() {
1023                     public Image call() {
1024                         Image newIcon = null;
1025                         if (isLink()) {
1026                             Win32ShellFolder2 folder = getLinkLocation(false);


1029                             }
1030                         }
1031                         if (isFileSystem() || isLibrary()) {
1032                             long parentIShellIcon = (parent != null)
1033                                 ? ((Win32ShellFolder2) parent).getIShellIcon()
1034                                 : 0L;
1035                             long relativePIDL = getRelativePIDL();
1036 
1037                             // These are cached per type (using the index in the system image list)
1038                             int index = getIconIndex(parentIShellIcon, relativePIDL);
1039                             if (index > 0) {
1040                                 Map<Integer, Image> imageCache;
1041                                 if (isLink()) {
1042                                     imageCache = getLargeIcon ? largeLinkedSystemImages : smallLinkedSystemImages;
1043                                 } else {
1044                                     imageCache = getLargeIcon ? largeSystemImages : smallSystemImages;
1045                                 }
1046                                 newIcon = imageCache.get(Integer.valueOf(index));
1047                                 if (newIcon == null) {
1048                                     long hIcon = getIcon(getAbsolutePath(), getLargeIcon);
1049                                     newIcon = makeIcon(hIcon, getLargeIcon);
1050                                     disposeIcon(hIcon);
1051                                     if (newIcon != null) {
1052                                         imageCache.put(Integer.valueOf(index), newIcon);
1053                                     }
1054                                 }
1055                             }
1056                         }
1057 
1058                         if (newIcon == null) {
1059                             // These are only cached per object
1060                             long hIcon = extractIcon(getParentIShellFolder(),
1061                                     getRelativePIDL(), getLargeIcon, false);
1062                             // E_PENDING: loading can take time so get the default
1063                             if(hIcon <= 0) {
1064                                 hIcon = extractIcon(getParentIShellFolder(),
1065                                          getRelativePIDL(), getLargeIcon, true);
1066                                 if(hIcon <= 0) {
1067                                     if (isDirectory()) {
1068                                         return getShell32Icon(4, getLargeIcon);
1069                                     } else {
1070                                         return getShell32Icon(1, getLargeIcon);
1071                                     }
1072                                 }
1073                             }
1074                             newIcon = makeIcon(hIcon, getLargeIcon);
1075                             disposeIcon(hIcon);
1076                         }
1077 
1078                         if (newIcon == null) {
1079                             newIcon = Win32ShellFolder2.super.getIcon(getLargeIcon);
1080                         }
1081                         return newIcon;
1082                     }
1083                 });
1084             if (getLargeIcon) {
1085                 largeIcon = icon;
1086             } else {
1087                 smallIcon = icon;
1088             }
1089         }
1090         return icon;
1091     }
1092 
1093     /**
1094      * Gets an icon from the Windows system icon list as an {@code Image}
1095      */
1096     static Image getSystemIcon(SystemIcon iconType) {
1097         long hIcon = getSystemIcon(iconType.getIconID());
1098         Image icon = makeIcon(hIcon, true);
1099         disposeIcon(hIcon);
1100         return icon;
1101     }
1102 
1103     /**
1104      * Gets an icon from the Windows system icon list as an {@code Image}
1105      */
1106     static Image getShell32Icon(int iconID, boolean getLargeIcon) {
1107         boolean useVGAColors = true; // Will be ignored on XP and later
1108 
1109         int size = getLargeIcon ? 32 : 16;
1110 
1111         Toolkit toolkit = Toolkit.getDefaultToolkit();
1112         String shellIconBPP = (String)toolkit.getDesktopProperty("win.icon.shellIconBPP");
1113         if (shellIconBPP != null) {
1114             useVGAColors = shellIconBPP.equals("4");
1115         }
1116 
1117         long hIcon = getIconResource("shell32.dll", iconID, size, size, useVGAColors);
1118         if (hIcon != 0) {
1119             Image icon = makeIcon(hIcon, getLargeIcon);
1120             disposeIcon(hIcon);
1121             return icon;
1122         }
1123         return null;
1124     }
1125 
1126     /**
1127      * Returns the canonical form of this abstract pathname.  Equivalent to
1128      * <code>new&nbsp;Win32ShellFolder2(getParentFile(), this.{@link java.io.File#getCanonicalPath}())</code>.
1129      *
1130      * @see java.io.File#getCanonicalFile
1131      */
1132     public File getCanonicalFile() throws IOException {
1133         return this;
1134     }
1135 
1136     /*
1137      * Indicates whether this is a special folder (includes My Documents)
1138      */
1139     public boolean isSpecial() {




 965 
 966     // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
 967     private static native int getIconIndex(long parentIShellIcon, long relativePIDL);
 968 
 969     // Return the icon of a file system shell folder in the form of an HICON
 970     private static native long getIcon(String absolutePath, boolean getLargeIcon);
 971 
 972     // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
 973     private static native long extractIcon(long parentIShellFolder, long relativePIDL,
 974                                            boolean getLargeIcon, boolean getDefaultIcon);
 975 
 976     // Returns an icon from the Windows system icon list in the form of an HICON
 977     private static native long getSystemIcon(int iconID);
 978     private static native long getIconResource(String libName, int iconID,
 979                                                int cxDesired, int cyDesired,
 980                                                boolean useVGAColors);
 981                                                // Note: useVGAColors is ignored on XP and later
 982 
 983     // Return the bits from an HICON.  This has a side effect of setting
 984     // the imageHash variable for efficient caching / comparing.
 985     private static native int[] getIconBits(long hIcon);
 986     // Dispose the HICON
 987     private static native void disposeIcon(long hIcon);
 988 
 989     // Get buttons from native toolbar implementation.
 990     static native int[] getStandardViewButton0(int iconIndex, boolean small);
 991 
 992     // Should be called from the COM thread
 993     private long getIShellIcon() {
 994         if (pIShellIcon == -1L) {
 995             pIShellIcon = getIShellIcon(getIShellFolder());
 996         }
 997 
 998         return pIShellIcon;
 999     }
1000 
1001     private static Image makeIcon(long hIcon) {
1002         if (hIcon != 0L && hIcon != -1L) {
1003             // Get the bits.  This has the side effect of setting the imageHash value for this object.
1004             final int[] iconBits = getIconBits(hIcon);
1005             // icons are always square
1006             final int size = (int)Math.sqrt(iconBits.length);
1007             if (iconBits != null) {
1008                 final BufferedImage img = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
1009                 img.setRGB(0, 0, size, size, iconBits, 0, size);
1010                 return img;
1011             }
1012         }
1013         return null;
1014     }
1015 
1016 
1017     /**
1018      * @return The icon image used to display this shell folder
1019      */
1020     public Image getIcon(final boolean getLargeIcon) {
1021         Image icon = getLargeIcon ? largeIcon : smallIcon;
1022         if (icon == null) {
1023             icon =
1024                 invoke(new Callable<Image>() {
1025                     public Image call() {
1026                         Image newIcon = null;
1027                         if (isLink()) {
1028                             Win32ShellFolder2 folder = getLinkLocation(false);


1031                             }
1032                         }
1033                         if (isFileSystem() || isLibrary()) {
1034                             long parentIShellIcon = (parent != null)
1035                                 ? ((Win32ShellFolder2) parent).getIShellIcon()
1036                                 : 0L;
1037                             long relativePIDL = getRelativePIDL();
1038 
1039                             // These are cached per type (using the index in the system image list)
1040                             int index = getIconIndex(parentIShellIcon, relativePIDL);
1041                             if (index > 0) {
1042                                 Map<Integer, Image> imageCache;
1043                                 if (isLink()) {
1044                                     imageCache = getLargeIcon ? largeLinkedSystemImages : smallLinkedSystemImages;
1045                                 } else {
1046                                     imageCache = getLargeIcon ? largeSystemImages : smallSystemImages;
1047                                 }
1048                                 newIcon = imageCache.get(Integer.valueOf(index));
1049                                 if (newIcon == null) {
1050                                     long hIcon = getIcon(getAbsolutePath(), getLargeIcon);
1051                                     newIcon = makeIcon(hIcon);
1052                                     disposeIcon(hIcon);
1053                                     if (newIcon != null) {
1054                                         imageCache.put(Integer.valueOf(index), newIcon);
1055                                     }
1056                                 }
1057                             }
1058                         }
1059 
1060                         if (newIcon == null) {
1061                             // These are only cached per object
1062                             long hIcon = extractIcon(getParentIShellFolder(),
1063                                     getRelativePIDL(), getLargeIcon, false);
1064                             // E_PENDING: loading can take time so get the default
1065                             if(hIcon <= 0) {
1066                                 hIcon = extractIcon(getParentIShellFolder(),
1067                                          getRelativePIDL(), getLargeIcon, true);
1068                                 if(hIcon <= 0) {
1069                                     if (isDirectory()) {
1070                                         return getShell32Icon(4, getLargeIcon);
1071                                     } else {
1072                                         return getShell32Icon(1, getLargeIcon);
1073                                     }
1074                                 }
1075                             }
1076                             newIcon = makeIcon(hIcon);
1077                             disposeIcon(hIcon);
1078                         }
1079 
1080                         if (newIcon == null) {
1081                             newIcon = Win32ShellFolder2.super.getIcon(getLargeIcon);
1082                         }
1083                         return newIcon;
1084                     }
1085                 });
1086             if (getLargeIcon) {
1087                 largeIcon = icon;
1088             } else {
1089                 smallIcon = icon;
1090             }
1091         }
1092         return icon;
1093     }
1094 
1095     /**
1096      * Gets an icon from the Windows system icon list as an {@code Image}
1097      */
1098     static Image getSystemIcon(SystemIcon iconType) {
1099         long hIcon = getSystemIcon(iconType.getIconID());
1100         Image icon = makeIcon(hIcon);
1101         disposeIcon(hIcon);
1102         return icon;
1103     }
1104 
1105     /**
1106      * Gets an icon from the Windows system icon list as an {@code Image}
1107      */
1108     static Image getShell32Icon(int iconID, boolean getLargeIcon) {
1109         boolean useVGAColors = true; // Will be ignored on XP and later
1110 
1111         int size = getLargeIcon ? 32 : 16;
1112 
1113         Toolkit toolkit = Toolkit.getDefaultToolkit();
1114         String shellIconBPP = (String)toolkit.getDesktopProperty("win.icon.shellIconBPP");
1115         if (shellIconBPP != null) {
1116             useVGAColors = shellIconBPP.equals("4");
1117         }
1118 
1119         long hIcon = getIconResource("shell32.dll", iconID, size, size, useVGAColors);
1120         if (hIcon != 0) {
1121             Image icon = makeIcon(hIcon);
1122             disposeIcon(hIcon);
1123             return icon;
1124         }
1125         return null;
1126     }
1127 
1128     /**
1129      * Returns the canonical form of this abstract pathname.  Equivalent to
1130      * <code>new&nbsp;Win32ShellFolder2(getParentFile(), this.{@link java.io.File#getCanonicalPath}())</code>.
1131      *
1132      * @see java.io.File#getCanonicalFile
1133      */
1134     public File getCanonicalFile() throws IOException {
1135         return this;
1136     }
1137 
1138     /*
1139      * Indicates whether this is a special folder (includes My Documents)
1140      */
1141     public boolean isSpecial() {


< prev index next >