Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Windows 8 Distorts my TrayIcon

Windows 8 appears to make tray icons be 20 x 20 pixels. It seems as though Java still thinks they should be 16 x 16 pixels. This is causing some bad distortion as Java scales things down, and then Windows scales things back up. The following example uses these three images to create three tray icons that look like this (note the distortion):

20x20 green icon20x20 red icon16x16 blue icon

resulting tray.

import java.awt.Image;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;

public class TrayTest
{
    public static void main(String[] args) throws Exception
    {
        final SystemTray tray = SystemTray.getSystemTray();

        TrayIcon trayIcon16 = new TrayIcon(getImage("16pxBlue.png"));
        tray.add(trayIcon16);

        TrayIcon trayIcon20 = new TrayIcon(getImage("20pxRed.png"));
        tray.add(trayIcon20);

        TrayIcon trayIcon20autoSize = new TrayIcon(getImage("20pxGreen.png"));
        trayIcon20autoSize.setImageAutoSize(true);
        tray.add(trayIcon20autoSize);
    }

    public static Image getImage(String resource)
    {
        return Toolkit.getDefaultToolkit().createImage(TrayTest.class.getResource(resource));
    }
}

This is what the whole thing looks like magnified with pixel lines added (opening image in a new tab will give you a clearer view):

enter image description here

My question: How can I prevent Java / Windows 8 from distorting my icons?

like image 604
Lunchbox Avatar asked Sep 17 '13 20:09

Lunchbox


1 Answers

The 16×16 size is apparently hardcoded into the Java TrayIcon implementation. I don't see a way to change it at runtime. From WTrayIconPeer.java:

final static int TRAY_ICON_WIDTH = 16;
final static int TRAY_ICON_HEIGHT = 16;

This needs to be reported as a bug.

As a workaround, using smooth, anti-aliased icons will make the distortion less noticeable.

If you're desperate, you could write (or find?) an alternative implementation of tray icons using JNA or JNI. The code in WTrayIconPeer.java and the corresponding native code in awt_TrayIcon.cpp could serve as a guide. It looks like a lot of work though.

like image 109
Boann Avatar answered Oct 08 '22 22:10

Boann