Текст Swing выглядит плохо

Я переопределяю метод paintComponent () JCOmponent и рисую текст в окне. Я работаю в Ubuntu и использую шрифт «Ubuntu Mono» (шрифт по умолчанию для текстового редактора Ubuntu). Когда мое приложение Java отображает текст, он выглядит тусклым и расплывчатым. Что я делаю неправильно?

Я рисую текст так:

graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
Font font = new Font("Ubuntu Mono", Font.PLAIN, 18);
fontMetrics = graphics.getFontMetrics(font);
graphics.setFont(font);
graphics.drawString(value, getX(), getY() + fontMetrics.getHeight());

В моем java-приложении это выглядит так:

Текст приложения Java

В текстовом редакторе Ubuntu это выглядит так:

введите описание изображения здесь

Изменить: пострадает ли производительность, если будут использоваться .png изображения вместо drawText()? Это бизнес-приложение, а не игра, требующая плавной анимации.

Изменить: я изменил цвета, чтобы они соответствовали цветам TextEditor, и это на самом деле немного улучшило качество, но символы все еще намного тоньше ... вы почти не видите ".". В gimp я могу воссоздать внешний вид TextEditor, создав текст с правильным шрифтом и сглаживанием.


person Stinky    schedule 14.07.2012    source источник
comment
У меня такое чувство, что, возможно, Java (или, может быть, Swing) просто не имеет того контроля, который мне нужен. Я изменил шрифт в netbeans (использует Swing), чтобы он соответствовал шрифту моего приложения, и он выглядит так же. стон У меня нет расписания в этом проекте, чтобы выучить C ++? Похоже, что все основные браузеры написаны на C ++. Есть предположения?   -  person Stinky    schedule 14.07.2012
comment
Это LayoutTest с использованием TextLayout может оказаться полезным.   -  person trashgod    schedule 15.07.2012
comment
Может быть, это проблема решения. Насколько я помню (прошло некоторое время с тех пор, как я просмотрел этот материал), Java работает с разрешением 72 DPI (или 92 DPI ??)   -  person MadProgrammer    schedule 15.07.2012


Ответы (4)


Прочтите изображение .png и кешируйте его в BufferedImage. Производительность не пострадает - на самом деле использование такого промежуточного изображения дает лучшую производительность, чем рисование текста в первую очередь.

Убедитесь, что вы создали совместимый образ, например:

private Image getCompatibleImage(BufferedImage img) throws IOException {
        GraphicsConfiguration c = GraphicsEnvironment
                .getLocalGraphicsEnvironment().getDefaultScreenDevice()
                .getDefaultConfiguration();

        if (c.getColorModel().equals(img.getColorModel()))
            return img;

        BufferedImage compatible = c.createCompatibleImage(img.getWidth(),
                img.getHeight());
        Graphics cg = compatible.getGraphics();
        cg.drawImage(img, 0, 0, null);
        cg.dispose();

        return compatible;
    }

Это позволит сэкономить на попиксельном преобразовании на некоторых мониторах для повышения производительности.

person LanguagesNamedAfterCofee    schedule 15.07.2012

Как ни странно, я пробовал использовать "Моноширинный" вместо "Ubuntu Mono" с:

graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

и для меня это выглядит достаточно хорошо. Вот что я собираюсь использовать.

person Stinky    schedule 17.07.2012
comment
Спасибо за это, удивительно, какая разница - person smac89; 09.12.2014

Вы не обязательно делаете что-то не так. Из API для RenderingHints (выделено мной):

эти ключи и значения являются подсказками, не требуется, чтобы данная реализация поддерживала все возможные варианты, указанные ниже, или чтобы она могла отвечать на запросы, чтобы изменить выбранный ею алгоритм. Значения различных ключей подсказки могут также взаимодействуют таким образом, что, хотя все варианты данного ключа поддерживаются в одной ситуации, реализация может быть более ограничена при изменении значений, связанных с другими ключами. [отрывок]

Реализации могут полностью игнорировать подсказки, но должны попытаться использовать алгоритм реализации, максимально приближенный к запросу.

person Dan O    schedule 14.07.2012

Вместо того, чтобы заставлять подсказки рендеринга, попробуйте использовать собственные настройки рабочего стола для шрифтов, то есть:

Toolkit tk = Toolkit.getDefaultToolkit();
Map desktopHints = (Map)(tk.getDesktopProperty("awt.font.desktophints"));

...

if (desktopHints != null) {
    graphics.addRenderingHints(desktopHints);
}

(источник - Filthy Rich Clients)

РЕДАКТИРОВАТЬ:

Обязательно попробуйте различные советы по контролю качества отрисовки текста. Вот справочник и примеры.

person tenorsax    schedule 14.07.2012
comment
Хм ... небольшое изменение, но все же намного хуже шрифта TextEditor. - person Stinky; 14.07.2012
comment
@Stinky, ты пробовал GASP или подсказки LCD? - person tenorsax; 14.07.2012
comment
См. stackoverflow.com/questions/179955/ - person Alan Stokes; 15.07.2012
comment
@ Макс. Они очень похожи на VALUE_TEXT_ANTIALIAS_ON. - person Stinky; 15.07.2012