Swiz, BabelFx, and Logging

For over 5 years, I have been a Cairngorm proponent and evangelist. During the last 6 months I have discovered a new framework passion called “Swiz.” Inversion of control, metadata processors, dependency injection… these are just some of the amazing features available in the Swiz framework.

With the release of Swiz 1.0rc1, several developers asked questions regarding the best way to use the BabelFx Framework (aka l10nInjection) to add multi-language features to Swiz RIA applications. So here is the modified version of the Swiz Flex 4 CafeTownsend application… now with extra features for Logging and BabelFx.

In fact, this application now uses the ThunderBolt AS3 classes to log output to the Firebug console. That is very cool!

Using BabelFx, the Swiz-version of CafeTownsend demo now supports both Spanish and English locales. And when you look at the code, you will see that none of the view code has been changed… yet click on the map buttons and the locale changes magically work. If you run the application from in debug mode, the trace console will show a full log output of the application activity.

Add-in the BabelFx framework with custom Swiz Logging and… wow! you will be amazed. With Swiz and “inversion of control”, the code for my own applications has become so clean and robust. Can’t you tell that I love Swiz?

Multi-language features using the Flex BabelFx localization framework!

The CafeTownsend application leverages Swiz v1.0rc1 and the [Inject] metadata tag functionality to inject models into controllers and views. Now do you recall that the BabelFx library also listens for “creationComplete” of GUI instances and injects localized resources into those target instances?

Did you know, however, that the BabelFx can also inject into data models and controllers? With Swiz it is almost trivial to accomplish that. Simply add the BabelFx LocalizationMap to the beanProvider list and then let Swiz Inject model instance references into your custom LocalizationMap. Below is a live demo of the Swiz, multi-language CafeTownsend application; with attached source code. Simply right-click to browse or download the source.

CafeTownsend (Swiz w/ l10n)
Figure 1: Swiz CafeTownsend (with l10n)

In order to add l10n features to the FlexStore, I needed to perform three (3) tasks in order to add multi-language features to the CafeTownsend application:

  1. Include the BabelFx.swc
  2. Compile and embed the resourceBundles inside the deployed swf.
  3. Create an BabelFx LocalizationMap to specify which resources are to be injected into which GUI and model targets (see source below)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
<?xml version="1.0" encoding="utf-8"?>
<l10n:LocaleMap 	enableLog="true"
					xmlns:mx="http://www.adobe.com/2006/mxml" 
					xmlns:l10n="library://ns.mindspace.com/l10n/flex/" >
 
<mx:Metadata>
	<!-- References to bundles so embedding process works; 
		 if runtime loaded, then disable this section 
	-->
	[ResourceBundle("login")]
	[ResourceBundle("employees")]
	[ResourceBundle("language")]
</mx:Metadata>
 
