--- old/src/java.desktop/share/classes/javax/swing/filechooser/FileSystemView.java 2018-07-20 11:46:39.280292200 +0530 +++ new/src/java.desktop/share/classes/javax/swing/filechooser/FileSystemView.java 2018-07-20 11:46:37.797280200 +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,146 @@ } /** + * 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 + * @param height height of the icon in pixels to be scaled + * @return an icon as it would be displayed by a native file chooser + * @exception RuntimeException if the icon failes to be scaled or + * @exception IllegalArgumentException if the icon scaling is out of range + * @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)) { + System.err.println("Warning: Icon scaling may be distorted"); + throw new IllegalArgumentException("unexpected icon scaling size"); + } + + 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, width, height); + + // set the scaled icon + if(scaledImg != null) { + img = scaledImg; + } else { + throw new RuntimeException("unable to scale the icon"); + } + } + } else { + Icon icon = UIManager.getIcon(f.isDirectory() ? "FileView.directoryIcon" : "FileView.fileIcon"); + + if((icon != null) && ((icon.getIconWidth() != width) || (icon.getIconHeight() != height))) { + Image scaledImg = scaleIcon(icon, width, height); + + // set the scaled icon + if(scaledImg != null) { + img = scaledImg; + } else { + throw new RuntimeException("unable to scale the icon"); + } + } + } + + if (img != null) { + return new ImageIcon(img, sf.getFolderType()); + } + + return null; + } + + private static Image scaleIconImage(Image icon, int scaledW, int scaledH) { + if (icon == null) { + return null; + } + + int w = icon.getWidth(null); + int h = icon.getHeight(null); + + GraphicsEnvironment ge = + GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice gd = ge.getDefaultScreenDevice(); + GraphicsConfiguration gc = gd.getDefaultConfiguration(); + + // convert icon into image + BufferedImage iconImage = gc.createCompatibleImage(w, h, + Transparency.TRANSLUCENT); + Graphics2D g = iconImage.createGraphics(); + g.drawImage(icon, 0, 0, w, h, null); + 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; + } + + private static Image scaleIcon(Icon icon, int scaledW, int scaledH) { + if (icon == null) { + return null; + } + + int w = icon.getIconWidth(); + int h = icon.getIconHeight(); + + GraphicsEnvironment ge = + GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice gd = ge.getDefaultScreenDevice(); + GraphicsConfiguration gc = gd.getDefaultConfiguration(); + + // convert icon into image + BufferedImage iconImage = gc.createCompatibleImage(w, h, + Transparency.TRANSLUCENT); + Graphics2D g = iconImage.createGraphics(); + icon.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().