diff --git a/src/java.desktop/share/classes/javax/swing/filechooser/FileSystemView.java b/src/java.desktop/share/classes/javax/swing/filechooser/FileSystemView.java
index 1a6c0e41cac20..b089b1e2d3f81 100644
--- a/src/java.desktop/share/classes/javax/swing/filechooser/FileSystemView.java
+++ b/src/java.desktop/share/classes/javax/swing/filechooser/FileSystemView.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
package javax.swing.filechooser;
import java.awt.Image;
+import java.awt.image.AbstractMultiResolutionImage;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.FileNotFoundException;
@@ -255,6 +256,54 @@ public Icon getSystemIcon(File f) {
}
}
+ /**
+ * Icon for a file, directory, or folder as it would be displayed in
+ * a system file browser for the requested size.
+ *
+ * The default implementation gets information from the
+ * ShellFolder class. Whenever possible the icon
+ * returned will be a multi-resolution icon image,
+ * which will allow better scaling with different
+ * magnification factors.
+ *
+ * Example:
+ * FileSystemView fsv = FileSystemView.getFileSystemView();
+ * Icon icon = fsv.getSystemIcon("application.exe", 64);
+ * JLabel label = new JLabel(icon);
+ *
+ *
+ * @param f a File object
+ * @param size width and height of the icon in pixels
+ * @return an icon as it would be displayed by a native file chooser
+ * or null if invalid parameters are passed such as pointer to a
+ * non-existing file.
+ * @see JFileChooser#getIcon
+ * @see AbstractMultiResolutionImage
+ * @since 16
+ */
+ public Icon getSystemIcon(File f, int size) {
+ if (f == null) {
+ return null;
+ }
+
+ ShellFolder sf;
+
+ try {
+ sf = ShellFolder.getShellFolder(f);
+ } catch (FileNotFoundException e) {
+ return null;
+ }
+
+ Image img = sf.getIcon(size);
+
+ if (img != null) {
+ return new ImageIcon(img, sf.getFolderType());
+ } else {
+ return UIManager.getIcon(f.isDirectory() ? "FileView.directoryIcon"
+ : "FileView.fileIcon");
+ }
+ }
+
/**
* On Windows, a file can appear in multiple folders, other than its
* parent directory in the filesystem. Folder could for example be the
diff --git a/src/java.desktop/share/classes/sun/awt/shell/ShellFolder.java b/src/java.desktop/share/classes/sun/awt/shell/ShellFolder.java
index ca8f2f40fb0e2..ba0aaf175ef6d 100644
--- a/src/java.desktop/share/classes/sun/awt/shell/ShellFolder.java
+++ b/src/java.desktop/share/classes/sun/awt/shell/ShellFolder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -201,6 +201,15 @@ public Image getIcon(boolean getLargeIcon) {
return null;
}
+ /**
+ * Returns the icon of the specified size used to display this shell folder.
+ *
+ * @param size size of the icon > 0(Valid range: 1 to 256)
+ * @return The icon of the specified size used to display this shell folder
+ */
+ public Image getIcon(int size) {
+ return null;
+ }
// Static
diff --git a/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolder2.java b/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolder2.java
index 64817438eba14..42ae204c809e6 100644
--- a/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolder2.java
+++ b/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolder2.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -74,6 +74,16 @@
@SuppressWarnings("serial") // JDK-implementation class
final class Win32ShellFolder2 extends ShellFolder {
+ static final int SMALL_ICON_SIZE = 16;
+ static final int LARGE_ICON_SIZE = 32;
+ static final int MIN_QUALITY_ICON = 16;
+ static final int MAX_QUALITY_ICON = 256;
+ private final static int[] ICON_RESOLUTIONS
+ = {16, 24, 32, 48, 64, 72, 96, 128, 256};
+
+ static final int FILE_ICON_ID = 1;
+ static final int FOLDER_ICON_ID = 4;
+
private static native void initIDs();
static {
@@ -982,7 +992,10 @@ public String getExecutableType() {
// 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);
+
+ // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
+ private static native boolean hiResIconAvailable(long parentIShellFolder, long relativePIDL);
// Returns an icon from the Windows system icon list in the form of an HICON
private static native long getSystemIcon(int iconID);
@@ -1009,20 +1022,17 @@ private long getIShellIcon() {
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
- ? img
- : new MultiResolutionIconImage(baseSize, img);
+ new BufferedImage(iconSize, iconSize, BufferedImage.TYPE_INT_ARGB);
+ img.setRGB(0, 0, iconSize, iconSize, iconBits, 0, iconSize);
+ return img;
}
}
return null;
@@ -1034,11 +1044,13 @@ private static Image makeIcon(long hIcon, boolean getLargeIcon) {
*/
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() {
public Image call() {
Image newIcon = null;
+ Image newIcon2 = null;
if (isLink()) {
Win32ShellFolder2 folder = getLinkLocation(false);
if (folder != null && folder.isLibrary()) {
@@ -1063,33 +1075,40 @@ public Image call() {
newIcon = imageCache.get(Integer.valueOf(index));
if (newIcon == null) {
long hIcon = getIcon(getAbsolutePath(), getLargeIcon);
- newIcon = makeIcon(hIcon, getLargeIcon);
+ newIcon = makeIcon(hIcon, getLargeIcon ? LARGE_ICON_SIZE : SMALL_ICON_SIZE);
disposeIcon(hIcon);
if (newIcon != null) {
imageCache.put(Integer.valueOf(index), newIcon);
}
}
- }
- }
-
- if (newIcon == null) {
- // These are only cached per object
- long hIcon = extractIcon(getParentIShellFolder(),
- getRelativePIDL(), getLargeIcon, false);
- // E_PENDING: loading can take time so get the default
- if(hIcon <= 0) {
- hIcon = extractIcon(getParentIShellFolder(),
- getRelativePIDL(), getLargeIcon, true);
- if(hIcon <= 0) {
- if (isDirectory()) {
- return getShell32Icon(4, getLargeIcon);
+ if (newIcon != null) {
+ if (isLink()) {
+ imageCache = getLargeIcon ? smallLinkedSystemImages
+ : largeLinkedSystemImages;
} else {
- return getShell32Icon(1, getLargeIcon);
+ imageCache = getLargeIcon ? smallSystemImages : largeSystemImages;
}
+ newIcon2 = imageCache.get(Integer.valueOf(index));
+ if (newIcon2 == null) {
+ long hIcon = getIcon(getAbsolutePath(), !getLargeIcon);
+ newIcon2 = makeIcon(hIcon, getLargeIcon ? SMALL_ICON_SIZE
+ : LARGE_ICON_SIZE);
+ disposeIcon(hIcon);
+ }
+ }
+
+ if (newIcon2 != null) {
+ Map bothIcons = new HashMap<>(2);
+ bothIcons.put(getLargeIcon? LARGE_ICON_SIZE : SMALL_ICON_SIZE, newIcon);
+ bothIcons.put(getLargeIcon? SMALL_ICON_SIZE : LARGE_ICON_SIZE, newIcon2);
+ newIcon = new MultiResolutionIconImage(getLargeIcon ? LARGE_ICON_SIZE
+ : SMALL_ICON_SIZE, bothIcons);
}
}
- newIcon = makeIcon(hIcon, getLargeIcon);
- disposeIcon(hIcon);
+ }
+
+ if (hiResIconAvailable(getParentIShellFolder(), getRelativePIDL()) || newIcon == null) {
+ newIcon = getIcon(getLargeIcon ? LARGE_ICON_SIZE : SMALL_ICON_SIZE);
}
if (newIcon == null) {
@@ -1098,21 +1117,64 @@ public Image call() {
return newIcon;
}
});
- if (getLargeIcon) {
- largeIcon = icon;
- } else {
- smallIcon = icon;
- }
}
return icon;
}
+ /**
+ * @return The icon image of specified size used to display this shell folder
+ */
+ 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);
+ }
+ }
+ Map multiResolutionIcon = new HashMap<>();
+ int start = size > MAX_QUALITY_ICON ? ICON_RESOLUTIONS.length - 1 : 0;
+ int increment = size > MAX_QUALITY_ICON ? -1 : 1;
+ int end = size > MAX_QUALITY_ICON ? -1 : ICON_RESOLUTIONS.length;
+ for (int i = start; i != end; i+=increment) {
+ int s = ICON_RESOLUTIONS[i];
+ if (size < MIN_QUALITY_ICON || size > MAX_QUALITY_ICON
+ || (s >= size/2 && s <= size*2)) {
+ long hIcon = extractIcon(getParentIShellFolder(),
+ getRelativePIDL(), s, false);
+
+ // E_PENDING: loading can take time so get the default
+ if (hIcon <= 0) {
+ hIcon = extractIcon(getParentIShellFolder(),
+ getRelativePIDL(), s, true);
+ if (hIcon <= 0) {
+ if (isDirectory()) {
+ return getShell32Icon(FOLDER_ICON_ID, size);
+ } else {
+ return getShell32Icon(FILE_ICON_ID, size);
+ }
+ }
+ }
+ newIcon = makeIcon(hIcon, s);
+ disposeIcon(hIcon);
+
+ multiResolutionIcon.put(s, newIcon);
+ if (size < 8 || size > 256) {
+ break;
+ }
+ }
+ }
+ return new MultiResolutionIconImage(size, multiResolutionIcon);
+ });
+ }
+
/**
* 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, LARGE_ICON_SIZE);
disposeIcon(hIcon);
return icon;
}
@@ -1120,11 +1182,8 @@ static Image getSystemIcon(SystemIcon iconType) {
/**
* 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) {
@@ -1133,7 +1192,7 @@ static Image getShell32Icon(int iconID, boolean getLargeIcon) {
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;
}
@@ -1316,13 +1375,17 @@ public List call() throws Exception {
}
static class MultiResolutionIconImage extends AbstractMultiResolutionImage {
-
final int baseSize;
- final Image resolutionVariant;
+ final Map resolutionVariants = new HashMap<>();
- public MultiResolutionIconImage(int baseSize, Image resolutionVariant) {
+ public MultiResolutionIconImage(int baseSize, Map resolutionVariants) {
this.baseSize = baseSize;
- this.resolutionVariant = resolutionVariant;
+ this.resolutionVariants.putAll(resolutionVariants);
+ }
+
+ public MultiResolutionIconImage(int baseSize, Image image) {
+ this.baseSize = baseSize;
+ this.resolutionVariants.put(baseSize, image);
}
@Override
@@ -1337,17 +1400,34 @@ public int getHeight(ImageObserver observer) {
@Override
protected Image getBaseImage() {
- return resolutionVariant;
+ return getResolutionVariant(baseSize, baseSize);
}
@Override
public Image getResolutionVariant(double width, double height) {
- return resolutionVariant;
+ int dist = 0;
+ Image retVal = null;
+ // We only care about width since we don't support non-rectangular icons
+ int w = (int) width;
+ int retindex = 0;
+ for (Integer i: resolutionVariants.keySet()) {
+ if (retVal == null || dist > Math.abs(i - w)
+ || (dist == Math.abs(i - w) && i > retindex)) {
+ retindex = i;
+ dist = Math.abs(i - w);
+ retVal = resolutionVariants.get(i);
+ if (i == w) {
+ break;
+ }
+ }
+ }
+ return retVal;
}
@Override
public List getResolutionVariants() {
- return Arrays.asList(resolutionVariant);
+ return Collections.unmodifiableList(
+ new ArrayList(resolutionVariants.values()));
}
}
}
diff --git a/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java b/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java
index 8dd6cbbb38ba7..99cbb1851b4f8 100644
--- a/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java
+++ b/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -53,10 +53,12 @@
import static sun.awt.shell.Win32ShellFolder2.DESKTOP;
import static sun.awt.shell.Win32ShellFolder2.DRIVES;
import static sun.awt.shell.Win32ShellFolder2.Invoker;
+import static sun.awt.shell.Win32ShellFolder2.LARGE_ICON_SIZE;
import static sun.awt.shell.Win32ShellFolder2.MultiResolutionIconImage;
import static sun.awt.shell.Win32ShellFolder2.NETWORK;
import static sun.awt.shell.Win32ShellFolder2.PERSONAL;
import static sun.awt.shell.Win32ShellFolder2.RECENT;
+import static sun.awt.shell.Win32ShellFolder2.SMALL_ICON_SIZE;
// NOTE: This class supersedes Win32ShellFolderManager, which was removed
// from distribution after version 1.4.2.
@@ -144,9 +146,9 @@ private static Image getStandardViewButton(int iconIndex) {
new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
img.setRGB(0, 0, size, size, iconBits, 0, size);
- STANDARD_VIEW_BUTTONS[iconIndex] = (size == 16)
+ STANDARD_VIEW_BUTTONS[iconIndex] = (size == SMALL_ICON_SIZE)
? img
- : new MultiResolutionIconImage(16, img);
+ : new MultiResolutionIconImage(SMALL_ICON_SIZE, img);
}
return STANDARD_VIEW_BUTTONS[iconIndex];
@@ -408,7 +410,8 @@ public Object get(String key) {
try {
int i = Integer.parseInt(name);
if (i >= 0) {
- return Win32ShellFolder2.getShell32Icon(i, key.startsWith("shell32LargeIcon "));
+ return Win32ShellFolder2.getShell32Icon(i,
+ key.startsWith("shell32LargeIcon ")?LARGE_ICON_SIZE : SMALL_ICON_SIZE);
}
} catch (NumberFormatException ex) {
}
diff --git a/src/java.desktop/windows/native/libawt/windows/ShellFolder2.cpp b/src/java.desktop/windows/native/libawt/windows/ShellFolder2.cpp
index 6e6d5bd021011..60ee407ec9f30 100644
--- a/src/java.desktop/windows/native/libawt/windows/ShellFolder2.cpp
+++ b/src/java.desktop/windows/native/libawt/windows/ShellFolder2.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -880,7 +880,7 @@ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_getIcon
LPCTSTR pathStr = JNU_GetStringPlatformChars(env, absolutePath, NULL);
JNU_CHECK_EXCEPTION_RETURN(env, 0);
if (fn_SHGetFileInfo(pathStr, 0L, &fileInfo, sizeof(fileInfo),
- SHGFI_ICON | (getLargeIcon ? 0 : SHGFI_SMALLICON)) != 0) {
+ SHGFI_ICON | (getLargeIcon ? SHGFI_LARGEICON : SHGFI_SMALLICON)) != 0) {
hIcon = fileInfo.hIcon;
}
JNU_ReleaseStringPlatformChars(env, absolutePath, pathStr);
@@ -912,15 +912,51 @@ JNIEXPORT jint JNICALL Java_sun_awt_shell_Win32ShellFolder2_getIconIndex
return (jint)index;
}
+/*
+ * Class: sun.awt.shell.Win32ShellFolder2
+ * Method: hiResIconAvailable
+ * Signature: (JJ)Z
+ */
+JNIEXPORT jboolean JNICALL Java_sun_awt_shell_Win32ShellFolder2_hiResIconAvailable
+ (JNIEnv* env, jclass cls, jlong pIShellFolderL, jlong relativePIDL)
+{
+ IShellFolder* pIShellFolder = (IShellFolder*)pIShellFolderL;
+ LPITEMIDLIST pidl = (LPITEMIDLIST)relativePIDL;
+ if (pIShellFolder == NULL || pidl == NULL) {
+ return FALSE;
+ }
+ HRESULT hres;
+ IExtractIconW* pIcon;
+ hres = pIShellFolder->GetUIObjectOf(NULL, 1, const_cast(&pidl),
+ IID_IExtractIconW, NULL, (void**)&pIcon);
+ if (SUCCEEDED(hres)) {
+ WCHAR szBuf[MAX_PATH];
+ INT index;
+ UINT flags;
+ UINT uFlags = GIL_FORSHELL | GIL_ASYNC;
+ hres = pIcon->GetIconLocation(uFlags, szBuf, MAX_PATH, &index, &flags);
+ if (SUCCEEDED(hres)) {
+ return wcscmp(szBuf, L"*") != 0;
+ } else if (hres == E_PENDING) {
+ uFlags = GIL_DEFAULTICON;
+ hres = pIcon->GetIconLocation(uFlags, szBuf, MAX_PATH, &index, &flags);
+ if (SUCCEEDED(hres)) {
+ return wcscmp(szBuf, L"*") != 0;
+ }
+ }
+ }
+ return FALSE;
+}
+
/*
* Class: sun_awt_shell_Win32ShellFolder2
* Method: extractIcon
- * Signature: (JJZZ)J
+ * Signature: (JJIZ)J
*/
JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_extractIcon
(JNIEnv* env, jclass cls, jlong pIShellFolderL, jlong relativePIDL,
- jboolean getLargeIcon, jboolean getDefaultIcon)
+ jint size, jboolean getDefaultIcon)
{
IShellFolder* pIShellFolder = (IShellFolder*)pIShellFolderL;
LPITEMIDLIST pidl = (LPITEMIDLIST)relativePIDL;
@@ -928,6 +964,7 @@ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_extractIcon
return 0;
}
+ HICON hIconLow = NULL;
HICON hIcon = NULL;
HRESULT hres;
@@ -941,15 +978,12 @@ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_extractIcon
UINT uFlags = getDefaultIcon ? GIL_DEFAULTICON : GIL_FORSHELL | GIL_ASYNC;
hres = pIcon->GetIconLocation(uFlags, szBuf, MAX_PATH, &index, &flags);
if (SUCCEEDED(hres)) {
- HICON hIconLarge;
- hres = pIcon->Extract(szBuf, index, &hIconLarge, &hIcon, (16 << 16) + 32);
- if (SUCCEEDED(hres)) {
- if (getLargeIcon) {
- fn_DestroyIcon((HICON)hIcon);
- hIcon = hIconLarge;
- } else {
- fn_DestroyIcon((HICON)hIconLarge);
- }
+ hres = pIcon->Extract(szBuf, index, &hIcon, &hIconLow, (16 << 16) + size);
+ if (size < 24) {
+ fn_DestroyIcon((HICON)hIcon);
+ hIcon = hIconLow;
+ } else {
+ fn_DestroyIcon((HICON)hIconLow);
}
} else if (hres == E_PENDING) {
pIcon->Release();
@@ -980,7 +1014,7 @@ JNIEXPORT void JNICALL Java_sun_awt_shell_Win32ShellFolder2_disposeIcon
JNIEXPORT jintArray JNICALL Java_sun_awt_shell_Win32ShellFolder2_getIconBits
(JNIEnv* env, jclass cls, jlong hicon)
{
- const int MAX_ICON_SIZE = 128;
+ const int MAX_ICON_SIZE = 256;
int iconSize = 0;
jintArray iconBits = NULL;
diff --git a/test/jdk/javax/swing/JFileChooser/FileSystemView/SystemIconTest.java b/test/jdk/javax/swing/JFileChooser/FileSystemView/SystemIconTest.java
new file mode 100644
index 0000000000000..34ee5ef9630e6
--- /dev/null
+++ b/test/jdk/javax/swing/JFileChooser/FileSystemView/SystemIconTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8182043
+ * @requires os.family == "windows"
+ * @summary Access to Windows Large Icons
+ * sun.awt.shell.ShellFolder
+ * @run main SystemIconTest
+ */
+import javax.swing.ImageIcon;
+import javax.swing.filechooser.FileSystemView;
+import java.io.File;
+
+public class SystemIconTest {
+ static final FileSystemView fsv = FileSystemView.getFileSystemView();
+
+ public static void main(String[] args) {
+ testSystemIcon();
+ System.out.println("ok");
+ }
+
+ static void testSystemIcon() {
+ String windir = System.getenv("windir");
+ testSystemIcon(new File(windir));
+ testSystemIcon(new File(windir + "/explorer.exe"));
+ return;
+ }
+
+ static void testSystemIcon(File file) {
+ int[] sizes = new int[] {16, 32, 48, 64, 128};
+ for (int size : sizes) {
+ ImageIcon icon = (ImageIcon) fsv.getSystemIcon(file, size);
+
+ //Enable below to see the icon
+ //JLabel label = new JLabel(icon);
+ //JOptionPane.showMessageDialog(null, label);
+
+ if (icon == null) {
+ throw new RuntimeException("icon is null!!!");
+ }
+
+ if (icon.getIconWidth() != size) {
+ throw new RuntimeException("Wrong icon size " +
+ icon.getIconWidth() + " when requested " + size);
+ }
+ }
+ }
+}