<mx:Script>
<![CDATA[
	import com.cafetownsend.domain.Employee;
	import com.cafetownsend.model.AppModel;
	import com.cafetownsend.model.Constants;
	import com.cafetownsend.presentation.LoginPresentationModel;
	import com.cafetownsend.view.EmployeeDetail;
	import com.cafetownsend.view.EmployeeDetailNavigation;
	import com.cafetownsend.view.EmployeeListNavigation;
	import com.cafetownsend.view.LoginView;
	import com.cafetownsend.view.MainView;
 
	import l10n.views.LanguageBar;
 
	import mx.containers.Form;
	import mx.resources.IResourceManager;
	import mx.resources.ResourceManager;
 
	// ********************************************************************************
	// Public Mutators and Properties (injected by Swiz)
	// ********************************************************************************
 
	/**
	 * To support l10n injection into non-displayObjects (e.g. data models)
	 * the LocaleMap must have instance references. So we use Swiz to inject
	 * a reference to each model bean instance that will be used or modified
	 * when locales change.
	 * 
	 */			
	[Bindable]
	[Inject("employeeModel.selectedEmployee")]
	public function get selectedEmployee():Employee {
		return _selectedEmployee;
	}
	public function set selectedEmployee(value:Employee):void {
		_selectedEmployee = value;
		Constants.EMPLOYEE_CONFIRM_DELETE = buildConfirmMessage();
	}
 
	[Bindable]
	[Inject]    
	public var authenticated : AppModel = null;
 
	[Inject]
	public var model         : LoginPresentationModel = null;
 
 
	// ********************************************************************************
	// Private Methods
	// ********************************************************************************
 
	/**
	 * Manual injections into static variables stored in the Constants class. 
	 * 
	 */
	private function onLocaleChanged(event:Event):void {
	 var sri     : SmartResourceInjector = event.target as SmartResourceInjector;
	 var cntr	: LoginView 			= sri.targetInstances[0] as LoginView;
 
	 if(cntr != null) {
 
	 /**
	 * BabelFx or l10nInjection supports injection into both GUI and non-GUI instances (data models, 
	 * controllers, etc). But static variables cannot be directly modifed with injection.
	 * This is manual process; shown below.
	 */
	 Constants.LOGIN_FAILED_MESSAGE   	= _rMngr.getString("login","login.error.noMatch");
	 Constants.LOGIN_FAILED_TITLE     	= _rMngr.getString("login","login.error.title");
	 Constants.LOGIN_INVALID_USERNAME 	= _rMngr.getString("login","login.error.usernameRequired");
	 Constants.LOGIN_INVALID_PASSWORD 	= _rMngr.getString("login","login.error.passwordRequired");
 
	 Constants.EMPLOYEE_LOAD_ERROR 		= _rMngr.getString("employees","users.unableToLoad");
	 Constants.EMPLOYEE_INVALID_FIRSTNAME= _rMngr.getString("employees","editor.invalid.firstName");
	 Constants.EMPLOYEE_INVALID_LASTNAME= _rMngr.getString("employees","editor.invalid.lastName") ;
	 Constants.EMPLOYEE_CONFIRM_DELETE 	= buildConfirmMessage();
 
	 cntr.loginErrorTxt.text = "";				// Manually clear the error text...
	 cntr.loginBtn.skin.invalidateProperties();	// Force refresh on custom skin part 
	 if (model != null) {
		model.usernameError 					= "";	// Clear all validation errors... 
		model.passwordError						= "";
	 }
 
	 } else {
 
		var main : MainView = sri.targetInstances[0] as MainView;
		if (main != null) {
			main.btnLogout.skin.invalidateProperties();	// Force refresh on custom skin part
		}
	 }
	}
 
	private function buildConfirmMessage():String {
		var params : Array = selectedEmployee ? [selectedEmployee.firstName, selectedEmployee.lastName] : ["",""]; 
		return 	_rMngr.getString("employees","users.confirmDelete",params);
	}
 
	// ********************************************************************************
	// Private Attributes
	// ********************************************************************************
 
 
	private var _rMngr 	: IResourceManager 	= ResourceManager.getInstance();
	private var _selectedEmployee 	: Employee 			= null;
 
]]>
</mx:Script>
 
 
 <l10n:SmartResourceInjector bundleName="login" target="{MainView}" localeChange="onLocaleChanged(event);" >
	<l10n:ResourceProxy 		property="btnLogout.label" 		key="login.signOut" />
	<l10n:ResourceProxy 		property="txtWelcomeUser.text" 	key="login.welcome" parameters="{[authenticated.user.username]}" />
	<l10n:ResourceProxy 		property="imgHeader.source" 	key="login.header" type="class" />
	<!-- 
	      Would be better to inject a new styleName or a new styleSheet 
		  Note: The login and logout buttons have custom skins with states.
	            Because we are modifying the colors of skin part manually (instead of different styleName)
	            we must manually invalidate to force immediate redraws. (see lines 83/89).
	-->
	<l10n:ResourceProxy 		property="contentContainer.backgroundColor" key="content.background.color" />
	<l10n:ResourceProxy 		property="contentFrame.color" 				key="content.frame.color" />
	<l10n:ResourceProxy 		property="btnLogout.backgroundColor" 		key="content.frame.color" />
 </l10n:SmartResourceInjector>
 
 <l10n:SmartResourceInjector bundleName="login" target="{LoginView}" localeChange="onLocaleChanged(event);" >
	<l10n:ResourceProxy 		property="fiUserName.label" 	key="login.form.fiUserName" />
	<l10n:ResourceProxy 		property="fiPassword.label" 	key="login.form.fiPassword" />
	<l10n:ResourceProxy 		property="loginBtn.label" 		key="login.submit" />
	<l10n:ResourceProxy 		property="lblHint.text" 		key="login.tip" />
 
	<l10n:ResourceProxy 	property="loginBtn.backgroundColor" key="content.frame.color" />
 </l10n:SmartResourceInjector>
 
 <l10n:SmartResourceInjector bundleName="employees" target="{EmployeeListNavigation}" >
	<l10n:ResourceProxy 		property="btnCreate.label" 	key="users.buttons.create" />
	<l10n:ResourceProxy 		property="btnEdit.label" 	key="users.buttons.edit" />
	<l10n:ResourceProxy 		property="btnDelete.label" 	key="users.buttons.delete" />
 </l10n:SmartResourceInjector>
 
 <l10n:SmartResourceInjector bundleName="employees" target="{EmployeeDetailNavigation}" >
	<l10n:ResourceProxy 		property="btnBack.label" 	key="users.buttons.back" />
 </l10n:SmartResourceInjector>
 
 <l10n:SmartResourceInjector bundleName="employees" target="{EmployeeDetail}" >
	<l10n:ResourceProxy 		property="fiFirstName.label" 	key="form.fiFirstName" />
	<l10n:ResourceProxy 		property="fiLastName.label" 	key="form.fiLastName" />
	<l10n:ResourceProxy 		property="fiStartDate.label" 	key="form.fiStartDate" />
	<l10n:ResourceProxy 		property="fiEmail.label" 		key="form.fiEmail" />
	<l10n:ResourceProxy 		property="btnSubmit.label" 		key="form.buttons.submit" />
	<l10n:ResourceProxy 		property="btnDelete.label" 		key="form.buttons.delete" />
 
	<l10n:ResourceProxy 		property="scaleX" 				key="form.scaling" />
	<l10n:ResourceProxy 		property="scaleY" 				key="form.scaling" />
 </l10n:SmartResourceInjector>
 
 <l10n:SmartResourceInjector  bundleName="language" target="{LanguageBar}">
	<l10n:ResourceProxy 		property="lblBarHelp.text" 		key="languagebar.title" 	parameters="{['target.selectedLocale']}" />
	<!--
		See LocaleAssets for sort order on Flags 
	-->
	<l10n:ResourceProxy  		property="flags[0].toolTip" 	key="flag.toolTip.en_US" />
	<l10n:ResourceProxy  		property="flags[1].toolTip" 	key="flag.toolTip.es_ES" />
 </l10n:SmartResourceInjector>
 
