JDK-8188238 : Access to Windows Large Icons
  • Type: CSR
  • Component: client-libs
  • Sub-Component: javax.swing
  • Priority: P3
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 17
  • Submitted: 2017-10-02
  • Updated: 2021-05-27
  • Resolved: 2021-05-26
Related Reports
CSR :  
Description
Summary
-------
API sun.awt.shell.ShellFolder.getShellFolder(file).getIcon(getLargeIcon) in
the sun package is now considered internal and is not exposed since Java-9 so a replacement API is added to Swing's FileSystemView.

Problem
------
Customers requested ability to query higher resolution icon for files with functionality at least matching the functionality of the now inaccessible API.

Solution
--------

Add a new method to javax.swing.filechooser.FileSystemView that allows querying icon of the specific size.
Method should return the icon of the best available quality based on the requested icon size 
associated with the specified file. Whenever possible we should return the multi resolution icon that can be used
to display said icon on displays with different magnification factors.

Specification
-------------

Webrev: https://openjdk.github.io/cr/?repo=jdk&pr=2875&range=06

    +   /**
    +    * Returns an icon for a file, directory, or folder as it would be displayed
    +    * in a system file browser for the requested size.
    +    * <p>
    +    * Example: <pre>
    +    *     FileSystemView fsv = FileSystemView.getFileSystemView();
    +    *     Icon icon = fsv.getSystemIcon(new File("application.exe"), 64, 64);
    +    *     JLabel label = new JLabel(icon);
    +    * </pre>
    +    *
    +    * @implSpec The available icons may be platform specific and so the
    +    * available sizes determined by the platform. Therefore an exact match
    +    * for the requested size may not be possible.
    +    *
    +    * The icon returned may be a multi-resolution icon image,
    +    * which allows better support for High DPI environments
    +    * with different scaling factors.
    +    *
    +    * @param f a {@code File} object for which the icon will be retrieved
    +    * @param width width of the icon in user coordinate system.
    +    * @param height height of the icon in user coordinate system.
    +    * @return an icon as it would be displayed by a native file chooser
    +    * or null for a non-existent or inaccessible file.
    +    * @throws IllegalArgumentException if an invalid parameter such
    +    * as a negative size or a null file reference is passed.
    +    * @see JFileChooser#getIcon
    +    * @see AbstractMultiResolutionImage
    +    * @see FileSystemView#getSystemIcon(File)
    +    * @since 17
    +    */
    +    public Icon getSystemIcon(File f, int width, int height) {
    +        // implementation omitted
    +        }
    +
         /**
          * On Windows, a file can appear in multiple folders, other than its
          * parent directory in the filesystem. Folder could for example be the
Comments
Moving to Approved.
26-05-2021

Documentation updated after review on github
26-05-2021

> Edge length is >=1 ? How can it be less ? User can request icon of size -1. Since we specified that the valid size is greater than 1we will return null.
21-05-2021

As for the square icons - yes, we imply that the greater dimension is specified so in case of 256x128 icon (which on Windows is simply not a thing, non-square system icons are not supported, but on other systems it might be possible) the 256x256 icon will be returned with the 256x128 bitmap inside and the 256x256 reported size.
21-05-2021

I do not think that throwing an exception is a reasonable here, especially about the size - the size is often calculated and passing a wrong size is always possible. By the way, right now on Windows if user asks for any icon of any positive size we return a multiresolution icon with the bitmap of the maximum available quality and the scaleup size of requested size - so if user for some reason (like printing with ultra-fine quality or something like it) requests 4096x4096 icon - it will be served. And it will only take 64KB of memory to do so because the best quality icon on Windows right now is 256x256. I expect this to follow the suit on other systems too when it will be implemented.
21-05-2021

BTW I think we should throw IllegalArgumentException for sizes <=0, shouldn't we ? And I am not sure why we need to return null for a size that is too big. Just find the closest match. Are you are thinking a developer might overlook that and think "oh some platform might be able to scale arbitrarily, and I could ask for 4096 and then I'll get back the 512x512 icon or whatever is the biggest" Add then be surprised when they got back a massive 4Kx4K icon .. Probably we need a better way to tell the developer what a sensible max size is.
21-05-2021

Some quibbles. I have what I think is better wording for the implSpec part. I think "platform" is more appropriate than implementation since implementation implies we could do anything, whereas I assume we are constrained by the platform. The "maximum size allowed" presumably mean "maximum size available" ? Also this is Java so I changed "pointer" to "reference" in the @return doc The bit about only supporting square icons is weird. I can't make out what you want to say Edge length is >=1 ? How can it be less ? And are you saying we'll crop a 256x128 image ? I doubt you mean that. Do you really mean : The requested size implies a square icon, since width and height cannot be specified independently. In the event that the platform provides icons that differ in width and height, the requested size is used to match ... <pre> 1) width 2) height 3) any icon that most closely matches in either dimension 4) the lesser dimension is always used ? 5) the greater dimension is always used ? </pre> <pre> + /** + * Returns an icon for a file, directory, or folder as it would be displayed + * in a system file browser for the requested size. + * <p> + * Example: <pre> + * FileSystemView fsv = FileSystemView.getFileSystemView(); + * Icon icon = fsv.getSystemIcon(new File("application.exe"), 64); + * JLabel label = new JLabel(icon); + * </pre> + * + * @implSpec The available icons may be platform specific and so the * available sizes determined by the platform. Therefore an exact match * for the requested size may not be possible. * + * The icon returned may be a multi-resolution icon image, + * which allows better support for High DPI environments + * with different scaling factors. + * + * @param f a {@code File} object for which the icon will be retrieved + * @param size width and height of the icon in user coordinate system. + * This API only supports square icons with the edge length + * equals or greater than 1. ^^^^^^^^^^^^ NEEDS DISCUSSION ^^^^^^^^^^^^^ * The maximum size available may be constrained by the platform + * @return an icon as it would be displayed by a native file chooser + * or null if invalid parameters are passed such as a reference to a + * non-existing file or a size outside of supported range. + * @see JFileChooser#getIcon + * @see AbstractMultiResolutionImage + * @see FileSystemView#getSystemIcon(File) + * @since 17 + */ + public Icon getSystemIcon(File f, int size) { + // implementation omitted + } + </pre>
21-05-2021

I missed the place where we said this "As stated in specification allowed parameters are 1 to 256"?
20-05-2021

Moving to Approved.
20-05-2021

> Should getSystemIcon(File f) be deprecated? I do not see why, it is a method to receive the default icon for a file without specifying the size. It uses the same implementing code so the icon returned will be suitable for display in High DPI environment. > Shouldn't Icon getSystemIcon(File f, int size) have an @see/@link to the other method? Added too @see clause > Are icon's necessary square in shape? Yes, we do not support non-square icons > What happens if size is zero or negative? As stated in specification allowed parameters are 1 to 256 and as stated in the @return description is invalid parameters are passed we will return null. > would be a fine @implSpec tag. Added. Has to move example up a notch since all HTML tags such as "pre" got ignored after the spec tags
19-05-2021

Moving to Provisional, not Approved. Code review comments: Should getSystemIcon(File f) be deprecated? Shouldn't Icon getSystemIcon(File f, int size) have an @see/@link to the other method? Are icon's necessary square in shape? What happens if size is zero or negative? The text + * The default implementation gets information from the + * {@code ShellFolder} class. Whenever possible, the icon + * returned is a multi-resolution icon image, + * which allows better support for High DPI environments + * with different scaling factors. would be a fine @implSpec tag.
17-05-2021