Сглаживание текста в Java 1.7 (Windows)

сглаживающие подсказки рендеринга для текста кажутся сломанными для компонентов Swing Java 1.7 (Windows). Настройка KEY_ANTIALIASING и/или KEY_TEXT_ANTIALIASING не влияет на отображение JLabel, JEditorPane, etc. - но на самом деле мне нужны разные настройки в моем проекте.

вы можете сравнить различное поведение в Java 1.6 (jdk1.6.0_45) и Java 1.7 (jdk1.7.0_40) на этом скриншоте, произведенном с помощью тестовой программы ниже:

Left side run with Java 1.6, right side with Java 1.7

левая сторона Java 1.6, правая сторона-Java 1.7. Первая колонка окрашена в Graphics2D.drawString, второй -JLabel. В Java 1.6 подсказки рендеринга влияют на отображение JLabel, тогда как в Java 1.7 все JLabels отображают то же самое (за исключением одного с дробными метриками).

знаете ли вы, как я могу иметь подсказки сглаживания влияют на компоненты Swing в Java 1.7?

тестовая программа:

    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.aatext и awt.useSystemAAFontSettings нет эффекта. Ни изменение Look and Feel.

3 ответов


найдено решение в ответ. Обновить код в ваш вопрос:

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) обновления Windows, как kb3013455 сломали шрифт сглаживания на многих системах.


во-первых, несколько пунктов о поведении компонентов Swing:

  • делегат пользовательского интерфейса для компонента Swing, который вы вызываете при вызове super.paintComponent() может настроить любые подсказки рендеринга, которые он хочет-похоже, что делегат UI для JLabel из внешнего вида переопределяет ваш
  • если вы хотите не чтобы использовать сглаживание (т. е. вы используете удаленный X или аналогичный), вы, вероятно, должны использовать MetalLookAndFeel, который был разработан с которых в разум.
  • нет никакой гарантии, что делегат UI для любого компонента не переопределит все, что вы установили для рендеринга подсказок-т. е. поведение, которое вы видите, совершенно законно

это, как говорится, начиная с JDK 1.6 (и, следовательно, насколько я знаю, 1.7, но никаких обещаний), вы можете получить доступ к подсказкам рендеринга по умолчанию, используемым AWT и Swing через без документов (и поэтому не поддерживается) рабочий стол собственность

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

здесь пример использования я написал для NetBeans, около 2004-см. getHints() метод. Он делает противоположное тому, что вам нужно, поскольку он пытается заставить сглаживание быть включенным. Но манипулировать содержимым этого Map или его замена может работать для глобального изменения настроек сглаживания.


Я знаю, что это древний вопрос, но я столкнулся с той же проблемы.

после исследования я обнаружил, что если вы добавляете следующее к методу main (), код работает так, как ожидалось:

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

Кажется, что значения по умолчанию для Java 7 изменились с обоих свойств " off "на оба "on"