</l10n:LocaleMap>

The BabelFx framework works with Flex 3 & 4, and with Cairngorm, Mate, Swiz, RobotLegs, and other MVC/IoC solutions. But it seems to work “best of all” (easiest to integrate) with Swiz. Swiz leverages dependency injection and listens for GUI instantiations. And BabelFx leverages resource injection and listens for GUI instantiations (independent of Swiz). These two frameworks are a “marriage made in heaven.”

An interesting challenge with the CafeTownsend application was its implementation of color borders with Flex 4 skins. In order to change the skin colors during locale changes, the skins need to redraw via an updateDisplayList phase. See LocalizationMap [line 92] for the easy resolution to invalidating the skin colors during locale changes. Alternate solutions are possible but I wanted to demonstrate that l10Injection even adapts to allow changes of color settings in container skins.
 

And let’s not forget custom logging with the new Swiz LogProcessor and the [Log] metadata tag!

Another important change to the CafeTownsend demo are the new logging features. With Swiz you can log (or trace to the output console) activity within the Swiz engine and within your own custom application code. And, remember that the Localization Framework (l10nInjection) has its own logger to ouput its injection activity. While the l10nInjection injection has its own logging automatically enabled within the CafeTownsend application (see bottom), the application code now uses a new metadatatag [Log] to inject a logger instance and enable super-easy log functionality.

Note that the [Log] tag is enabled simply by adding a LogProcessor instance to your swiz setup and then calling log.debug() from your controllers, models, and views. Developers should also note that the log.debug() methods do not have to specify times, dates, or even the classname… yet they all show up in the trace console. That feature is inherited from the LogProcessor.

