I encountered the same issue of needing high-resolution icons. After an hour of digging, I think the answer is quite clear, albeit quite unfortunate.
- There is currently no native library support.
- Native support is expected on Java version 12.
- There is no reliable third-party library anywhere that I can find, even after extensive searching.
A ticket of this issue has already been submitted here on JDK bug system, but it seems pretty low on their priority list.
However, there does seem to be workarounds:
I am assuming you are using Windows. Finding the icon file on Linux is trivial because the icon is stored separately and linked in the desktop entry.
- Extract the icon using a third-party command line exe tool, like this one or this one, to a temporary directory. You can use
Runtime.exec()
.
- Use a .ico reader library like the ones suggested here to read all the image files it contains into
BufferedImage
in a List
.
- Iterate through the list to find the image with highest resolution.
- Delete temporary files.
Update
Just implemented my workaround and it worked. Here's the code snippet. I used iconsext.exe and image4j in my implementation.
// Extract icons and wait for completion.
File iconDir = new File("tempIcons");
String[] iconsextCmd = { "iconsext.exe", "/save", exeFile.getPath(), iconDir.getPath(), "-icons" };
Process iconsextProc = Runtime.getRuntime().exec(iconsextCmd);
iconsextProc.waitFor();
// Get all icons, sort by ascending name, and pick first one.
File[] icons = iconDir.listFiles();
Arrays.sort(icons, (f1, f2) -> f1.getName().compareTo(f2.getName()));
File defaultIcon = icons[0];
// Read images from icon.
List<ICOImage> iconImgs = ICODecoder.readExt(defaultIcon);
// Sort images by descending size and color depth, and pick first one.
iconImgs.sort((i1, i2) -> (i2.getWidth() * i2.getHeight() * 33 + i2.getColourDepth())
- (i1.getWidth() * i1.getHeight() * 33 + i1.getColourDepth()));
BufferedImage awtImg = iconImgs.get(0).getImage();
// Delete temporary icons.
for (File i : icons)
{
i.delete();
}
iconDir.delete();
Throw in some JavaFX code:

Nice and big icons!
The workaround is messy and complicated, I know. And it does negate Java's cross-platform benefits, but to be honest it is the best I can think of. Hope it helps.