FileIcon Demo

What Is It

The FileIcon is an abstract class creates a javax.swing.Icon for a File.

A file icon is a small (usually about 16x16) icon you can place next to a file name. Usually all files with the same file extension share the same file icon.

An "icon" is different from a "thumbnail". (A thumbnail is an image that is a rendering of a specific file.) And sometimes the word "preview" also carries special implications of interactivity (for ex: a video). So "icon", "thumbnail" and "preview" are all separate buzzwords.

How To Use It

The simplest one-line invocation resembles:

Icon icon = FileIcon.get().getIcon(file);

How It Works

Each subclass is responsible for deciding how to identify the appropriate icon. And the FileIcon class has a static getter/setter method for maintaining the active default FileIcon on a given system.

Discussion

Implementations

There are currently 2 subclasses of FileIcon. (There used to a 3rd that involved reflection, but in accordance with Java guidelines I'm trying to phase out reflection.)

Implementation #1: FileSystemViewFileIcon

This implementation uses FileSystemView, and it resembles:

public class FileSystemViewFileIcon extends FileIcon {
	@Override
	public Icon getIcon(File file) {
		FileSystemView fsv = FileSystemView.getFileSystemView();
		Icon icon = fsv.getSystemIcon(file);
		if (icon != null)
			return icon;
		return super.getDefaultIcon(file);
	}
}

This looks like it should be the ideal way to go, because it's so clean/direct. But on Mac it only ever returns a generic file or folder icon. I tried rummaging through the source code for FileSystemView (and related classes) to see if I could modify (hack) it without reflection, but there aren't a lot of entry points.

Implementation #2: FileViewFileIcon

This implementation uses a JFileChooser's FileView, and it resembles:

public class FileViewFileIcon extends FileIcon {
	FileView fileView;
	public FileViewFileIcon() {
		JFileChooser chooser = new JFileChooser();
		fileView = chooser.getUI().getFileView(chooser);
	}

	@Override
	public Icon getIcon(File file) {
		return fileView.getIcon(file);
	}
}

I don't like that this is so indirect and clunky. Sometimes creating a JFileChooser is not trivially cheap, either. But on Mac: this works great. It returns scalable icons for most every file type.

On Windows: both this approach and the FileSystemView approach produce unscaleable (kind of crappy/pixelated) 16x16 icons. But today as I wrote this I saw emails trickle in about a pull request to update this in future Java versions, so that's exciting.

Scaling

This demo includes an option to scale the icon.

On Mac the icons we get back are high-resolution, so they can scale to most any size with great clarity.

On Windows the icons are not (yet) high-resolution. (Although in a future Java release that should change.) So if you want a universal cross-platform approach: you ought to just stick with the icon's default size. (And even that, unfortunately, will look pixelated on a high-resolution monitor on Windows.)