1 ноября 2011 г.

中國 или новые приключения Java в Китае


“Never tire to study and to teach others.” —Confucius

Неожиданно появилась третья (и что-то мне кажется, что не последняя) часть саги о путешествии Java по разным странам мира. Ранее были Украина и Азербайджан. Теперь речь пойдет о Китае (насколько я понял, данная проблема касается всех иероглифных языков: китайского, японского и корейского).

Слоган компании Sun Microsystems Oracle по поводу Java все мы хорошо помним "Write once, run anywhere". Действительно, так и происходит: пишешь один раз и с JVM от того же поставщика все работает как и ожидалось на разных ОС. В частности, наши продукты активно используются под Windows и Linux в разных странах.

И вот пригласили нас на китайский рынок. Тема интересная и большая: локализация ПО, подготовка документации и т.д.

Переводчики закончили с текстами, добавили их в ПО, запускаем и видим квадратики вместо иероглифов. После поисков виноватых и наказаний непричастных выяснили, что дело в Look&Feel, который мы использовали. Он де совместим с иероглифами только традиционного китайского и только под Linux. Ладно, Бог с ним. Перешли на другой L&F и все как будто бы наладилось. Квадратиков стало поменьше, но они по прежнему остались! Эмпирическим путем установили, что квадратики появляются только под Windows и только в момент когда идет изменение шрифта (стиль или размер).

В общем, не буду тянуть - Windows L&F очень (очень-очень-очень-очень) странно себя ведет с иероглифами:
  1. После его установки (иногда?) системный шрифт меняется на Tahoma, а иногда остается Dialog.
  2. Если шрифт остается Dialog, то иероглифы отображаются, но, в общем и целом, интерфейс начинает выглядеть "по уродски" (технический термин).
  3. Если шрифт становится Tahoma, то он может даже покажет Вам иероглифы, но вот малейшие с ним манипуляции приводят к квадратам (так и хочется не к месту вспомнить Малевича).
    В нашем случае вот такой вот код безбожно "квадратит": label.setFont(label.getFont().deriveFont(Font.BOLD));
И на сладкое, как это "лечится":
  1. Заменой L&F'a на какой-то иероглифо совместимый аналог. Важно его проверить под всеми ОС с которыми Вы планируете использовать свой продукт, а то могут быть "сюрпризы".
  2. Если это в силу каких-то причин сделать не возможно и нужно "жить" с "родным" Windows L&F, есть секретный слабо документированный параметр (точнее переменная окружения) swing.useSystemFontSettings. Нашел на сайте IBM JDK упоминание, что этот параметр по-умолчанию включен и он влияет на использование системных шрифтов для Windows L&F вместо "родных" шрифтов Java ("From v1.4.1 onwards, by default Swing programs running with the Windows® Look and Feel render with the system font set by the user instead of a Java-defined font. As a result, fonts for v1.4.1 differ from those in prior releases. This option addresses compatibility problems like these for programs that depend on the old behavior. By setting this option, v1.4.1 fonts and those of prior releases will be same for Swing programs running with the Windows Look and Feel."). На сайте Sun Oracle о нем как бы тоже говорят, но больше в контексте, что он существует, чем в контексте, а что он собственно делает.
Итак, для того чтобы в Windows L&F включить "совместимость" с иероглифами достаточно:
  1. Задать переменную окружения ОС (sic!) swing.useSystemFontSettings и поставить ей значение false (правда неожиданно :)?
  2. Или задать ее значение программно:
    System.setProperty("swing.useSystemFontSettings", Boolean.toString(false));
  3. Или любыми другими способами передать значение этой переменной в JRE. Например, в качестве параметра запуска -Dswing.useSystemFontSettings=false
К сожалению, после всех этих манипуляций Ваш продукт будет выглядеть не столь красиво :(.

P.S. Для полноты картины все же поясню, что "корень зла"  - это шрифт Tahoma, который не полностью совместим с иероглифами. Т.е. есть еще один вариант решения данного вопроса: глобальная замена шрифта Tahoma на более приемлемый.

Комментариев нет:

Отправить комментарий