Earlier I posted how to do Flash localization. Now it's time for an example of Flex localization. Flex localization is a bit more difficult to do, but it's a lot better done. Follow along with the example attached at the bottom of the post.
This example is for Runtime localization. This means that the resource bundles will be external swf files and will not be compiled into your main application.
The official flex documentation for localization can be found here.
I plan on just writing a quick-start example.
Localization file structure
Create the folders and property files you'll need. In this example, let's use English and German.
yourFlexProject
bin-debug
src
libs
locale
en_US
myBundle.properties
de_DE
myBundle.propertiesCreating the property files
Create the .properties files in their respective folders, and then set their text file encoding to UTF-8. If you don't do that, characters with accents and such will just show up as empty squares.
Right click the file, then go to properties.

# locale/en_US/myBundle.properties greeting=Hello goodbye=Goodbye, come back soon!
# locale/de_DE/myBundle.properties greeting=Hallo goodbye=Auf wiedersehen!
Compiling the resource bundles
Now here's the tricky part. Flex Builder has no easy way to compile these resources we just created automatically. So the best way to do this is using ANT.
ANT will come installed by default in Eclipse, but in Flex Builder, you will need to add it. Flex Builder comes with some strange crippled version of ANT, I don't quite understand that.
Installing Ant in Flex Builder Stand-alone
Once you have ANT installed, you will need to create your script to tell the Flex compiler to create swf files out of your language bundles.
In order for ANT to know how to use the flex compiler, we need to copy two files over from your flex directory.
In your Flex Builder 3\extras directory, there are two files; flexTasks.jar and flexTasks.tasks. Copy flexTasks.jar to your flex project libs directory (the directory should exist by default), and copy flexTasks.tasks to the root directory of your project.
Now that ant is installed and has what it needs, create an xml file in your root project directory called antBuild.xml:
<?xml version="1.0" encoding="utf-8"?> <project name="Example resource bundle builder" basedir="." default="main"> <taskdef resource="flexTasks.tasks" classpath="${basedir}/libs/flexTasks.jar"/> <!-- CHANGE TO YOUR FLEX DIRECTORY //--> <property name="FLEX_HOME" value="C:/Program Files/Adobe/Flex Builder 3/sdks/3.0.0"/> <property name="APP_ROOT" value="myApp"/> <target name="main"> <antcall target="en_US"></antcall> <antcall target="de_DE"></antcall> </target> <target name="en_US"> <mxmlc> <locale>en_US</locale> <source-path>locale/{locale}</source-path> <include-resource-bundles>mainBundle</include-resource-bundles> <!--<include-resource-bundles>anotherBundle</include-resource-bundles>--> <output>bin-debug/Resources_en_US.swf</output> </mxmlc> </target> <target name="de_DE"> <mxmlc> <locale>de_DE</locale> <source-path>locale/{locale}</source-path> <compiler.library-path dir="${FLEX_HOME}/frameworks" append="false"> <include name="libs" /> </compiler.library-path> <include-resource-bundles>mainBundle</include-resource-bundles> <!--<include-resource-bundles>anotherBundle</include-resource-bundles>--> <output>bin-debug/Resources_de_DE.swf</output> </mxmlc> </target> </project>
To use this script, open your ANT view, click the Add Buildfiles button, and add that xml file we just created. Because we set default="main", we can just double click the "Resource bundle builder" icon we now should see in the ANT pane.
If everything worked, there will be two new files in your bin-debug directory: Resources_en_US.swf, and Resources_de_DE.swf
If you've gotten this far, the hardest part is over, so keep with me here =-)
We now need to tell Flex where to look for the bundles. For that, we need to add a FlashVar entry.
I know this is annoying, but there's three places we need to modify to change FlashVars in Flex.
Open your index.template.html page. Here you will see three major parts:
Version Check
if ( hasProductInstall && !hasRequestedVersion )
AC_FL_RunContent
Javascript Embed
else if (hasRequestedVersion)
AC_FL_RunContent
And noscript HTML object
The flashVar parameters we need to add are: resourceModuleURLs=Resources_en_US.swf&localeChain=en_US
This will tell Flex what locale to load first on startup.
If you know how to add that into the three places, go ahead, if not, look at the index.template.html file in the example I have attached at the bottom.
Now we need to tell Flex not to compile any language files into the main application. To do this, go into your project properties, flex compiler, and under additional compiler arguments, change -locale=en_US to simply -locale=
Using the resource strings
Ok, the localization should finally be ready to use!
For mxml components, use binding expressions to bind the localized strings:
For actionscript, just use:
resourceManager.getString('myBundle', 'greeting')
If the locale changes at any point, the text will automatically change, at least that part is easy.
To change the locale at runtime:
var eventDispatcher:IEventDispatcher = resourceManager.loadResourceModule("Resources_de_DE.swf"); var localeChain:Array = ["de_DE", "en_US"]; resourceManager.localeChain = localeChain; eventDispatcher.addEventListener(Event.COMPLETE, languageChangeComplete);
So there you go. Setting this up for the first time can be a troublesome process, but once you know how, it's very easy to use.
| Attachment | Size |
|---|---|
| FlexLocalizationExample.zip | 504.66 KB |
Thank you for posting this useful article. Still, I have a question for you:
I use the way that you described to build the resources swf file. My application works perfectly fine with this resource file, except that the 'OK' and 'Cancel' button labels of the alert boxes (alert.show) are displayed as 'null' (literally). Of course, those OK / Cancel button labels are not defined in properties.
Do you have any idea how I can solve this problem?
Thanks
Dominic
Hi Dominic,
You can solve that problem like this:
Alert.noLabel = resourceManager.getString('myBundle', 'noLabel');
Alert.cancelLabel = resourceManager.getString('myBundle', 'cancelLabel');
I know that what you'd expect is to not have to do that and just see english, but unfortunately I think my example is missing the inclusion of the flex native bundles. The english bundles flex uses are:
collections containers controls core effects formatters logging skins states styles utils validators
Flex only has these bundles in english and japanese, so I pretty much just set the text for things like I just mentioned.
THank you for your reply.
Do you mean that every time I use Alert.Show, I need to put the following statement (s)before it?
Alert.okLabel = ...
Alert.noLabel = ...
Or, do you mean that I only put them only once for the whole life cycle of the application?
Thanks
Dominic
They are static variables, so you would only have to do it once. However, setting Alert.okLabel = resourceManager.getString(... is not a binding expression, so if you change languages, you would have to update those labels.
To do this, somewhere, probably your main Application, override the resourcesChanged method.
override protected function resourcesChanged():void {
super.resourcesChanged();
Alert.okLabel = resourceManager.getString( ....
}
The resourcesChanged method will get called anytime the locale changes. I should also mention that resourcesChanged gets called before initialization, so if you have references to components in your resourcesChanged method, you should add this line at the top:
if (!initialized) return;
How can I change the locale of the Flash built components within Flex ? I need to build some Flash Components used in Flex but can I change the Flash Components locale by changing Flex Resource Manager localeChain property ? Flex and Flash employ a totally different way in localization, it is very odd and confused to me. Any ideas ?
That's a tricky one. You're not going to be able to do it with the flex code, you'll need to use Flash's Locale.loadLanguageXML method. Although you might have to use getDefinitionByName to resolve the Locale class after you load the flash component, I'm not sure about that. Let me know when you figure it out.
I made an update to the example and to resourceBundles.xml
If I tried to compile another language, I would get the error:
locale/{locale} , which causes problems during compile.
flex-config.xml(70): Error: unable to open 'locale/de_DE'
The problem is that in the flex-config.xml, there is a line:
If you comment that out, you can then compile the resource bundles, but then your projects that don't use runtime resource bundles will break.
So instead, we add the following to our ant script.
This keeps Flex from trying to find the locale/{locale} bundles that don't exist.
Hey!
Excellent Article! Why can´t Adobe have somthing this simple in the livedocs!
anyway just thought I shoud tell you that you forgot to add the example index.template.html to the end of the post.
Keep up the good work.
David
Ah, thanks, I should have mentioned; the index.template.html to which I'm referring is in the zip file attached, within the html-template folder.
Very nice article.
I can't see any attachment file. Could you please paste index.template.html content.