Localizing Flex Applications

Localizing a Flex application is very simple. All we need to do is to create resource bundles for different languages and then use the ResourceManager class provided by the Flex API to get the resources. Just changing the locale of the resource manager will reflect changes in the entire application with the values from the new locale’s resource bundle.

Creating assets can be done in two ways. One is to create resource bundles, which will be compiled into the application SWF or create resource modules, which are resource bundles compiled as swfs which will not be compiled into the application SWF. If the resource bundles are created as resource modules, you can load them on runtime using the loadResourceModule()method of the resourceManager.

resourceManager is the instance of the ResourceManager class, included in the UIComponent class. If your class is not extending UIComponent then you can get the instance of the ResourceManager using ResourceManager.getInstance().

Sample application

Sample application is a registration form which supports two locales. I created resource bundles and accessed them using resourceManager property of the UIComponent class.

Creating Resource Bundles

All the resource bundles have to be created in one parent folder. Under this parent folder there should be one separate folder containing resource bundles for each locale. For example if I want to support two locales (en_US and en_ES) in my application and I my parent folder is named as “Locales”, then I might have following folders.

Locales/en_US

Locales/en_ES

These two folders have to be added to the application source path. Create two properties files named WelcomePage.properties and place them in the two folders. The properties files have to be in UTF-8 format. Modify the WelcomePage.properties files as shown below.

en_US/WelcomePage.properties

welcome_title_text=Welcome, select your locale and register

form_first_name_text=First Name

form_second_name_text=Last Name

form_gender_text=Gender

form_gender_list_male_text=Male

form_gender_list_female_text=Female

form_company_text=Company

form_designation_text=Designation

form_description_text=About yourself

form_register_text=Register

form_response_text=Registration Successful

select_locale_text=Change Locale

en_ES/WelcomePage.properties

welcome_title_text=Bienvenido, seleccione la opción y registro

form_first_name_text=Nombre

form_second_name_text=Apellido

form_gender_text=Género

form_gender_list_male_text=Hombre

form_gender_list_female_text=Mujeres

form_company_text=Compañía

form_designation_text=Designación

form_description_text=Acerca de ti

form_register_text=Registro

form_response_text=El éxito de Registro

select_locale_text=Cambiar Locale

Adding Locales

Add the locale to the compiler options.

-locale=en_US,en_ES

When adding other locales, you must also include the framework resources for that locale. The en_US locale is already provided. For all other locales, you must create the framework resources. To create a locale’s framework resources, use the copylocale utility in the /sdk/bin directory. For Flex Builder, the copylocale utility is located in flex_builder_install/sdks/3.0.0/bin. You can only execute this utility from the command line.

For example, to create the framework locale files for the es_ES locale, use the following command:

copylocale en_US en_ES

Using the Resource Manager to retrieve the resources

Below is the MXML file in which we use the ResourceManager to retrieve the locale specific resources. This application provides a combo box, using which you can change your locale preference. When the locale preference is changed, the application reflects the changes.

MXML file

<?xml version=”1.0″ encoding=”utf-8″?>

<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml&#8221; layout=”vertical”>

<mx:Script>

<![CDATA[

import mx.controls.Alert;

import mx.resources.ResourceBundle;

[Bindable]

private var locales:Array = [{data:”en_US”, label:”English”}, {data:”en_ES”, label:”Spanish”}];

private function changeLocale():void

{

resourceManager.localeChain =[currentLocale.selectedItem.data];

genderList.dataProvider = listValues;

}

private function register():void

{

Alert.show(resourceManager.getString(‘WelcomePage’, ‘form_response_text’));

}

]]>

</mx:Script>

<mx:Metadata>

[ResourceBundle(“WelcomePage”)]

</mx:Metadata>

<mx:Array id=”listValues”>

<mx:String>{resourceManager.getString(‘WelcomePage’, ‘form_gender_list_male_text’)}</mx:String>

<mx:String>{resourceManager.getString(‘WelcomePage’, ‘form_gender_list_female_text’)}</mx:String>

</mx:Array>

<mx:HBox horizontalAlign=”center” width=”100%”>

<mx:Label text=”{resourceManager.getString(‘WelcomePage’, ‘select_locale_text’)}” fontSize=”11″ fontWeight=”normal”/>

<mx:ComboBox id=”currentLocale” dataProvider=”{locales}” change=”changeLocale()”/>

</mx:HBox>

<mx:Label id=”welcomeLbl” text=”{resourceManager.getString(‘WelcomePage’, ‘welcome_title_text’)}” fontWeight=”bold” fontSize=”13″/>

<mx:Form id=”registrationForm”>

<mx:FormItem label=”{resourceManager.getString(‘WelcomePage’, ‘form_first_name_text’)}”>

<mx:TextInput id=”firstNameTxt”/>

</mx:FormItem>

<mx:FormItem label=”{resourceManager.getString(‘WelcomePage’, ‘form_second_name_text’)}”>

<mx:TextInput id=”lastNameTxt”/>

</mx:FormItem>

