Java

         

Java


Многие связывают неправильный вывод русских букв с неправильной установкой шрифта. Мне кажется, это связанно с тяжким опытом программирования на Windows 3.x, где основная причина действительно была в этом. В Java всё сложнее и редко действительно связанно со шрифтами. Я не разбирался со специфическими настройками броузеров, т.к. ещё не писал апплетов, только приложения, но думаю в последних версиях в этом плане всё нормально.

Где же действительно лежат наибольшие подводные камни? В основном это связанно с неправильной перекодировкой символов. Часть этих проблем и методы их решения описаны выше. Если у Вас все преобразования выполняются корректно, и для вывода используется шрифт Unicode, то есть очень большой шанс, что Ваша программа будет работать правильно.

Если проблемы всё же остались, тут нужно выяснить, где они возникают. Попробуйте запустить приложение под разными JVM, под разными платформами, на разных броузерах.

Если программа не работает нигде - значит проблема только в ней и в ваших руках. Внимательно перечитайте всё, что было написано выше, и ищите. Если же проблема проявляется только в конкретном окружении - значит дело, скорей всего в настройках. Где именно - зависит от того, какой графической библиотекой Вы пользуетесь. Если AWT - помочь может правильная настройка файла font.properties.ru. Пример корректного файла можно взять из Java 2. Если у Вас нет этой версии, можете скачать его с данного сайта: , . Если у Вас установлена русская версия OS - просто добавьте этот файл туда, где лежит файл font.properties. Если же это англицкая версия, то нужно, или дополнительно сменить текущий язык при помощи задания настройки -Duser.language=ru или переписать этот файл вместо font.properties. Этот файл задаёт используемые шрифты и кодовые страницы.

С библиотекой Swing всё проще - в ней всё рисуется через подсистему Java2D. Надписи в стандартных диалогах (JOptionPane, JFileChooser, JColorChooser) переделать на русский очень просто - достаточно лишь создать несколько файлов ресурсов. Я это уже проделал, так что можете просто взять готовый и добавить его в свой CLASSPATH. Единственная проблема, с которой я столкнулся - в версиях JDK начиная с 1.2 rc1 и по 1.3 beta, русские буквы не выводятся под Win9x при использовании стандартных шрифтов (Arial, Courier New, Times New Roman, etc.) из-за ошибки в Java2D. Ошибка весьма своеобразна - со стандартными шрифтами изображения букв отображаются не в соответствии с кодами Unicode, а по таблице Cp1251 (кодировка Ansi). Эта ошибка зарегистрирована в BugParade под номером . По умолчанию в Swing используются шрифты, задаваемые в файле font.properties.ru, так что достаточно заменить их другими - и русские буквы появляются. К сожалению, набор рабочих шрифтов небольшой - это шрифты Tahoma, Tahoma Bold и два набора шрифтов из дистрибутива JDK - Lucida Sans * и Lucida Typewriter * (). Чем эти шрифты отличаются от стандартных - мне непонятно.

Начиная с версии 1.3rc1 эта проблема уже исправлена, так что можно просто обновить JDK. Так же надо учесть, что с оригинальной версией Win95 поставляются шрифты, не поддерживающие Unicode - в этой ситуации можно просто скопировать шрифты из Win98 или WinNT.

Если же вам, кровь из носу, нужно использовать стандартные шрифты, работая в JDK 1.2, то можно компенсировать этот глюк, перекодировав строки текста непосредственно перед выводом. Сделать это можно, например, так:


public static String convertToWin9x(String s) { byte[] bb; try { bb = s.getBytes("Cp1251"); } catch( java.io.UnsupportedEncodingException e ) { return s; } char[] cb = new char[bb.length]; for(int i=0; i < bb.length; i++) { cb[i] = (char)( bb[i] & 0x00FF ); } return new String(cb); }

Но только не забудьте - этот код будет работать только под Win9x и Sun JDK/JRE 1.2.

По поводу компилятора jikes. Как мне рассказали в конференции по Java (fido7.ru.java) при использовании этого компилятора русские буквы тоже появляются. Это на самом деле классический пример того, как один глюк компенсирует другой - jikes просто не учитывает кодировку исходников. Того же эффекта можно добиться, если указать javac кодировку ISO-8859-1 (Latin1) в ключике -encoding. Если при этом в исходниках русские символы записаны в кодировке Cp1251, то тем самым они вместо диапазона 0x400-0x4ff (стандартный диапазон Unicode для кириллицы) попадают в диапазон 0x80-0xff. Из-за вышеупомянутого глюка в среде Win9x кириллица в стандартных шрифтах отображается как раз в этом диапазоне и русские буквы появляются. Если же попробовать запустить программу в другой среде (например, в WinNT) - русских букв не будет, так как там этот глюк отсутствует.

Аналогично на подобную компенсацию можно нарваться, если поменять региональные настройки с русских на буржуйские. При этом, кроме всего прочего, меняется и кодировка по умолчанию (file.encoding) - вместо 1251 становится 1252. Это приводит к тому, что, если при чтении файлов кодировка не была явно указана (и при компиляции не задавался ключик -encoding), то русские буквы переезжают в диапазон 0x80-0xff и создаётся впечатление нормальной работы. Разницу можно заметить на преобразованиях регистра и сортировках через java.text.Collator - они будут выполняться неверно. А если были использованы строковые константы - то на других платформах вы увидите только кракозяблы.

Ещё один способ - скачать версию Swing для JDK 1.1 и запускать приложение из под Microsoft JVM - там всё выводится корректно. Только не забудьте обновить MS JVM - те версии, что идут в комплекте с IE 4.x не совсем корректно работают. С сервера Microsoft можно скачать свежую версию, например 5.00.3240 - с ней всё ОК.

Кстати, по поводу MS JVM. Непонятно по каким соображениям, но в ней отсутствуют все файлы кодировок русских букв, акромя Cp1251 (наверное, они таким образом пытались уменьшить размер дистрибутива). Если Вам нужны другие кодировки, например, Cp866, то нужно добавить соответствующие классы в CLASSPATH. Причём классы от последних версий Sun JDK не подходят - у Sun-а уже давно изменилась их структура, поэтому последние версии классов с Microsoft-ом не стыкуются (у MS осталась структура от JDK 1.1.4). На сервере Microsoft, в принципе, лежит полный комплект дополнительных кодировок (страница , ссылка "Additional I/O libraries"), но там файл размером около 3 метров, а их сервер докачку не поддерживает :-). Мне удалось таки выкачать этот файл, я его перепаковал jar-ом, можете взять его .



Содержание раздела