Below is the Swiz setup class which activates the Swiz LogProcessor:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?xml version="1.0" encoding="utf-8"?>
<sw:Swiz    xmlns:sw="http://swiz.swizframework.org"
		    xmlns:fx="http://ns.adobe.com/mxml/2009" 
		    xmlns:mx="library://ns.adobe.com/flex/mx" >
 
 <fx:Script>
 <![CDATA[
	import mx.controls.Alert;
	import mx.rpc.events.FaultEvent;
 
	private function genericFault( fe : FaultEvent ) : void {
		var message : String = fe.fault.faultDetail; 
		var code    : String = fe.fault.faultCode;
 
		Alert.show(message , code);
	}
 ]]>
 </fx:Script>
 
 <sw:beanProviders>
	<config:Beans 		 xmlns:config="com.cafetownsend.config.*" />
 </sw:beanProviders>
 
 <sw:config>
	<sw:SwizConfig 		 id="appConfig"
						 strict="true"
						 eventPackages="com.cafetownsend.event.*" 
						 viewPackages="com.cafetownsend.view.*"
						 defaultFaultHandler="{genericFault}"/>
 </sw:config>
 
 <sw:customProcessors>
	<sw:LogProcessor /> </sw:customProcessors>
 
</sw:Swiz>

Now that we have configured Swiz to use the custom LogProcessor, we can use the [Log] metadatatag in our custom application code. The [Log] tag tells Swiz to inject a custom instance of an ILogger. That instance has been pre-configured to auto-output the time, date and className for the class in which it has been injected. Below is a snippet of the EmployeeController class which illustrates how you configure the “almost magical” ILogger injection using the [Log] tag and how you use the log.debug() method. Notice how the developer only had to add the method name and the method argument as additional custom information that they wish to log.

1
2
3
4
5
6
7
8
9
10
11
12
13
public class EmployeeController {
 
  [Log]			
  public var log : ILogger = null;		
 
  [Mediate(event="LoginEvent.COMPLETE")]
  public function loadEmployees(department:String=""):void {
	log.debug("loadEmployees( '{0}' )",department); 
	var agent : AsyncInterceptor = new AsyncInterceptor(parseEmployeesData);
	serviceRequestUtil.executeServiceCall(agent.intercept(delegate.loadEmployees()), onResults_loadEmployees);
  }
}

Below is a trace console output sample from the CafeTownsend Swiz demo; output generated when using the custom Swiz LogProcessor and ILogger::debug() calls:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
6/6/2010 07:38:23.169 [DEBUG] com.cafetownsend.controller::AppController login(Flex)
6/6/2010 07:38:23.968 [DEBUG] com.cafetownsend.controller::AppController onResults_login(Flex)
6/6/2010 07:38:23.974 [DEBUG] com.cafetownsend.controller::EmployeeController loadEmployees('accounting')
6/6/2010 07:38:24.009 [DEBUG] com.cafetownsend.controller::NavigationController logInCompleteHandler()
6/6/2010 07:38:24.009 [DEBUG] com.cafetownsend.presentation::MainViewPresentationModel currentState==loggedIn
6/6/2010 07:38:24.198 [DEBUG] com.cafetownsend.presentation::EmployeeListPresentationModel set employees(); len=0
6/6/2010 07:38:24.200 [DEBUG] com.cafetownsend.presentation::EmployeeListPresentationModel selectedEmployeeIndex == -1
6/6/2010 07:38:24.201 [DEBUG] com.cafetownsend.presentation::EmployeeListPresentationModel selectedEmployeeIndex == -1
6/6/2010 07:38:24.476 [DEBUG] com.cafetownsend.controller::EmployeeController parseEmployeesData()
6/6/2010 07:38:24.477 [DEBUG] com.cafetownsend.controller::EmployeeController EmployeeUtil.getEmployeesFromXML()
6/6/2010 07:38:24.478 [DEBUG] com.cafetownsend.controller::EmployeeController onResults_loadEmployees(): employees=4
6/6/2010 07:38:24.481 [DEBUG] com.cafetownsend.presentation::EmployeeListPresentationModel set employees(); len=4
6/6/2010 07:38:24.481 [DEBUG] com.cafetownsend.presentation::EmployeeListPresentationModel set employees(); len=4
6/6/2010 07:38:25.071 [DEBUG] com.cafetownsend.presentation::EmployeeListPresentationModel set employees(); len=4
6/6/2010 07:38:25.072 [DEBUG] com.cafetownsend.presentation::EmployeeListPresentationModel selectedEmployeeIndex == -1
6/6/2010 07:38:25.073 [DEBUG] com.cafetownsend.presentation::EmployeeListPresentationModel selectedEmployeeIndex == -1

