To make Internationalization/Localization for your Flex applications very easy
Lets split whole process by steps
1st Step: Compile framework resources for necessary language
go to you flex sdk’s bin directory and copy locale using copylocale.exe for your language
cd D:\Development\Flex\sdks\3.0.0\bin
copylocale.exe en_US nl_NL
copylocale.exe en_US ru_RU
copylocale.exe en_US ua_UA
copylocale.exe en_US nl_NL
copylocale.exe en_US ru_RU
copylocale.exe en_US ua_UA
2nd Step: Create language files
/locale/en_US/HR.properties
APP_TITLE=Hour Registration System
LANGUAGE_LABEL=Language:
en_US=English (U.S.)
nl_NL=Nederland
ru_RU=Russian
ua_UA=Ukrainian
LANGUAGE_LABEL=Language:
en_US=English (U.S.)
nl_NL=Nederland
ru_RU=Russian
ua_UA=Ukrainian
/locale/ru_RU/HR.properties
APP_TITLE=Hour Registration System
LANGUAGE_LABEL=Язык:
en_US=Английский
nl_NL=Нидерландский
ru_RU=Русский
ua_UA=Украинский
LANGUAGE_LABEL=Язык:
en_US=Английский
nl_NL=Нидерландский
ru_RU=Русский
ua_UA=Украинский
….
3rd Step: Create ANT script to compile framework resources and language files
/local.build.properties
flex.sdks.dir=D:/Development/Flex/sdks
config.xml
<project name=”Config” basedir=”.”>
<property file=”${basedir}/local.build.properties”/>
<property name=”flex.sdks” value=”${flex.sdks.dir}”/>
<property name=”flex.sdk.version” value=”2.0.1″/>
<property name=”flex.home” value=”${flex.sdks}/${flex.sdk.version}”/>
<property name=”flex.lib” value=”${flex.home}/frameworks”/>
<property name=”flex.compc.jar” value=”${flex.home}/lib/compc.jar”/>
<property name=”flex3.sdk.version” value=”3.0.0″/>
<property name=”flex3.home” value=”${flex.sdks}/${flex3.sdk.version}”/>
<property name=”flex3.mxmlc.jar” value=”${flex3.home}/lib/mxmlc.jar”/>
<property name=”flex3.compc.jar” value=”${flex3.home}/lib/compc.jar”/>
<property name=”flex3.asdoc.jar” value=”${flex3.home}/lib/asdoc.jar”/>
<property name=”flex3.lib” value=”${flex3.home}/frameworks”/>
<property name=”FLEX_HOME” value=”${flex3.home}”/>
<taskdef resource=”flexTasks.tasks” classpath=”${flex3.home}/ant/lib/flexTasks.jar”/>
</project>
<property file=”${basedir}/local.build.properties”/>
<property name=”flex.sdks” value=”${flex.sdks.dir}”/>
<property name=”flex.sdk.version” value=”2.0.1″/>
<property name=”flex.home” value=”${flex.sdks}/${flex.sdk.version}”/>
<property name=”flex.lib” value=”${flex.home}/frameworks”/>
<property name=”flex.compc.jar” value=”${flex.home}/lib/compc.jar”/>
<property name=”flex3.sdk.version” value=”3.0.0″/>
<property name=”flex3.home” value=”${flex.sdks}/${flex3.sdk.version}”/>
<property name=”flex3.mxmlc.jar” value=”${flex3.home}/lib/mxmlc.jar”/>
<property name=”flex3.compc.jar” value=”${flex3.home}/lib/compc.jar”/>
<property name=”flex3.asdoc.jar” value=”${flex3.home}/lib/asdoc.jar”/>
<property name=”flex3.lib” value=”${flex3.home}/frameworks”/>
<property name=”FLEX_HOME” value=”${flex3.home}”/>
<taskdef resource=”flexTasks.tasks” classpath=”${flex3.home}/ant/lib/flexTasks.jar”/>
</project>
build.xml
<?xml version=”1.0″?>
<project name=”HR” default=”compile rm” basedir=”.”>
<import file=”${basedir}/config.xml”/>
<macrodef name=”compile_locale”>
<attribute name=”locale”/>
<sequential>
<java jar=”${flex3.mxmlc.jar}”
fork=”true”
maxmemory=”512m”
failonerror=”true”>
<arg value=”+flexlib=${flex3.home}/frameworks”/>
<arg line=”-locale=@{locale} ” />
<arg line=”-source-path=locale/{locale}” />
<arg line=”-allow-source-path-overlap=true” />
<arg line=”-include-resource-bundles=HR,SharedResources,collections,containers,controls,core,effects,formatters,skins,styles” />
<arg line=”-output=bin-debug/Resources_@{locale}.swf” />
</java>
</sequential>
</macrodef>
<target name=”compile rm” description=”compile a resource module”>
<compile_locale locale=”en_US” />
<compile_locale locale=”nl_NL” />
<compile_locale locale=”ru_RU” />
<compile_locale locale=”ua_UA” />
</target>
</project>
<project name=”HR” default=”compile rm” basedir=”.”>
<import file=”${basedir}/config.xml”/>
<macrodef name=”compile_locale”>
<attribute name=”locale”/>
<sequential>
<java jar=”${flex3.mxmlc.jar}”
fork=”true”
maxmemory=”512m”
failonerror=”true”>
<arg value=”+flexlib=${flex3.home}/frameworks”/>
<arg line=”-locale=@{locale} ” />
<arg line=”-source-path=locale/{locale}” />
<arg line=”-allow-source-path-overlap=true” />
<arg line=”-include-resource-bundles=HR,SharedResources,collections,containers,controls,core,effects,formatters,skins,styles” />
<arg line=”-output=bin-debug/Resources_@{locale}.swf” />
</java>
</sequential>
</macrodef>
<target name=”compile rm” description=”compile a resource module”>
<compile_locale locale=”en_US” />
<compile_locale locale=”nl_NL” />
<compile_locale locale=”ru_RU” />
<compile_locale locale=”ua_UA” />
</target>
</project>
4th Step: Create Languages switch in your Flex application
<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” layout=”absolute” initialize=”application_initializeHandler(event)”>
<mx:Metadata>
[ResourceBundle(”HR”)]
</mx:Metadata>
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.events.ResourceEvent;
import mx.resources.ResourceBundle;
/**
* The locales which this application supports.
* This is the dataProvider for the Language combobox.
*/
private var locales:Array = [ “en_US”, “nl_NL”, “ru_RU”, “ua_UA” ];
/**
* The name of the resource bundle
* containing the application-specific resources.
*/
private static const MY_BUNDLE:String = “HR”;
/**
* Called when the application starts,
* after its children have been created.
*/
private function application_initializeHandler(event:Event):void
{
updateLanguageComboBox();
languageComboBox.selectedItem = resourceManager.localeChain[0];
}
/**
* The labelFunction for the Language combobox.
* It takes a locale such as “en_US”
* and produces the localized string “English”.
*/
private function languageComboBoxLabelFunction(item:Object):String
{
var locale:String = String(item);
return resourceManager.getString(MY_BUNDLE, locale);
}
/**
* Called when the user selects “English” or “Japanese”
* from the Language combobox.
*/
private function languageComboBox_changeHandler(event:Event):void
{
var newLocale:String = String(languageComboBox.selectedItem);
// If we already have the resources for the new locale,
// switch to that locale.
// Otherwise, start loading the appropriate resource module.
if (resourceManager.getLocales().indexOf(newLocale) != -1)
{
switchLocale();
}
else
{
var resourceModuleURL:String = “Resources_” + newLocale + “.swf”;
var eventDispatcher:IEventDispatcher =
resourceManager.loadResourceModule(resourceModuleURL);
eventDispatcher.addEventListener(
ResourceEvent.COMPLETE, resourceModule_completeHandler);
}
}
/**
* Called when a resource module is loaded in response
* to the user selecting a new language in the Language combobox.
*/
private function resourceModule_completeHandler(
event:ResourceEvent):void
{
switchLocale();
}
/**
* Switches the user interface to display in a different locale.
* This method is called when the user changes the selection
* in the Language combobox.
*/
private function switchLocale():void
{
var newLocale:String = String(languageComboBox.selectedItem);
resourceManager.localeChain = [ newLocale ];
updateLanguageComboBox();
}
/**
* Comparison function for sorting the ‘locales’ Array,
* which is the dataProvider for the Language combobox.
* The sort order is locale-dependent,
* because the localized language names for the locales
* are presented in alphabetical order.
*/
private function localeCompareFunction(item1:Object, item2:Object):int
{
var language1:String = languageComboBoxLabelFunction(item1);
var language2:String = languageComboBoxLabelFunction(item2);
if (language1 < language2)
return -1;
if (language1 > language2)
return 1;
return 0;
}
/**
* Repopulates the Language combobox with localized language names
* for the supported locales, alphabetized by language name.
*/
private function updateLanguageComboBox():void
{
var oldSelectedItem:Object = languageComboBox.selectedItem;
// Repopulate the combobox with locales,
// re-sorting by localized language name.
locales.sort(localeCompareFunction);
languageComboBox.dataProvider = locales;
languageComboBox.selectedItem = oldSelectedItem;
}
]]>
</mx:Script>
<mx:ApplicationControlBar width=”100%” height=”30″>
<mx:Label fontSize=”14″ fontWeight=”bold”
text=”{resourceManager.getString(MY_BUNDLE, ‘APP_TITLE’)}”/>
<mx:Spacer width=”100%”/>
<mx:Label text=”{resourceManager.getString(MY_BUNDLE, ‘LANGUAGE_LABEL’)}”/>
<mx:ComboBox id=”languageComboBox”
labelFunction=”languageComboBoxLabelFunction”
change=”languageComboBox_changeHandler(event)”/>
</mx:ApplicationControlBar>
</mx:Application>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” layout=”absolute” initialize=”application_initializeHandler(event)”>
<mx:Metadata>
[ResourceBundle(”HR”)]
</mx:Metadata>
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.events.ResourceEvent;
import mx.resources.ResourceBundle;
/**
* The locales which this application supports.
* This is the dataProvider for the Language combobox.
*/
private var locales:Array = [ “en_US”, “nl_NL”, “ru_RU”, “ua_UA” ];
/**
* The name of the resource bundle
* containing the application-specific resources.
*/
private static const MY_BUNDLE:String = “HR”;
/**
* Called when the application starts,
* after its children have been created.
*/
private function application_initializeHandler(event:Event):void
{
updateLanguageComboBox();
languageComboBox.selectedItem = resourceManager.localeChain[0];
}
/**
* The labelFunction for the Language combobox.
* It takes a locale such as “en_US”
* and produces the localized string “English”.
*/
private function languageComboBoxLabelFunction(item:Object):String
{
var locale:String = String(item);
return resourceManager.getString(MY_BUNDLE, locale);
}
/**
* Called when the user selects “English” or “Japanese”
* from the Language combobox.
*/
private function languageComboBox_changeHandler(event:Event):void
{
var newLocale:String = String(languageComboBox.selectedItem);
// If we already have the resources for the new locale,
// switch to that locale.
// Otherwise, start loading the appropriate resource module.
if (resourceManager.getLocales().indexOf(newLocale) != -1)
{
switchLocale();
}
else
{
var resourceModuleURL:String = “Resources_” + newLocale + “.swf”;
var eventDispatcher:IEventDispatcher =
resourceManager.loadResourceModule(resourceModuleURL);
eventDispatcher.addEventListener(
ResourceEvent.COMPLETE, resourceModule_completeHandler);
}
}
/**
* Called when a resource module is loaded in response
* to the user selecting a new language in the Language combobox.
*/
private function resourceModule_completeHandler(
event:ResourceEvent):void
{
switchLocale();
}
/**
* Switches the user interface to display in a different locale.
* This method is called when the user changes the selection
* in the Language combobox.
*/
private function switchLocale():void
{
var newLocale:String = String(languageComboBox.selectedItem);
resourceManager.localeChain = [ newLocale ];
updateLanguageComboBox();
}
/**
* Comparison function for sorting the ‘locales’ Array,
* which is the dataProvider for the Language combobox.
* The sort order is locale-dependent,
* because the localized language names for the locales
* are presented in alphabetical order.
*/
private function localeCompareFunction(item1:Object, item2:Object):int
{
var language1:String = languageComboBoxLabelFunction(item1);
var language2:String = languageComboBoxLabelFunction(item2);
if (language1 < language2)
return -1;
if (language1 > language2)
return 1;
return 0;
}
/**
* Repopulates the Language combobox with localized language names
* for the supported locales, alphabetized by language name.
*/
private function updateLanguageComboBox():void
{
var oldSelectedItem:Object = languageComboBox.selectedItem;
// Repopulate the combobox with locales,
// re-sorting by localized language name.
locales.sort(localeCompareFunction);
languageComboBox.dataProvider = locales;
languageComboBox.selectedItem = oldSelectedItem;
}
]]>
</mx:Script>
<mx:ApplicationControlBar width=”100%” height=”30″>
<mx:Label fontSize=”14″ fontWeight=”bold”
text=”{resourceManager.getString(MY_BUNDLE, ‘APP_TITLE’)}”/>
<mx:Spacer width=”100%”/>
<mx:Label text=”{resourceManager.getString(MY_BUNDLE, ‘LANGUAGE_LABEL’)}”/>
<mx:ComboBox id=”languageComboBox”
labelFunction=”languageComboBoxLabelFunction”
change=”languageComboBox_changeHandler(event)”/>
</mx:ApplicationControlBar>
</mx:Application>

May 22nd, 2008 at 3:32 pm
don’t forget to set additional compiler arguments in Flex Builder!
I am using en_US locale by default.
In my case additional arguments will be:
-locale en_US -source-path=../locale/{locale}