--- old/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolder2.java 2018-09-21 15:20:08.637346000 -0700 +++ new/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolder2.java 2018-09-21 15:20:07.518905200 -0700 @@ -74,6 +74,9 @@ @SuppressWarnings("serial") // JDK-implementation class final class Win32ShellFolder2 extends ShellFolder { + static final int SMALL_ICON_SIZE = 16; + static final int LARGE_ICON_SIZE = 32; + private static native void initIDs(); static { @@ -977,7 +980,7 @@ // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details private static native long extractIcon(long parentIShellFolder, long relativePIDL, - boolean getLargeIcon, boolean getDefaultIcon); + int size, boolean getDefaultIcon); // Returns an icon from the Windows system icon list in the form of an HICON private static native long getSystemIcon(int iconID); @@ -1004,20 +1007,19 @@ return pIShellIcon; } - private static Image makeIcon(long hIcon, boolean getLargeIcon) { + private static Image makeIcon(long hIcon, int size) { if (hIcon != 0L && hIcon != -1L) { // Get the bits. This has the side effect of setting the imageHash value for this object. final int[] iconBits = getIconBits(hIcon); if (iconBits != null) { // icons are always square - final int size = (int) Math.sqrt(iconBits.length); - final int baseSize = getLargeIcon ? 32 : 16; + final int iconSize = (int) Math.sqrt(iconBits.length); final BufferedImage img = - new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB); - img.setRGB(0, 0, size, size, iconBits, 0, size); - return size == baseSize + new BufferedImage(iconSize, iconSize, BufferedImage.TYPE_INT_ARGB); + img.setRGB(0, 0, iconSize, iconSize, iconBits, 0, iconSize); + return iconSize == size ? img - : new MultiResolutionIconImage(baseSize, img); + : new MultiResolutionIconImage(size, img); } } return null; @@ -1029,6 +1031,7 @@ */ public Image getIcon(final boolean getLargeIcon) { Image icon = getLargeIcon ? largeIcon : smallIcon; + int size = getLargeIcon ? LARGE_ICON_SIZE : SMALL_ICON_SIZE; if (icon == null) { icon = invoke(new Callable() { @@ -1058,7 +1061,7 @@ newIcon = imageCache.get(Integer.valueOf(index)); if (newIcon == null) { long hIcon = getIcon(getAbsolutePath(), getLargeIcon); - newIcon = makeIcon(hIcon, getLargeIcon); + newIcon = makeIcon(hIcon, size); disposeIcon(hIcon); if (newIcon != null) { imageCache.put(Integer.valueOf(index), newIcon); @@ -1070,20 +1073,20 @@ if (newIcon == null) { // These are only cached per object long hIcon = extractIcon(getParentIShellFolder(), - getRelativePIDL(), getLargeIcon, false); + getRelativePIDL(), size, false); // E_PENDING: loading can take time so get the default if(hIcon <= 0) { hIcon = extractIcon(getParentIShellFolder(), - getRelativePIDL(), getLargeIcon, true); + getRelativePIDL(), size, true); if(hIcon <= 0) { if (isDirectory()) { - return getShell32Icon(4, getLargeIcon); + return getShell32Icon(4, size); // pick folder icon } else { - return getShell32Icon(1, getLargeIcon); + return getShell32Icon(1, size); // pick file icon } } } - newIcon = makeIcon(hIcon, getLargeIcon); + newIcon = makeIcon(hIcon, size); disposeIcon(hIcon); } @@ -1093,21 +1096,46 @@ return newIcon; } }); - if (getLargeIcon) { - largeIcon = icon; - } else { - smallIcon = icon; - } } return icon; } + public Image getIcon(int size) { + return invoke(() -> { + Image newIcon = null; + if (isLink()) { + Win32ShellFolder2 folder = getLinkLocation(false); + if (folder != null && folder.isLibrary()) { + return folder.getIcon(size); + } + } + long hIcon = extractIcon(getParentIShellFolder(), + getRelativePIDL(), size, false); + + // E_PENDING: loading can take time so get the default + if (hIcon <= 0) { + hIcon = extractIcon(getParentIShellFolder(), + getRelativePIDL(), size, true); + if (hIcon <= 0) { + if (isDirectory()) { + return getShell32Icon(4, size); + } else { + return getShell32Icon(1, size); + } + } + } + newIcon = makeIcon(hIcon, size); + disposeIcon(hIcon); + return newIcon; + }); + } + /** * Gets an icon from the Windows system icon list as an {@code Image} */ static Image getSystemIcon(SystemIcon iconType) { long hIcon = getSystemIcon(iconType.getIconID()); - Image icon = makeIcon(hIcon, true); + Image icon = makeIcon(hIcon, 32); disposeIcon(hIcon); return icon; } @@ -1115,11 +1143,8 @@ /** * Gets an icon from the Windows system icon list as an {@code Image} */ - static Image getShell32Icon(int iconID, boolean getLargeIcon) { + static Image getShell32Icon(int iconID, int size) { boolean useVGAColors = true; // Will be ignored on XP and later - - int size = getLargeIcon ? 32 : 16; - Toolkit toolkit = Toolkit.getDefaultToolkit(); String shellIconBPP = (String)toolkit.getDesktopProperty("win.icon.shellIconBPP"); if (shellIconBPP != null) { @@ -1128,7 +1153,7 @@ long hIcon = getIconResource("shell32.dll", iconID, size, size, useVGAColors); if (hIcon != 0) { - Image icon = makeIcon(hIcon, getLargeIcon); + Image icon = makeIcon(hIcon, size); disposeIcon(hIcon); return icon; }