Skip to main content

Multi-resolution or resolution independent Icon class

11 replies [Last post]
swpalmer
Offline
Joined: 2003-06-10

Are there plans for such a thing in Java 7?

It might help with things like http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5097852

File Icons on Windows and Mac are provided in several sizes by the native platform, yet there is only a way to get the small icons via Java. The Icon class in Java doesn't seem to support multiple resolutions.

I think we really need this to integrate properly on the client and make professional looking desktop apps.

I know some people have been working with SVG for some resolution independent things... but that doesn't solve this problem of getting at the 16x16, 32x32, 64x64, 128x128, etc icons that are available from the native icon files of the operating system.

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
mthornton
Offline
Joined: 2003-06-10

The size of a multi resolution icon depends on the surface on which it is rendered. The Icon class has methods for width and height which are independent of display surface (and rescaling the bitmaps to exactly match the size would probably result in poor images). So, I think, new methods are unavoidable.

campbell
Offline
Joined: 2003-06-24

Hi Scott,

The short answer is yes, support for multi-res icons (both system- and user-provided) is on the table as part of the overall "HiDPI" feature for JDK 7. The JDK 7 feature list still isn't set in stone, which is one reason why we haven't blogged much about this to date, but multi-res icons (and image resources in general) is something I've investigated. The closest thing I have on the subject is a comment I made on Kirill's blog a couple months back:
http://weblogs.java.net/blog/kirillcool/archive/2007/03/java_on_the_des....

