1 /*
   2  * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javax.swing.filechooser;
  27 
  28 import java.awt.Image;
  29 import javax.swing.Icon;
  30 import javax.swing.ImageIcon;
  31 import javax.swing.JFileChooser;
  32 import javax.swing.UIManager;
  33 import sun.awt.shell.ShellFolder;
  34 import java.awt.RenderingHints;
  35 import java.awt.image.BufferedImage;
  36 import java.awt.Graphics2D;
  37 import java.awt.GraphicsConfiguration;
  38 import java.awt.GraphicsDevice;
  39 import java.awt.GraphicsEnvironment;
  40 import java.io.FileNotFoundException;
  41 import java.awt.Transparency;
  42 import java.io.File;
  43 import java.io.IOException;
  44 import java.awt.image.MultiResolutionImage;
  45 import java.awt.image.BaseMultiResolutionImage;
  46 
  47 /**
  48  * SystemIcon is JFileChooser's gateway to the
  49  * file system icons.
  50  *
  51  * <p>
  52  *
  53  * @author shashidhara
  54  */
  55 public class SystemIcon extends FileSystemView {
  56 
  57         /**
  58      * Store the reference to the file
  59      */
  60         protected File file;
  61 
  62         /**
  63      * Create a reference to the file
  64      */
  65     public SystemIcon() {
  66         this.file = null;
  67     }
  68 
  69         /**
  70      * Stere the reference to the file
  71      *
  72      * @param f a <code>File</code> object
  73      */
  74     public SystemIcon(File f) {
  75         this.file = f;
  76     }
  77 
  78     /**
  79      * Icon for a file, directory, or folder as it would be displayed in
  80      * a system file browser. Example from Windows: the "M:\" directory
  81      * displays a CD-ROM icon.
  82      *
  83      * The default implementation gets information from the ShellFolder class.
  84      *
  85      * @param f a <code>File</code> object
  86      * @return an icon as it would be displayed by a native file chooser
  87      * @see JFileChooser#getIcon
  88      * @since 12
  89      */
  90     public Icon getSystemIcon() {
  91         if(this.file == null) {
  92                 return null;
  93         }
  94 
  95         return getSystemIcon(this.file);
  96     }
  97 
  98         /**
  99      * Scaled icon for a file, directory, or folder as it would be displayed in
 100      * a system file browser. Example from Windows: the "M:\" directory
 101      * displays a CD-ROM icon.
 102      *
 103      * The default implementation gets information from the ShellFolder class.
 104      *
 105      * @param f a <code>File</code> object
 106      * @param width width of the icon in pixels to be scaled(valid range: 1 to 256)
 107      * @param height height of the icon in pixels to be scaled(valid range: 1 to 256)
 108      * @return an icon as it would be displayed by a native file chooser
 109      * @see JFileChooser#getIcon
 110      * @since 12
 111      */
 112     public Icon getSystemIcon(int width, int height) {
 113         if(this.file == null) {
 114                 return null;
 115         }
 116 
 117         return getSystemIcon(this.file, width, height);
 118     }
 119 
 120         /**
 121      * Scaled icon for a file, directory, or folder as it would be displayed in
 122      * a system file browser. Example from Windows: the "M:\" directory
 123      * displays a CD-ROM icon.
 124      *
 125      * The default implementation gets information from the ShellFolder class.
 126      *
 127      * @param f a <code>File</code> object
 128      * @param size width and height of the icon in pixels to be scaled(valid range: 1 to 256)
 129      * @return an icon as it would be displayed by a native file chooser
 130      * @see JFileChooser#getIcon
 131      * @since 12
 132      */
 133     public Icon getSystemIcon(int size) {
 134         if(this.file == null) {
 135                 return null;
 136         }
 137 
 138         return getSystemIcon(this.file, size, size);
 139     }
 140 
 141         /**
 142      * Scaled icon for a file, directory, or folder as it would be displayed in
 143      * a system file browser. Example from Windows: the "M:\" directory
 144      * displays a CD-ROM icon.
 145      *
 146      * The default implementation gets information from the ShellFolder class.
 147      *
 148      * @param f a <code>File</code> object
 149      * @param width width of the icon in pixels to be scaled(valid range: 1 to 256)
 150      * @param height height of the icon in pixels to be scaled(valid range: 1 to 256)
 151      * @return an icon as it would be displayed by a native file chooser
 152      * @see JFileChooser#getIcon
 153      * @since 12
 154      */
 155     public Icon getSystemIcon(File f, int width, int height) {
 156         if (f == null) {
 157             return null;
 158         }
 159 
 160         if((width > 256 || width < 1) || (height > 256 || height < 1)) {
 161             return null;
 162         }
 163 
 164         int size;
 165         if(width > height) {
 166             size = width;
 167         } else {
 168             size = height;
 169         }
 170 
 171         Icon icon = getSystemIcon(f, size);
 172         Image scaledImg = null;
 173 
 174         // scale the icon to the required size
 175         if(icon != null) {
 176             scaledImg = scaleIconImage(icon, width, height);
 177         }
 178 
 179         if (scaledImg != null) {
 180             return new ImageIcon(scaledImg);
 181         }
 182 
 183         return null;
 184     }
 185 
 186         /**
 187      * Scaled icon for a file, directory, or folder as it would be displayed in
 188      * a system file browser. Example from Windows: the "M:\" directory
 189      * displays a CD-ROM icon.
 190      *
 191      * The default implementation gets information from the ShellFolder class.
 192      *
 193      * @param f a <code>File</code> object
 194      * @param width width of the icon in pixels to be scaled(valid range: 1 to 256)
 195      * @param height height of the icon in pixels to be scaled(valid range: 1 to 256)
 196      * @return an multi resolution image icons as it would be displayed by a native file chooser
 197      * @see JFileChooser#getIcon
 198      * @since 12
 199      */
 200     public MultiResolutionImage getSystemIcons(File f, int width, int height) {
 201         Image[] imageArray;
 202         if (f == null) {
 203             return null;
 204         }
 205 
 206         if((width > 256 || width < 1) || (height > 256 || height < 1)) {
 207             return null;
 208         }
 209 
 210         int size;
 211         if(width > height) {
 212             size = width;
 213         } else {
 214             size = height;
 215         }
 216 
 217         Icon icon = getSystemIcon(f, size);
 218         Image scaledImg = null;
 219 
 220         // scale the icon to the required size
 221         if(icon != null) {
 222             scaledImg = scaleIconImage(icon, width, height);
 223         }
 224 
 225         if(scaledImg != null) {
 226                 imageArray = new Image[2];
 227 
 228                 if(icon instanceof ImageIcon) {
 229                         imageArray[0] = ((ImageIcon)icon).getImage(); // store the original icon returned from the system
 230                 } else {
 231                         BufferedImage image = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_RGB);
 232                         icon.paintIcon(null, image.getGraphics(), 0, 0);
 233                         imageArray[0] = (Image)image; // store the original icon returned from the system
 234                 }
 235                 imageArray[1] = scaledImg;       // store the scaled up icon
 236 
 237                 return new BaseMultiResolutionImage(imageArray);
 238             }
 239 
 240             return null;
 241     }
 242 
 243     private static Image scaleIconImage(Icon srcIcon, int scaledW, int scaledH) {
 244         if (srcIcon == null) {
 245             return null;
 246         }
 247 
 248         int w;
 249         int h;
 250 
 251         w = srcIcon.getIconWidth();
 252         h = srcIcon.getIconHeight();
 253 
 254         GraphicsEnvironment ge =
 255                 GraphicsEnvironment.getLocalGraphicsEnvironment();
 256         GraphicsDevice gd = ge.getDefaultScreenDevice();
 257         GraphicsConfiguration gc = gd.getDefaultConfiguration();
 258 
 259         // convert to image
 260         BufferedImage iconImage = gc.createCompatibleImage(w, h,
 261                 Transparency.TRANSLUCENT);
 262         Graphics2D g = iconImage.createGraphics();
 263         srcIcon.paintIcon(null, g, 0, 0);
 264         g.dispose();
 265 
 266         // and scale it nicely
 267         BufferedImage scaledImage = gc.createCompatibleImage(scaledW, scaledH,
 268                 Transparency.TRANSLUCENT);
 269         g = scaledImage.createGraphics();
 270         g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
 271                 RenderingHints.VALUE_INTERPOLATION_BILINEAR);
 272         g.drawImage(iconImage, 0, 0, scaledW, scaledH, null);
 273         g.dispose();
 274 
 275         return (Image)scaledImage;
 276     }
 277 
 278     public File createNewFolder(File containingDir) throws IOException {
 279         return null;
 280     }
 281 }