And since the Flex Localization (l10nInjection) framework has logging enabled by default, the l10nInjection logging generates output that looks something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
07:40:02.599 [DEBUG] LocalizationMap register(com.cafetownsend.view::MainView)
07:40:02.600 [DEBUG] LocalizationMap register(com.cafetownsend.view::LoginView)
07:40:02.600 [DEBUG] LocalizationMap register(com.cafetownsend.view::EmployeeListNavigation)
07:40:02.601 [DEBUG] LocalizationMap register(com.cafetownsend.view::EmployeeDetailNavigation)
07:40:02.602 [DEBUG] LocalizationMap register(com.cafetownsend.view::EmployeeDetail)
07:40:02.603 [DEBUG] LocalizationMap register(l10n.views::LanguageBar)
07:40:02.604 [DEBUG] LocalizationMap addListenerProxy() Attaching listener for all  'creationComplete' event
07:40:02.859 [DEBUG] LocalizationMap onLoadLocale() announce 'changing' locale
07:40:02.861 [DEBUG] LocaleCommand loadLocale(en_US) - embedded.
07:40:02.961 [DEBUG] LocalizationMap onCreationComplete_Target() for 'l10n.views::LanguageBar'
07:40:02.962 [DEBUG] SmartResourceInjector onInstanceCreationComplete(l10n.views::LanguageBar)
07:40:02.965 [DEBUG] SmartResourceInjector inject 'Switch from English to locale:' into 'lblBarHelp.text' from resource language::languagebar.title
07:40:02.966 [DEBUG] SmartResourceInjector inject 'English (USA)' into 'flags[0].toolTip' from resource language::flag.toolTip.en_US
07:40:02.967 [DEBUG] SmartResourceInjector inject 'Spanish' into 'flags[1].toolTip' from resource language::flag.toolTip.es_ES
07:40:02.968 [DEBUG] LocalizationMap onCreationComplete_Target() for 'com.cafetownsend.view::MainView'
07:40:02.968 [DEBUG] SmartResourceInjector onInstanceCreationComplete(com.cafetownsend.view::MainView)
07:40:02.968 [DEBUG] SmartResourceInjector inject 'logout' into 'btnLogout.label' from resource login::login.signOut
07:40:02.969 [DEBUG] SmartResourceInjector inject 'Hello {0}!' into 'txtWelcomeUser.text' from resource login::login.welcome
07:40:02.970 [DEBUG] SmartResourceInjector inject '[class en_US$login_properties__embed_properties___assets_images_header_png_321309068]' into 'imgHeader.source' from resource login::login.header
07:40:02.970 [DEBUG] SmartResourceInjector inject '0xFFFFFF' into 'contentContainer.backgroundColor' from resource login::content.background.color
07:40:02.971 [DEBUG] SmartResourceInjector inject '0x9C0000' into 'contentFrame.color' from resource login::content.frame.color
07:40:02.971 [DEBUG] SmartResourceInjector inject '0x9C0000' into 'btnLogout.backgroundColor' from resource login::content.frame.color
07:40:03.399 [DEBUG] LocalizationMap onCreationComplete_Target() for 'loginView'
07:40:03.400 [DEBUG] SmartResourceInjector onInstanceCreationComplete(com.cafetownsend.view::LoginView)
07:40:03.400 [DEBUG] SmartResourceInjector inject 'Username:' into 'fiUserName.label' from resource login::login.form.fiUserName
07:40:03.401 [DEBUG] SmartResourceInjector inject 'Password:' into 'fiPassword.label' from resource login::login.form.fiPassword
07:40:03.401 [DEBUG] SmartResourceInjector inject 'Login' into 'loginBtn.label' from resource login::login.submit
07:40:03.402 [DEBUG] SmartResourceInjector inject '( Username: Flex   Password: Swiz )' into 'lblHint.text' from resource login::login.tip
07:40:03.402 [DEBUG] SmartResourceInjector inject '0x9C0000' into 'loginBtn.backgroundColor' from resource login::content.frame.color

As you can see, the logging can be a very powerful output and monitoring tool for developers. The custom Swiz LogProcessor is available on my GitHub repository. And the l10nInjection logger is built-into the l10nInjection framework.

