【问题标题】:Text antialiasing broken in Java 1.7 (Windows)Java 1.7 (Windows) 中的文本抗锯齿功能被破坏
【发布时间】:2013-09-12 12:42:00
【问题描述】:

Swing 组件 Java 1.7 (Windows) 的文本抗锯齿渲染提示似乎已失效。设置KEY_ANTIALIASING 和/或KEY_TEXT_ANTIALIASING 不再影响JLabelJEditorPane 等的显示 - 但实际上我的项目中需要不同的设置。

您可以在此屏幕截图中比较Java 1.6 (jdk1.6.0_45) 和Java 1.7 (jdk1.7.0_40) 中的不同行为,由以下测试程序生成:

左边是Java 1.6,右边是Java 1.7。第一列用Graphics2D.drawString 绘制,第二列用JLabel 绘制。在 Java 1.6 中,呈现提示会影响 JLabel 的显示,而在 Java 1.7 中,所有 JLabel 的呈现方式都相同(带有小数度量的除外)。

您知道如何让抗锯齿提示影响 Java 1.7 中的 Swing 组件吗?

测试程序:

    import java.awt.*;
    import java.util.*;
    import javax.swing.*;

    public class AntialiasMain extends JFrame {
    public AntialiasMain() {
        JPanel panel = new JPanel(new GridLayout(0, 1));
        panel.add(new AntialiasLabel("default", null));

        HashMap<Key, Object> hints = new HashMap<Key, Object>();
        hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
        panel.add(new AntialiasLabel("AA off", hints));

        hints = new HashMap<Key, Object>();
        hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        panel.add(new AntialiasLabel("AA on", hints));

        hints = new HashMap<Key, Object>();
        hints.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
        panel.add(new AntialiasLabel("TextAA off", hints));

        hints = new HashMap<Key, Object>();
        hints.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        panel.add(new AntialiasLabel("TextAA on", hints));

        hints = new HashMap<Key, Object>();
        hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        hints.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        panel.add(new AntialiasLabel("AA+TextAA on", hints));

        hints = new HashMap<Key, Object>();
        hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        hints.put(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
        panel.add(new AntialiasLabel("AA+FracMetr on", hints));

        hints = new HashMap<Key, Object>();
        hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        hints.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
        panel.add(new AntialiasLabel("AA+TextLCD on", hints));

        hints = new HashMap<Key, Object>();
        hints.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
        panel.add(new AntialiasLabel("TextLCD on", hints));

        getContentPane().add(panel);

    }

    class AntialiasLabel extends JLabel {
        private final HashMap<Key, Object>  hints;
        private final String                label;

        private static final String         PALYNDROME          = "The quick brown fox jumped over the lazy dog";

        public AntialiasLabel(String label, HashMap<Key, Object> hints) {
            super(PALYNDROME);
            setForeground(Color.BLACK);
            setBorder(BorderFactory.createEmptyBorder(10, 150, 10, 10));
            this.label = label;
            this.hints = hints;
        }

        @Override
        protected void paintComponent(Graphics g) {
            Graphics2D g2 = (Graphics2D) g;
            if (hints != null)
                g2.setRenderingHints(hints);
            g2.drawString("Setting: " + label, 2, getHeight() / 2 + 5);
            super.paintComponent(g2);
        }
    }

    public static void main(final String[] args) {
        JFrame f = new AntialiasMain();
        f.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        f.pack();
        f.setVisible(true);
    }
}

编辑:系统属性swing.aatextawt.useSystemAAFontSettings 无效。也没有更改Look and Feel

【问题讨论】:

  • 你能用另一个 L&F 试试同样的代码吗?
  • 好主意。 Nimbus、Metal、Windows 和 Substance 的结果相同。

标签: java swing java-2d antialiasing


【解决方案1】:

this answer 中找到了解决方案。更新问题中的代码:

private static final Object AA_TEXT_PROP = getAaTextProperty();

public static Object getAaTextProperty() {

    Object aatext = null;
    try {
        Class<?> c = Class.forName("sun.swing.SwingUtilities2");
        Field f = c.getField("AA_TEXT_PROPERTY_KEY");
        aatext = f.get(null);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return aatext;
}
...

public AntialiasLabel(String label, HashMap<Key, Object> hints) {
    super(PALYNDROME);
    putClientProperty(AA_TEXT_PROP, null);
    ...
}

在 Java 1.7 Windows 上测试。请注意,最近(2015 年 2 月)的 Windows 更新(如 kb3013455)在许多系统上破坏了字体抗锯齿功能。

【讨论】:

  • 是的,这似乎有效。 1.5 年后.. 恭喜!
  • 或者简单地说:putClientProperty(SwingUtilities2.AA_TEXT_PROPERTY_KEY, null);此外,它不再适用于 Java 9。
【解决方案2】:

首先,关于 Swing 组件行为的几点说明:

  • 调用 super.paintComponent() 时调用的 Swing 组件的 UI 委托可以设置它想要的任何呈现提示 - 从外观上看,JLabel 的 UI 委托似乎覆盖了您的
  • 如果您希望使用抗锯齿功能(即,您使用的是远程 X 或类似功能),您可能应该使用专为该用例设计的 MetalLookAndFeel。李>
  • 无法保证任何组件的 UI 委托都不会覆盖您为呈现提示设置的任何内容 - 即您看到的行为是完全合法的

话虽如此,从 JDK 1.6 开始(据我所知,1.7,但没有承诺)您可以通过 undocumented 访问 AWT 和 Swing 使用的默认渲染提示(以及因此不支持)桌面属性

(Map&lt;RenderingHints.Key, Object&gt;)(Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints"));

这是usage example I wrote for NetBeans, circa 2004 - see the getHints() method。它与您所追求的相反,因为它试图强制启用抗锯齿。但是操纵 Map 的内容或替换它,可能会全局更改抗锯齿设置。

【讨论】:

  • 谢谢。 StanislavL 已经提出了这一建议,请参见上面的 cmets。更改 L&F 并没有帮助(通过运行上面的示例代码尝试自己;一次与 1.7,然后与 1.7 进行比较)。
  • 我得到了地图,但它已经包含正确的提示; Motif LAF 只是忽略它☹
【解决方案3】:

我知道这是一个古老的问题,但我遇到了同样的问题。

经过调查,我发现如果在 main() 方法中添加以下代码,代码将按预期工作:

System.setProperty("awt.useSystemAAFontSettings","off");
System.setProperty("swing.aatext", "false");

Java 7 的默认值似乎从两个属性“关闭”更改为“打开”

【讨论】:

    猜你喜欢
    • 2018-11-07
    • 2014-08-21
    • 1970-01-01
    • 2011-01-14
    • 1970-01-01
    • 2014-11-16
    • 1970-01-01
    • 1970-01-01
    • 2011-02-21
    相关资源
    最近更新 更多