6

Swing コンポーネント Java 1.7 (Windows) では、テキストのアンチエイリアシング レンダリング ヒントが壊れているようです。KEY_ANTIALIASINGand/or を設定 しても、 、 などKEY_TEXT_ANTIALIASINGの表示には影響しませんが、実際にはプロジェクトで別の設定が必要です。JLabelJEditorPane

Java 1.6以下のテスト プログラムで生成されたこのスクリーンショットで、 (jdk1.6.0_45) とJava 1.7(jdk1.7.0_40)の異なる動作を比較できます。

左側は Java 1.6 で実行、右側は Java 1.7 で実行

左側が Java 1.6、右側が Java 1.7 です。最初の列は で塗りつぶされGraphics2D.drawString、2 番目の列は で塗りつぶされ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 でテスト済み。kb3013455などの最近 (2015 年 2 月) の Windows アップデートにより、多くのシステムでフォントのアンチエイリアスが壊れていることに注意してください。

于 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 に答える