Логин:   Пароль:




Новости
Рассылки
Форум
Поиск


Java
- Апплеты
- Вопрос-ответ
- Классы
- Примеры
- Руководства
- Статьи
- IDE
- Словарь терминов
- Скачать

Мобильная Java
- Игры
- Примеры
- Статьи
- WAP, WML и пр.

JavaScript
- Вопрос-ответ
- Примеры
- Статьи

Веб-мастеринг
- HTML
- CSS
- SSI

Разминка для ума
Проекты
Книги
Ссылки
Программы
Юмор :)




Rambler's Top100

Мобильная Java: СтатьиКак локализовать мидлет

Как локализовать мидлет

Недавно с удивлением для себя обнаружил, что многие J2ME програмисты не используют properties файлы и вставляют строчки прямо в код. После чего имеют большие затруднения связанные с их редактированием и локализацией. Да стандартный J2MЕ не имеет в своем арсенале класс ResourseBundle, но написать свой класс предоставляющий подобные возможности не представляет большого труда.

Итак, давайте напишем такой класс Resourse. У нашего класса будет один конструктор и 3 public метода.

directory - имя директории в jar файле мидлета, в которой находятся ресурсы.
fileName - имя файла.
extenssion - расширение файла.
public Resources (String directory, String fileName, String extenssion)

Теперь перейдем к методам нашего класса.


public boolean load()
public String get (String key)
public void unload()

Метод load находит ресурс файл в jar файле, и загружает его. Если он не может этого сделать возвращает false.
Метод get (String key) возвращает ресурс.
Метод unload() освобождает все связанные c объектом Resources внутренние ресурсы.
Напишем сразу же небольшой мидлет который будет использовать класс Resources

package example;

import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;

import ru.mank.me.util.Resources;

public final class Example extends MIDlet 
                       implements CommandListener
{
  /*===============[ INSTANCE VARIABLES ]=========*/
  private Command exitCommand = null;

  /*===============[ CLASS METHODS ]==============*/
  protected void destroyApp (boolean unconditional)
  throws MIDletStateChangeException
  {
    exitMIDlet();
  }

  private void exitMIDlet()
  {
    notifyDestroyed();
  }

  protected void pauseApp(){}
  protected void startApp()
  throws MIDletStateChangeException
  {
    Resources resources = 
     new Resources ("resources", "mymidlet", "properties");
    Form form;
    if (resources.load())
    {
      exitCommand = 
       new Command (resources.get("exitCommand"), Command.EXIT, 1);
      form = new Form (resources.get ("title"));
      StringItem countryItem = new StringItem
      (resources.get ("country"), resources.get ("countryValue"));
      StringItem townItem = new StringItem
      (resources.get ("town"), resources.get ("townValue"));
      form.append (countryItem);
      form.append (townItem);

      resources.unload();
    }
    else
    {
      form = new Form ("Error");
      exitCommand = new Command ("Exit", Command.EXIT, 1);
      form.append ("Cannot load resource");
    }
    form.addCommand (exitCommand);
    form.setCommandListener (this);
    Display.getDisplay (this).setCurrent (form);
  }

  public void commandAction (Command c, Displayable d)
  {
    exitMIDlet();
  }
  /*============================*/
}

Cоздадим файлы mymidlet.properties и mymidlet_ru.properties и положим их в jar файл мидлета в директорию resources

mymidlet.properties:

exitCommand=Exit
title=Example
country=Country
countryValue=Russia
town=Town
townValue=Pskov

mymidlet_ru.properties:

exitCommand=\u0412\u044b\u0445\u043e\u0434
title=\u041f\u0440\u0438\u043c\u0435\u0440
country=\u0421\u0442\u0440\u0430\u043d\u0430
countryValue=\u0420\u043e\u0441\u0441\u0438\u044f
town=\u0413\u043e\u0440\u043e\u0434
townValue=\u041f\u0441\u043a\u043e\u0432

Файл mymidlet_ru.properties содержит руссифицированную версию представленную в Unicode.

Соберем наш мидлет и загрузим его в телефон. Установим в телефоне английский язык и запустим мидлет (Рис. 1).


Загрузка мидлета UTF-8 в телефон

После этого установим в телефоне русский язык и снова запустим мидлет. (Рис. 2).

Теперь когда нам ясно как можно работать с классом Resources, рассмотрим его по подробней

package ru.mank.me.util;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import java.util.Hashtable;

public class Resources
{
  /*=============[ STATIC VARIABLES ]=============*/
  public static final String LIMITER = "=";
  private static final int BUFFER_SIZE = 300;

  /*=============[ INSTANCE VARIABLES ]===========*/
  private Hashtable hashtable;
  private char [] ac;
  private String fileName = null;
  private String directory;
  private String extenssion = "";
  private String name;
  private boolean load  = false;
  private boolean error  = false;

  /*=============[ CONSTRUCTORS ]=================*/
  public Resources (String directory, String name, 
                          String extenssion)
  {
    this.extenssion = extenssion;
    this.load = false;
    this.name = name;
    this.directory = '/' +
    (directory == null || directory.trim().length() ==
         0? "" : directory + '/');
  }


