【发布时间】:2022-01-04 19:02:36
【问题描述】:
当在简单的应用程序下运行并更改字体抗锯齿(WIN+R "sysdm.cpl" -> 系统属性 -> 高级 -> 性能设置 -> 屏幕字体的平滑边缘)时,可以看到 JTextArea 获得错误的字体(如果再次切换抗锯齿,也会保留它):
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class Main
{
public static void main(String[] args)
{
JFrame frame = new JFrame();
JPanel mainPanel = new JPanel();
JLabel label = new JLabel("labelMessage:");
mainPanel.add(label);
final JTextArea textArea = new JTextArea("textAreaMessage")
{
// @Override
// public void setFont(Font f)
// {
// super.setFont(label.getFont());
// }
};
textArea.setEditable(false);
textArea.setOpaque(false);
textArea.setFont(label.getFont());
mainPanel.add(textArea);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setVisible(true);
}
}
仅当取消注释 setFont 的覆盖时,它会像预期的那样工作。
当在那里设置断点时,可以看到当字体抗锯齿发生变化时,会触发一个 AATextListener:
在某些时候安装默认值:
editor.setFont(UIManager.getFont(prefix /*TextArea*/ + ".font"));
所以很清楚为什么会发生,但我不知道如何以一种好的方式解决它。
可能的解决方案:
-
在代码中重写如上所示的方法
-
使用例如
-Dswing.useSystemFontSettings=false(或-Dswing.aatext=true或awt.useSystemAAFontSettings)但是字体看起来很难看,所以如果没有进一步的增强是不可接受的 -
通过 UIManager 设置默认值
-
删除/禁用监听器?似乎是硬编码,不容易做到?
-
或 3. 可能是一个解决方案,但需要在大型遗留应用程序中进行大量工作。
注意:这只是一个简单的例子。在我们的应用程序中,问题要大得多,因为不仅丢失了设置的字体,而且几乎所有东西都丢失了,比如按钮的边框、自定义的 ComponentUI 等。所描述的如何重现它只是为了让它易于重现,这意味着我们遇到了这个例如,也自发地发出问题该应用程序运行了几个小时。然后我们看到一些 Windows 事件正在触发侦听器并破坏了我们应用程序的外观和感觉(当这种情况突然发生时,通常几乎一个小时都没有使用 PC)。
也许我也会在接下来的几天里询问 OpenJDK 社区。如果是这样,我将在此处链接票证 ID。
Windows 版本:Windows Enterprise 10 版本 20H2(内部版本 19042.1348) Java版本:zulu11.50.19-ca-jdk11.0.12-win_x64
【问题讨论】:
-
您可以通过adding a listener 监听
"awt.font.desktophints"属性的更改,该属性的值为RenderingHints Map。见docs.oracle.com/en/java/javase/17/docs/api/java.desktop/java/…。 -
谢谢,看来问题解决了!我用代码示例更新了问题。
-
@ConstantinButzke 您可以保留原始问题,而不是用答案编辑问题,您可以简单地回答自己的问题。这在堆栈溢出中是允许的。如果你愿意,你仍然可以这样做。我建议你这样做。
-
我不确定删除所有现有的桌面提示侦听器是一个好方法。它可能会在其他平台上引起问题,并且在其他版本的 Java 中可能根本无法工作。它当然既没有记录也没有保证。我在想你可以添加自己的监听器,这样你就可以监控变化并相应地调整自己的组件。
标签: java swing fonts antialiasing