系统托盘图标显示失真。

19

我正在尝试使用Java将图标添加并显示到系统托盘。然而,该图标通常要么太小,要么在某些区域被裁剪掉。 如果你没看出来的话,它是从左数第二个。

我做错了什么?如何让这个图标完全显示?系统托盘中使用的标准图标大小是多少?

编辑:我正在使用AWT SystemTray和TrayIcon。

4个回答

31

当你从磁盘中检索到实际的图像资源后,你可以创建一个“假”的图像并获取其宽度来将其调整为所需的大小。

我发现这比使用setImageAutoSize(true)方法更好,因为该方法不会使图像平滑缩放。

BufferedImage trayIconImage = ImageIO.read(getClass().getResource("/path/to/icon.png"));
int trayIconWidth = new TrayIcon(trayIconImage).getSize().width;
TrayIcon trayIcon = new TrayIcon(trayIconImage.getScaledInstance(trayIconWidth, -1, Image.SCALE_SMOOTH));

1
+1 参考精美手册,我认为楼主需要把它作为首要选择。 - Andrew Thompson
很抱歉,在Linux上添加透明背景图片无法工作。 - Gopal00005
1
您可以使用SystemTray.getSystemTray().getTrayIconSize()获取图标的正确尺寸,而不必创建一个虚假的图标。 - Gui Meira

9
根据 TrayIcon.setImageAutoSize(boolean)
设置自动调整大小属性。自动调整大小决定了托盘图标上图像的空间是否被自动调整大小来适应图像。默认情况下,自动调整大小属性被设置为 false。
如果自动调整大小为 false,并且图像大小与托盘图标空间不匹配,则该图像将按原样绘制在该空间内 - 如果图像大于分配的空间,则会被裁剪。

5
+1 … 尽管最简单的解决方案是将托盘图标设置为自动调整大小,但不幸的是,在内部,它似乎使用一种不平滑的算法,大多数人都会发现在生产使用中无法接受。自动调整大小的图像将不平滑且具有锯齿状边缘。我怀疑这是出于性能原因而这样做的。我通常会手动调整大小:https://dev59.com/Q2ct5IYBdhLWcg3wLqjw#12287388 - Redandwhite
1
点赞,因为对于 Windows,我已将此值默认为 true,这可以解决 HiDPI 上的缩放问题。不幸的是,在 Windows HiDPI 上,图标大小被错误地报告为 16x16,所以接下来,我必须检测屏幕缩放并将乘数应用于图标尺寸,然后选择正确的图标大小。 - tresf

9
为了以最佳尺寸显示图标,您需要手动调整大小以达到正确的尺寸。这个正确的尺寸在不同操作系统和偏好之间可能会有所不同,因此Java提供了一种获取任务栏图标尺寸的方法,在您的示例图像中为16x16。
if (SystemTray.isSupported()) {
    SystemTray tray = SystemTray.getSystemTray();
    Dimension trayIconSize = tray.getTrayIconSize();
    // resize icon image to trayIconSize
    // create your tray icon off of the resized image
}

调整图像大小非常简单;这里有一个不错的教程 - FThompson
1
我的任务栏上16x16看起来太小了。 - Ali
根据您问题中的图像,16x16是您操作系统托盘图标的大小。SystemTray#getTrayIconSize()返回什么值来表示您的托盘图标大小? - FThompson
如果图像文件是gif格式的,会对实际情况造成破坏吗?@Ali - gumuruh

2

我将一些答案结合起来,制作了我正在使用的代码。

这会从100x100的png文件中生成一个外观良好的系统托盘图标。

值得注意的是,在Retina MacBook上,缩小后的图标看起来更糟。因此,我在其他地方进行检查,如果它正在运行在Mac上,则不适用此代码。

public Image imageForTray(SystemTray theTray){

    Image trayImage = Toolkit.getDefaultToolkit().getImage("my100x100icon.png");
    Dimension trayIconSize = theTray.getTrayIconSize();
    trayImage = trayImage.getScaledInstance(trayIconSize.width, trayIconSize.height, Image.SCALE_SMOOTH);

    return trayImage;
}

1
这可能略微偏题,但我建议使用基础图标大小为2的倍数(128x128已被证明效果良好)。通常,图标大小是基于2的倍数,这将允许图像通过整数缩放进行处理。这通常比分数缩放看起来更好(除非您有非常大的图像)。另一个不错的选择是96x96像素,它具有许多“有用”的除数。 - mzuther

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接