gpt4 book ai didi

java - JOptionPane 图标在 Windows 10 中被裁剪

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:24:49 24 4
gpt4 key购买 nike

我正在使用以下代码在 Java Swing 中显示错误对话框:

JOptionPane.showMessageDialog(null, "Arquivo de imagem não encontrado. Por gentileza, altere o caminho do arquivo.", "Erro",  JOptionPane.ERROR_MESSAGE);

使用 Windows 10 默认外观:

UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

但是图标看起来被裁剪了,像这样:

Dialog with cropped icon

关于如何解决这个问题有什么想法吗?

这是 SSCCE:

import javax.swing.JOptionPane;
import javax.swing.UIManager;

public class SSCCE {
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
JOptionPane.showMessageDialog(null, "Error message", "Error", JOptionPane.ERROR_MESSAGE);
} catch (Exception e){
e.printStackTrace();
}
}

}

最佳答案

看起来 Oracle 终于注意到了这一点 will fix it in JDK 9 ,但对于那些不愿意提供自定义图标的人来说,目前这里有一个 qiuck、hacky 和 ​​Windows 相关的解决方案。

在调用 UIManager.setLookAndFeel() 之后插入此代码:

try
{
String[][] icons =
{
{"OptionPane.errorIcon", "65581"},
{"OptionPane.warningIcon", "65577"},
{"OptionPane.questionIcon", "65579"},
{"OptionPane.informationIcon", "65583"}
};
//obtain a method for creating proper icons
Method getIconBits = Class.forName("sun.awt.shell.Win32ShellFolder2").getDeclaredMethod("getIconBits", new Class[]{long.class, int.class});
getIconBits.setAccessible(true);
//calculate scaling factor
double dpiScalingFactor = Toolkit.getDefaultToolkit().getScreenResolution() / 96.0;
int icon32Size = (dpiScalingFactor == 1)?(32):((dpiScalingFactor == 1.25)?(40):((dpiScalingFactor == 1.5)?(45):((int) (32 * dpiScalingFactor))));
Object[] arguments = {null, icon32Size};
for (String[] s:icons)
{
if (UIManager.get(s[0]) instanceof ImageIcon)
{
arguments[0] = Long.valueOf(s[1]);
//this method is static, so the first argument can be null
int[] iconBits = (int[]) getIconBits.invoke(null, arguments);
if (iconBits != null)
{
//create an image from the obtained array
BufferedImage img = new BufferedImage(icon32Size, icon32Size, BufferedImage.TYPE_INT_ARGB);
img.setRGB(0, 0, icon32Size, icon32Size, iconBits, 0, icon32Size);
ImageIcon newIcon = new ImageIcon(img);
//override previous icon with the new one
UIManager.put(s[0], newIcon);
}
}
}
}
catch (Exception e)
{
e.printStackTrace();
}

为什么这行得通

在 Windows 上,提供给应用程序的图标已按当前 DPI 设置缩放(96 = 无缩放,120 = +25%,144 = +50%)。不幸的是,Java 总是假定图标的大小为 16x16 或 32x32,但事实并非如此。上面的代码利用 Java 使用的本地方法 sun.awt.shell.Win32ShellFolder2.getIconBits() 来获取操作系统图标,但提供了适当的大小。这种方法将来可能无法使用,因为 Win32ShellFolder2 不是 API 的一部分,可能会被修改或完全删除,但到目前为止,这是保留 native 图标的唯一方法。

关于java - JOptionPane 图标在 Windows 10 中被裁剪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33926645/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com