2

My Java ME MIDlet allows its user to change the language of the Midlet.
My code handles the internationalization, and it works fine for left-to-right languages.
But when the user changes the language to Right-To-Left language, the correct strings are being displayed but the screens remain left-justified.

In other words, the phone's locale is en_US and I don't want to change it.
I just want to change my MIDlet's locale.
What's the simplest way to dynamically change all the screens of the MIDlet to right-justify their content?
I don't mind if the solution involves having the user restart the application.
I also don't mind if the solution is proprietary to Nokia phones if there is no Java ME solution.

gnat
  • 6,213
  • 108
  • 53
  • 73
inor
  • 2,781
  • 2
  • 32
  • 42

1 Answers1

1

Assuming you are using LCDUI, by default StringItems and so on will be given a default layout based on the phone's locale. i.e. Item.LAYOUT_DEFAULT, this means a phone with an en_US locale will display items left to right whereas a phone with an ar_EG locale will display texts right to left.

It is however possible to force the layout to right justify texts using the setLayout() function:

StringItem myStringItem  = new StringItem("Title", "The text I want to display", Item.PLAIN);
myStringItem.setLayout(Item.LAYOUT_RIGHT);
append(myStringItem );

You could easily create a singleton Settings class, which could hold a flag with the value to use for justification ( Item.LAYOUT_LEFT or Item.LAYOUT_RIGHT), and call it when setting the layout e.g.:

myStringItem.setLayout(Settings.getInstance().getJustification());

This could also be done in the constructor if you wish.

For low level Graphics the drawString() method can be used and the direction of the text altered, but you'll need to calculate the start point from the top right of your text not the top left

  if (Settings.getInstance().getJustification() != Item.LAYOUT_RIGHT ) {
       g.drawString("Some Text", x + TEXT_MARGIN , y ,Graphics.TOP | Graphics.LEFT);
  } else {
       // Arabic rendering of menu items - getWidth() is the maximum length
       // of the line 
       g.drawString("Some Arabic Text",  x + getWidth() - TEXT_MARGIN, y ,
                            Graphics.TOP | Graphics.RIGHT);
  }

The simplest solution (which you have already rejected) would be to use Item.LAYOUT_DEFAULT throughout and alter the locale of the phone (of course), but you will still need to use an override for drawString() if you use low level graphics.

To check the correct justification I would enter the input locale using System.getProperty("microedition.locale") into a function such as this:

 static final String[] RIGHT_TO_LEFT = {
        "ar", // Arabic
        "az", // Azerbaijani
        "he", // Hebrew
        "jv", // Javanese
        "ks", // Kashmiri
        "ml", // Malayalam
        "ms", // Malay
        "pa", // Panjabi
        "fa", // Persian
        "ps", // Pushto
        "sd", // Sindhi
        "so", // Somali
        "tk", // Turkmen
        "ug", // Uighur
        "ur", // Urdu
        "yi" // Yiddish
    };

 public static int getJustification(String locale) {

        for (int index = 0; index < RIGHT_TO_LEFT.length; index++) {
            if (locale.indexOf(RIGHT_TO_LEFT[index]) != -1) {
                return Item.LAYOUT_RIGHT;
            }
        }
        return Item.LAYOUT_DEFAULT;
    }
Jason Fox
  • 5,115
  • 1
  • 15
  • 34
  • side note. If target device supports [JSR 238](http://jcp.org/en/jsr/detail?id=238 "J2ME Mobile Internationalization API") _Mobile I18N API_, there could be other options as well – gnat Jan 18 '13 at 07:05