6

对于 Swing 组件 Java 1.7 (Windows),文本的抗锯齿呈现提示似乎被破坏了。设置 KEY_ANTIALIASING和/或KEY_TEXT_ANTIALIASING不再影响 , 等的显示JLabel-JEditorPane但实际上我需要在我的项目中进行不同的设置。

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

左侧运行 Java 1.6,右侧运行 Java 1.7

左侧是 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

4

3 回答 3

4

在这个答案中找到了解决方案。更新问题中的代码:

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 )在许多系统上破坏了字体抗锯齿功能。

于 2015-02-18T13:25:45.423 回答
1

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

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

话虽如此,从 JDK 1.6(因此据我所知,1.7,但没有承诺),您可以通过未记录(因此不受支持)的桌面属性访问 AWT 和 Swing 使用的默认呈现提示

(Map<RenderingHints.Key, Object>)(Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints"));

这是我在 2004 年左右为 NetBeans 编写的使用示例 - 请参阅getHints()方法。它与您所追求的相反,因为它试图强制启用抗锯齿。但是操纵它的内容Map,或者替换它,可能会全局改变抗锯齿设置。

于 2013-09-16T19:36:15.593 回答
0

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

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

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

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

于 2015-02-18T12:19:39.843 回答