  /*=============[ CLASS METHODS ]================*/
  public boolean load()
  {
    //Если при предыдущей загрузке была ошибка, 
    //то возвращаем false
    if (error)
    return false;
    InputStreamReader in = null;
    try
    {
      //Получаем InputStream ресурс файла
      InputStream inputStream = getInputStream();
      if (inputStream == null)
      return false;

      //Создаем InputStreamReader
      in = new InputStreamReader (inputStream);

      //Создаем Hashtable в котором будем хранить 
      //содержимое ресурс файла
      hashtable = new Hashtable();
      ac = new char [BUFFER_SIZE];
      String str;


      //Читаем весь файл построчно и заполняем Hashtable
      while ((str = = readLine (in)) != null)
      {
        int len = str.indexOf (LIMITER);
        if (len > 0)
        {
          String key = str.substring (0, len);
          String value = str.substring (len+1);
          hashtable.put (key, value);
        }
      }

      //Закрываем InputStream
      in.close();
      ac = null;
      //Файл был загружен успешно
      load = true;
      return true;
    }
    catch (Exception io)
    {
      //Файл не был загружен успешно
      error = true;
      unload();
      return false;
    }
    finally
    {
      //Закрываем InputStream
      if (in != null)
      try {in.close();} catch (IOException ex){}
    }
  }

  private InputStream getInputStream()
  {
    //Если при предыдущей загрузке была ошибка 
    //то возвращаем null
    if (error)
    return null;
    if (fileName == null)
    {
      //Находим нужный нам файл
      InputStream in = null;
      String locale =
              System.getProperty ("microedition.locale");
      //Читаем свойство microedition.locale, 
      //которое представляет
      //текущий Locale (язык и страна).
      //К примеру если на телефоне текушим 
      //является русский язык, то
      //locale будет равен "ru-RU".
      if (locale != null)
      {
        //Если locale не равен нулю 
        //то заменяем символ '-' на '_'ю
        locale = locale.replace ('-', '_');

        //Создаем fileName с представлением языка и страны
        //например fileName_ru_RU
        fileName = directory + name + "_" +
              locale + "." + extenssion;

        in = this.getClass().getResourceAsStream (fileName);
        if (in != null)
        {
          //Если ресурс найден, то возвращаем InputStream
          return in;
        }
        else
        {
          //Если ресурс не найден то создаем fileName 
          //с представлением языка
          //например fileName_ru
          int i = locale.indexOf ('_');
          if (i != -1)
          {
locale = locale.substring (0, i);
fileName = directory + name + "_" + locale + "." + extenssion;
in = this.getClass().getResourceAsStream (fileName);
if (in != null)
{
  //Если ресурс найден, 
  //то возвращаем InputStream
  return in;
}
          }
        }
      }
      //Если ресурс не найден то создаем
      //fileName без представления языка и страны
      fileName = directory + name + "." + extenssion;
      in = this.getClass().getResourceAsStream (fileName);
      if (in == null)
      {
        //Ресурс не найден, возвращаем null
        error = true;
        unload();
        return null;
      }
      else
      {
        //Если ресурс найден, то возвращаем InputStream
        return in;
      }
    }
    else
    {
      //Если ресурс ранее уже был загружен, 
      //то возвращаем InputStream
      return this.getClass().getResourceAsStream (fileName);
    }
  }

  public String get (String name)
  {
    if (!load)
    {
      //Если файл с ресурсами не был загружен, 
      //то загружаем его
      if (!load())
      {
        //Если файл с ресурсами невозможно загрузить 
        //возвращаем пустую строчку
        return "";
      }
    }
    String str = (String) hashtable.get (name);
    if (str == null)
    {
      //Если ресурс не обнаружен возвращаем пустую строчку
      return "";
    }
    else
    {
      //Ура! Вот ваш ресурс!
      return str;
    }
  }

  public void unload()
  {
    //Если объект Resources нам временно не нужен,
    //освобождаем все связанные с ним ресурсы,
    //позволяя Garbage Collector'у собрать их.
    hashtable = null;
    ac = null;
    if (fileName != null)
    {
      name = null;
      extenssion = null;
      directory = null;
    }
    load = false;
  }

  //Этот метод читает строчку из потока.
  private String readLine (InputStreamReader in)
  throws IOException
  {
    int j = 0;
    StringBuffer buffer = new StringBuffer();
    int r = -1;
    while (j < ac.length && (r = in.read()) > 0 && r != 13)
    ac [j++] = (char)r;

    while (j > 0)
    {
      int copy = -1;
      for (int k = 0; k < j;)
      {
        if (ac [k] == '\\')
        {
          if (k >= BUFFER_SIZE - 6)
          {
copy = k;
break;
          }
          if (ac [k + 1] == 'u')
          {
try
{
  int l = Integer.parseInt (new String (ac, k + 2, 4), 16);
  k += 6;
  buffer.append (new String (new char[]{(char)l}));
}
catch (NumberFormatException ex){}
          }
          else
          {
buffer.append (new String (ac, k, 1));
k++;
          }
        }
        else
        {
          buffer.append (new String (ac, k, 1));
          k++;
        }
      }

      if (r == 13 || r < 0)
      break;
      if (copy != -1)
      {
        int limit = j;
        j = 0;
        for (int i = copy; i < BUFFER_SIZE && i < limit; i++)
        ac [j++] = ac[i];
      }
      else
      j = 0;
      while (j < ac.length && (r = in.read()) > 0 && r != 13)
      ac [j++] = (char)r;
    }
    if (r == -1 && buffer.length() == 0)
    return null;
    else
    return buffer.toString().trim();
  }
}
/*=====================*/

P.S. Прошу прощения за корявость языка, но просто сложно найти к устоявшиимся выражениям на английском языке, подходящий эквивалент на русском.

Автор: Mank
http://www.midlet.ru/


Ален Лиссуар
"WMI: программирование на JavaScript и VBScript"
Подробнее>>
Заказать>>


Кен Арнолд, Джеймс Гослинг, Дэвид Холмс
"Язык программирования Java"
Подробнее>>
Заказать>>

Узнай о чем ты на самом деле сейчас думаешь тут.


[an error occurred while processing this directive]



Apache Struts 2.0.11
Apache MyFaces Trinidad Core 1.2.3.
Sun переводит мобильные устройства с Java ME на Java SE
Хакерская атака!