There are actually a couple separate-but-related issues here... One is that we need a multi-res aware Icon class that is capable of pulling a resource (from disk, or memory) with the appropriate resolution depending on the current screen DPI where it is to be rendered. Another is that we need finer grained control over the icon sizes that are commonly used (e.g. new constants in the Action class). Another is that we need the ability for the L&F to provide a set of icons (especially important for the GTK L&F, because an app that doesn't use theme-provided icons at the appropriate sizes will look horribly out of place). SVG is one possible way that designers might provide res-independent icons, but more realistically we need to support a mixture of both vector and raster artwork. Vector art is great for larger sizes (because you only need to provide one definition), but in practice icon designers typically need to provide separate hand-tweaked raster variants for smaller sizes. My prototype did allow for this mixture, but the question of which formats to support is a tricky one. Multi-res TIFF is a good choice for multi-part raster icons, and one that Apple seems to be pushing for their developers; SVG is a decent vector format, with an iffy toolset. It's still up in the air whether we want to support such formats in the JDK, but we should have a better answer for you in the coming weeks.

I think I should probably whip up a blog about this sometime in the near future.

Thanks,
Chris

swpalmer
Offline
Joined: 2003-06-10

Thanks for the info Chris.

As far as multi-res TIFF goes... I'm not thrilled with the idea (despite being a big fan of OS X). Not that it doesn't work, but what do you use to make them? The are far too many graphics file formats in the world and I would rather let TIFF go the way of the Dodo. If providing raster images I would stick with the established pattern for the JFrame icon and go with a list of images. That way any format already supported by the built-in ImageIO loaders can be used, regardless of whether the format supports multiple resolutions in one file.

I don't think direct support of any particular vector format is necessary in the beginning... so long as the interfaces are there such that an Icon sub-class can render with any one of them. E.g. first we can use any custom painting code and within that make use of the existing SVG libraries for Java to draw the icon at the needed size. Much like what Kirill has started.
In fact, we could use the SVG to Java2d source conversion tool that Kirill has done to just generate the bulk of a paint method for the icon. That could eliminate the need to parse SVG at runtime in many cases.

Perhaps if something were to be built-in for vector support it could be a bitmap caching mechanism to keep UI painting speedy when the images will be drawn at the same size most of the time. That will save every developer from wanting/needing to provide that sort of thing in each of their vector-icon implementations, and it could likely be reused all over the place. I'm sure that Swing already makes use of some image caching (beyond the existing back-buffer).. pulling that out into something that everyone can make use of would be cool.

kirillcool
Offline
Joined: 2004-11-17

I already have something along this lines in [1] and [2]. The first class uses Batik and a thread pool to asynchronously load SVG images. Once an image is loaded, it's stored in a cache for subsequent use (at the same resolution). The second class implements the ResizableIcon interface and provides an option to resize the icon (duh). In addition, it implements the AsynchronousLoading interface, allowing the background loading of SVG images - the UI stays responsive (although without icons), while SVG images are loaded in background. Once an image is loaded, an event is fired, and the control repaints itself (with the newly loaded image).

I'm sure there could be a lot of improvements here, but i tried it on a UI with about 20 SVG icons, and the overall performance is nice - UI starts up immediately, and the icons are loaded and shown after the UI becomes interactive and responsive.

The above uses Batik online, and another option is to use the SVG to Java2D transcoder that creates Java2D painting corresponding to the original SVG. The generated class contains a single paint(Graphics2D) method, and before calling it you can apply any transformation (scale, rotate, shear, ...). The result is resolution-independent and doesn't require bundling Batik. The size of the original compressed SVG and the size of the compiled compressed Java2D class are pretty much the same. You don't pay for loading the SVG, but you pay for loading the class. Last thing - the transcoded class requires JDK 6.0 since SVG makes extensive use of multi-stop linear gradient and radial gradient - classes that are available only under JDK 6.0.

Of course, icons are only one part of resolution-independent UIs. Don't forget about fonts, insets, borders, layout margins and much more.

Thanks
Kirill

[1] https://flamingo.dev.java.net/source/browse/flamingo/src/org/jvnet/flami...
[2] https://flamingo.dev.java.net/source/browse/flamingo/src/org/jvnet/flami...

swpalmer
Offline
Joined: 2003-06-10

> Of course, icons are only one part of
> resolution-independent UIs. Don't forget about fonts,
> insets, borders, layout margins and much more.

Yes, of course. My immediate need was a way to get at the larger System icons for various files. Something that would probably go into FileSystemView.. but then I started thinking about what the new method would return.

i30817
Offline
Joined: 2006-05-02

I think that the problem is that many OS don't support SVG for example. So even if the setIcon api accepted SVG, many OS wouldn't be able to use them. A possible solution is on those places to use a SVG renderer to take a snapshot of the icon on the requested dimensions and use that.

swpalmer
Offline
Joined: 2003-06-10

This has nothing to do with the OS supporting SVG. SVG support is available from a few Java libraries so support doesn't have to be in the OS.. but that is still irrelevant.

All three major OS's support icons larger than can be retrieved via any Java API I know of and the Icon class itself lacks any sub-class that would hold a multi-resolution icon like those found on Windows and Mac systems. The you would have to roll your own or make separate icon objects for each size.

Btw..what setIcon API are you referring to? I'm talking about getting and using existing icons from the OS. Such as you find in the Windows native file chooser when using selecting the Icon view. (A view that is missing from the Windows L&F for Java's JFileChooser - it's a bug, but Sun won't admit it - they call it an RFE. I say where the System L&F doesn't match the system it is a bug.)

i30817
Offline
Joined: 2006-05-02

I'm refering to the JFrame setIcon method.

swpalmer
Offline
Joined: 2003-06-10

Ah, good point.
Though it appears that it was solved already by a different means:

This the fix in Java 6:

java.awt.Window.setIconImages(List icons);

I'm not thrilled with that fix. It takes Images not Icons as it should have from the beginning.. but I guess there are performance reasons, particularly when the frame isn't L&F decorated, so I can understand why it was done with Images. But it also means this multi-resolution issue has to be solved over and over again for any API that needs or supplies icons at multiple resolutions.

i30817
Offline
Joined: 2006-05-02

I would guess that it would be smarter to provide a multi resolution icon. What happens in a hypothetical OS that requests another icon size?

This i think is one of the problem points in the native-to-java land. Java is just implementing and using the interfaces of the OS, and that is propagated into the API (where it suppostly is set in stone, not that i agree with that, refactor swing ftw). When the sane way to fix this would be to provide a api that takes and independent largish image or svg and scale it to whatever the OS ask, and if it indeed asks for SVG use that. Not that i think sgv is a standard "now". Adapt the general api to the OS don't propagate it to us.

jimmydexo
Offline
Joined: 2012-05-14

We are offering best embroidery digitizing services in the market with our massy experience of over 50,000 designs , thus if you are looking for hats logo , jackets embroided designs or official logos , determine your item with galaxy digitizing , visit our official website for your scoop of detail.