<mx:FormItem label=”{resourceManager.getString(‘WelcomePage’, ‘form_gender_text’)}”>

<mx:ComboBox id=”genderList” dataProvider=”{listValues}”/>

</mx:FormItem>

<mx:FormItem label=”{resourceManager.getString(‘WelcomePage’, ‘form_company_text’)}”>

<mx:TextInput id=”companyTxt”/>

</mx:FormItem>

<mx:FormItem label=”{resourceManager.getString(‘WelcomePage’, ‘form_designation_text’)}”>

<mx:TextInput id=”designationTxt”/>

</mx:FormItem>

<mx:FormItem label=”{resourceManager.getString(‘WelcomePage’, ‘form_description_text’)}”>

<mx:TextInput id=”descriptionTxt”/>

</mx:FormItem>

</mx:Form>

<mx:Button label=”{resourceManager.getString(‘WelcomePage’, ‘form_register_text’)}” click=”register();”/>

</mx:Application>

Try using the application. http://sujitreddy.g.googlepages.com/Localizing.swf🙂

30 Responses to Localizing Flex Applications

  1. Prashant D Shelke says:

    Hi,

    Thanks for solution given by you for localization. I have used it as aleternative as I was facing problems related with Deprecated APIs(for resourceBundle).

    Thanks,
    Prashant D Shelke.

  2. Praveen says:

    Hi, I am having a small problem with localization., I think some body willl help me.

    We load the all the labels or texts of components form .properties files and using ‘resourcemanager’ class. But we want to change some of the compnent labels at runtime., although we can do this we cant save them i.e if we reload(not recompile) the application the same old labels of .properties files will come. I also tried directly modifying the .properties file after the Flex Application is compiled, but I think it is loading .properties file at compile time.

    Now what I want is I want to change these ‘values’ in .properties file at runtime either programatically or chaging the .properties file, and want these changes to reflect when I reload(not recompiling) the flex application.

    Thanks in advance.

  3. Sujit Reddy G says:

    Hi Praveen,
    Flex 3 allows you to create resources at runtime. Please check out this URL.
    Create resources at runtime
    Hope this helps. Let me know, if that did not help you🙂

  4. Praveen says:

    Thanks for the reply., I alreaysaw the webpage you given., but I want is I change a key’s value at run time and can I get the changed value after I restart the flex application.

  5. Sujit Reddy G says:

    I don’t think there is any direct way to do this. What you can do is, create a module, which creates the resource bundles from external files. Have all your resource values in external files. When ever there is a change to the values, update both the resource manager and the files, in which your resource values are stored. I will try to find out if there are better ways to do this and shall let u know, if there is any better way.🙂
    Hope this helps.

  6. Jamal says:

    Hi,

    I’m getting error when I try to create new resource from en_US

    …$ ls
    aasdoc adl.exe asdoc copylocale.exe fdb optimizer
    aasdoc.bat adt asdoc.exe digest fdb.exe optimizer.exe
    acompc adt.bat compc digest.exe jvm.config
    acompc.bat amxmlc compc.exe fcsh mxmlc
    adl amxmlc.bat copylocale fcsh.exe mxmlc.exe
    …$ copylocale
    -bash: copylocale: command not found

    Anyone faced this ?

  7. Sujit Reddy G says:

    try ./copylocale
    Hope this helps.🙂

  8. Douglas says:

    I tried your example but I got a symbol of interrogation immediately after the word -> Internacionalizaci?

    It’s like if I did not acknowledge “ó” branded.

    I tried to put the “ñ” and the same thing happens, it is as if only recognize the British character.

    You can escape these character somehow

  9. Andras says:

    Hi,

    I want to create aflex app. using ResourceBundles but without using the copylocale command, so i want to use just the property files loaded.

    Flex 3 documentation says: The localeChain property is an Array so that the ResourceManager can support incomplete locales. … If the resource is not found there, then the ResourceManager searches for the resource in the en_US bundle…

    It seems to me that isn’t working, if i compile my flex app with -locale en_US,en_HU , it’s always searching for locale\en_HU framework.swc files.

    Do you think i misunderstanded something or do something wrong?

    p.s.: i’ve posted this message to another blogs as well!

    Many thanks,
    Andrew

  10. Andras says:

    problem solved.
    flex builder needs an empty locale directory (like: C:\Program Files\Adobe\Flex\frameworks\locale\hu_HU\ ), but not any swc files.

  11. Oscar says:

    Just a heads up. The locale en_ES doesn’t really make any sense. It implies english as spoken in Spain. You probably mean es_ES.

    And a reply to Douglas above: Are you editing the file as UTF-8? From what I’ve heard it will croak otherwise (well, on non-ascii characters, that is).

  12. Srikanth says:

    Hi,

    Sujit – thanks for this sample example .
    This works fine for Flex 2 and for Flex 3 there needs to be a small change in the source path.

    /Locale/{locale}

    The extra backslash is because the code resides in src folder for Flex 3.

    Thanks

  13. Flex developer says:

    Hi,

    I am currently working on introduction of i18n to my application. When i change a resourceManager.localeChain value in login.mxml component (which is of mx:Application type) to for example polish, I successfully see labels in polish. Then I go to “taskList.mxml” component (which is of mx:Module type) and here I see all labels in english, as well as resourceManager.localeChain set to default value en_US. What can I do to propagate resourceManager.localeChain value from login.mxml to taskList.mxml? Flex documentation says that resourceManger is a singleton, so resourceManager.localeChain should have the same value in both somponents, but it does not.

  14. Kotireddy says:

    Hi SujithReddy thanks for the sample application, but I am unable to run from the console with help of maven build tool for the multiple locales.Can we set compiler properties other than flex builder? I modified in flex-config.xml even though its not effecting.Please help me in such way. Thanks in advance.

  15. Harsha says:

    Hi,

    I tried to implement all the steps in your example, but I got some weird error “Unable to resolve resource bundle ‘WelcomePage’.” While “WelcomePage.properties” are placed under src/Locale/en_US and en_ES. My mxml file name is “Test_Oct14.mxml”.

    Please tell me why am I facing this error.

  16. Raj says:

    hi,

    The example provided above is using combo box. i am currently trying on click of buttons ( French, German …) it should change all the text to particular language. Text are defined in their respective locale folder in properties file.

    any help please?

  17. Sujit Reddy G says:

    Hi Raj,

    Please try using ButtonBar. Please find more details on ButtonBar at the URL below.

    http://livedocs.adobe.com/flex/3/langref/mx/controls/ButtonBar.html

    Hope this helps.

  18. Billigflug says:

    “flex builder needs an empty locale directory (like: C:\Program Files\Adobe\Flex\frameworks\locale\hu_HU\ ), but not any swc files.”
    that is true

    Thanks a lot for solution given by you for localization. Exactly what i m looking fot
    keep up your good work
    I will be a regular reader of ur blog

  19. Malcom says:

    Hi,

    I try write a function like :
    private function getString(ps_key:String):String{
    return resourceManager.getString(“BaseCard”, ps_key);
    }

    and set one label to this like :

    but this label is not updated when I change language combobox, any idea ?

    Many Thanks,

  20. Malcom says:

    Sorry, seem post wrong,

    I try write a function like :
    private function getString(ps_key:String):String{
    return resourceManager.getString(“BaseCard”, ps_key);
    }

    and set one label to this like :
    … mx:FormItem label=”{getString(‘key1’)}” …

    but this label is not updated when I change language combobox, any idea ?

    Many Thanks,

  21. Hi Malcom,

    Please find details on how to implement this at the URL below.

    http://livedocs.adobe.com/flex/3/html/databinding_4.html#199771

    Hope this helps.

  22. Raj says:

    hi Sujit!!!

    one thing i like to ask that how would you externalize the UI data ie height and width of any component .

    for Ex- most of the translation to German has more no of characters than English so we have to change the size of the component for the localized version of the application.

    any suggestion on this!!!
    Thanks Raj.

  23. Toby says:

    Raj,

    Make heavy use of relative positioning containers (VBox, HBox) and avoid anything that uses absolute positioning (Canvas). Otherwise you will be forever tweaking positioning for each language.

  24. Sachin says:

    Hi,
    How to get the current locale of the user?
    Is there any way we can find current locale without making use of javascript or outer html wrapper?

  25. Nguyen Toan says:

    I had a problem when use resourceManager to change another language (no english); It causes errors for validating number, datetime; it can’t format data correctly; so I can’t format and validate data correctly when use Formatter( NumberFormatter, DateFormatter). Please help me!
    Thanks.

  26. Nguyen Toan says:

    And here the error I found with DateForrmater:
    “Cannot access a property or method of a null object reference.

    at mx.formatters::DateBase$/get http://www.adobe.com/2006/flex/mx/internal::defaultStringKey()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\formatters\DateBase.as:173]

    at mx.formatters::DateFormatter$/parseDateString()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\formatters\DateFormatter.as:156]
    at mx.formatters::DateFormatter/format()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\formatters\DateFormatter.as:544]”

  27. Raj says:

    Hi Sujith,

    I am developing one database application, for this application needs interface in Telugu and if I type it should appear in telugu in text areas.

    Could you plz help me, how to use locale concept for this?

    Thanks advance.

    Raj

  28. Aashish says:

    Hi Everyone,

    I want to load a property resource file in flex application. Can anyone guide me how to do that…?

    I know resourceManager.loadResourceBundle(), but that takes .swf file and i want to load .properties files only.

    Many Thanks,
    Ashish

  29. jag says:

    thnx a lot

  30. Ajit says:

    Hello Sujith,

    Thats a nice article. I am having some issues with an Adobe Air application which implements localization.

    There is a combo box through which, the user selects the language. On selecting the language, the appropriate property files are loaded and the application updates itself to display the text in the selected language. However, one label which alternates between two values , simply does not update itself instantaneously. It requires an application restart.

    Has anyone of you come across a similar problem? Any help would be appreciated.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: