--- old/src/java.desktop/share/classes/javax/swing/filechooser/FileSystemView.java 2018-07-30 12:17:24.218779400 +0530 +++ new/src/java.desktop/share/classes/javax/swing/filechooser/FileSystemView.java 2018-07-30 12:17:20.755754200 +0530 @@ -45,6 +45,14 @@ import jdk.internal.ref.CleanerFactory; import sun.awt.shell.ShellFolder; +import java.awt.image.BufferedImage; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.RenderingHints; +import java.awt.Transparency; + /** * FileSystemView is JFileChooser's gateway to the * file system. Since the JDK1.1 File API doesn't allow @@ -256,6 +264,123 @@ } /** + * Scaled icon for a file, directory, or folder as it would be displayed in + * a system file browser. Example from Windows: the "M:\" directory + * displays a CD-ROM icon. + * + * The default implementation gets information from the ShellFolder class. + * + * @param f a File object + * @param width width of the icon in pixels to be scaled(valid range: 1 to 256) + * @param height height of the icon in pixels to be scaled(valid range: 1 to 256) + * @return an icon as it would be displayed by a native file chooser + * @see JFileChooser#getIcon + * @since 12 + */ + public Icon getSystemIcon(File f, int width, int height) { + if (f == null) { + return null; + } + + if((width > 256 || width < 1) || (height > 256 || height < 1)) { + return null; + } + + ShellFolder sf; + try { + sf = getShellFolder(f); + } catch (FileNotFoundException e) { + return null; + } + + int size; + if(width > height) { + size = width; + } else { + size = height; + } + + Image img = sf.getIcon(size); + + // scale the icon in case the width/height does not match the requested + if (img != null) { + if((img.getWidth(null) != width) || (img.getHeight(null) != height)) { + Image scaledImg = scaleIconImage(img, null, width, height); + + // set the scaled icon + if(scaledImg != null) { + img = scaledImg; + } else { + return null; + } + } + } else { + Icon icon = UIManager.getIcon(f.isDirectory() ? "FileView.directoryIcon" : "FileView.fileIcon"); + + if((icon != null) && ((icon.getIconWidth() != width) || (icon.getIconHeight() != height))) { + Image scaledImg = scaleIconImage(null, icon, width, height); + + // set the scaled icon + if(scaledImg != null) { + img = scaledImg; + } else { + return null; + } + } + } + + if (img != null) { + return new ImageIcon(img, sf.getFolderType()); + } + + return null; + } + + private static Image scaleIconImage(Image srcImage, Icon srcIcon, int scaledW, int scaledH) { + if (srcImage == null && srcIcon == null) { + return null; + } + + int w; + int h; + + if(srcImage != null) { + w = srcImage.getWidth(null); + h = srcImage.getHeight(null); + } else { + w = srcIcon.getIconWidth(); + h = srcIcon.getIconHeight(); + } + + GraphicsEnvironment ge = + GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice gd = ge.getDefaultScreenDevice(); + GraphicsConfiguration gc = gd.getDefaultConfiguration(); + + // convert to image + BufferedImage iconImage = gc.createCompatibleImage(w, h, + Transparency.TRANSLUCENT); + Graphics2D g = iconImage.createGraphics(); + if(srcImage != null) { + g.drawImage(srcImage, 0, 0, w, h, null); + } else { + srcIcon.paintIcon(null, g, 0, 0); + } + g.dispose(); + + // and scale it nicely + BufferedImage scaledImage = gc.createCompatibleImage(scaledW, scaledH, + Transparency.TRANSLUCENT); + g = scaledImage.createGraphics(); + g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, + RenderingHints.VALUE_INTERPOLATION_BILINEAR); + g.drawImage(iconImage, 0, 0, scaledW, scaledH, null); + g.dispose(); + + return (Image)scaledImage; + } + + /** * On Windows, a file can appear in multiple folders, other than its * parent directory in the filesystem. Folder could for example be the * "Desktop" folder which is not the same as file.getParentFile().