GD Star Rating
loading...

9 Responses to “Swiz, BabelFx, and Logging”

  1. Damn, so many code… Localization is a simple thing, just create

    [Bindable("stringsChange")]
    public function getString(stringId:String):* {}

    function in your model and that’s it. Why having so many code? :)

    • thomasb says:

      @Maxim,

      Have you read my other blogs regarding Localization? Have you reviewed my video tutorial and slides? Looked at the online samples?
      After deploying four (4) commercial Flex applications that support multiple languages, I seriously doubt you will convince me that another solution is better. I have, however, a proposal for you:

      Study the BabelFx solution and samples.
      Download the source for the Swiz CafeTownsend application.
      Use your own solution or approach to add localization to the Swiz app. (Do not use the BabelFx framework.)
      Compare your solution with mine.
      Show me the better solution

      If your solution is better – and I will be a fair judge – I will pay you $50 USD for your efforts.

  2. Terrence H says:

    I have been using cairngorm for 18 months and I hated it but It works, I like how simple swiz seems to be I like this example demo the best, thanks again many times. I still need to attach 10nInjection framework to see it work behind the scenes. what I would like to know is it possible to query Google translate with the titles and text and have changed with a select language button. Yes not all translators know everything you are talking about but the 8 majors work pretty well.

    • thomasb says:

      BabelFx (aka l10nInjection) provides a sophisticated set of mechanisms to “inject” localized resources into RIA targets. And it even provides support to use externally-loaded resourcesbundles (pre-compiled as SWFs). But BabelFx does not do anything [yet] to auto-convert your properties files to alternate locales. Effort is currently underway to provide an online resource that internally uses Google Translate to 1-click translate a specified .properties file to an alternate localization. That tool is currently under development.

  3. Vijay Kumar says:

    Localization Map is framework is very good and cool feature , i have some questions regrading it:

    1) How to set the default Locale? I want to set default localization based on browser language. Is there any attribute or field to set as default localization?
    2) How to load runtime Locale (example : en_US.swf ) using commandFactory , can you provide API or details about command Factory (if possible any you provide simple example)? Or can I use ResourceManager.getInstance().loadResourceModule for loading runtime and for loading complete i ill dispatch LocaleEvent.LOAD_LOCALE , is this approach is correct?

    • thomasb says:

      @Vijay,
      Check out the GitHub samples and source code.. The l10nInjection has support for both (a) detecting locale changes and to (b) switching locales. To request a localeChange, you must dispatch a com.mindspace.l10n.events.LocaleEvent; e.g.

          dispatchEvent(new LocaleEvent(LocaleEvent.LOAD_LOCALE,”en_US”)

      If the resourceBundles are embedded, the locale will change and your LocalizationMap will re-inject new resources. If the resourceBundle (for the locale specified) is not embedded, you must load that bundle externally. That loading can be done manually with your own code or you can use the l10nInjection ExternalLocaleCommand to load the bundle, switch to that new locale, and re-inject localized resources into your application.

      Now to load external resource bundles, it is SUPER easy. Of course, you must have the bundles already compiled and deployed to a url for FlashPlayer loading. The l10nInjection has an ExternalLocaleCommand that can be used in the LocalizationMap. In fact the l10nInjection has a super simple way to configure and plugin that command… see lines 74-80 in the FlexStore. LocalizationMap for a sample.

      The samples use a LanguageBar to show locale Flags; when clicked each flag dispatches a LocaleEvent. The FlexStore has a Flex4 LanguageBar and the RegistrationDemo has a Flex3 LanguageBar. The FlexStore LanguageBar also has code to auto-detect the current OS language setttings and auto-switch the Locale upon startup see lines 98-100.

      • Vijay Kumar says:

        Hi thomasb

        I got answer for every Question ThankQ so much for such a Awesome Framework

        One Last Question

        Do you have any idea about getting browser language and setting it as default. I tryed javascript but its not working

        if you provide any suggestion/solution

        Thanks

        • thomasb says:

          @Vijay,
          Did you read my previous reply on 2010/07/12? Read the docs and the source code for the samples and LanguageBar. Those resources will answer your questions.

Leave a Reply

GD Star Rating
loading...

Please leave these two fields as-is:

Protected by Invisible Defender. Showed 403 to 2,816 bad guys.