Previous Tutorial: Developing a Multi-Language Application with ActionScript 2.0
2 of 4
Next

The FLA File

The "main.fla" file is almost free of any ActionScript code. There are only three component instances on the stage:

In a real-world application you wouldn't even need any physical representations of the Flash components on the stage. You could build the user interface completely with ActionScript, of course.

The first frame on the main timeline in the "main.fla" looks like this:

var defaultLanguage:String = "en";
Main.getMain().init(this, defaultLanguage);

In order to understand these lines we need to take a closer look at the ActionScript classes.

The ActionScript 2.0 Classes

Let's start with the "Main.as" class file. The purpose of the class "Main" is to initialize the application and to control the application flow.

Main.as

import mx.controls.*;
import mx.utils.Delegate;

class Main {
	
   private static var _instance:Main = null;
   private var _main_mc:MovieClip;
   private var _defaultLanguage:String;
		
   // constructor
   private function Main() {
      // emtpy
   }
	
   // function getMain()
   public static function getMain():Main {
      if (Main._instance == null) {
         Main._instance = new Main();
      }
      return Main._instance;
   }
	
   // function init()
   public function init(main_mc:MovieClip, defaultLanguage:String): Void {
      _main_mc = main_mc;
      _defaultLanguage = defaultLanguage;
      initLanguageSelector();		
   }
	
   // function initLanguageSelector()
   private function initLanguageSelector(): Void {
      var languageDP:Array = [{data:"en", label:"English"}, {data:"de", label:"German"}];		
      _main_mc.language_cb.dataProvider = languageDP;		
      _main_mc.language_cb.addEventListener("change", Delegate.create(this, changeLanguage));
      // select default language
      for (var i:Number=0; i < languageDP.length; i++) {
         if (languageDP[i].data == _defaultLanguage) {
            _main_mc.language_cb.selectedIndex = i;
            break;	
         }
      }
      // dispatch change event
      _main_mc.language_cb.dispatchEvent({type:"change"});
   }
	
   // function changeLanguage()
   private function changeLanguage(eventObj:Object): Void {
      var lang:String = eventObj.target.selectedItem.data;
      LanguageManager.getLanguageManager().init(lang);
   }
	
   // function doSomething()
   public function doSomething(): Void {
      _main_mc.monthNames_lbl.text = LanguageManager.LANG["monthNames"];
      _main_mc.monthNames_cb.dataProvider = [{data:1, label:LanguageManager.LANG["january"]}, 
	                                    {data:2, label:LanguageManager.LANG["february"]},
	                                    {data:3, label:LanguageManager.LANG["march"]},
	                                    {data:4, label:LanguageManager.LANG["april"]},
	                                    {data:5, label:LanguageManager.LANG["may"]},
	                                    {data:6, label:LanguageManager.LANG["june"]},
	                                    {data:7, label:LanguageManager.LANG["july"]},
	                                    {data:8, label:LanguageManager.LANG["august"]},
	                                    {data:9, label:LanguageManager.LANG["september"]},
	                                    {data:10, label:LanguageManager.LANG["october"]},
	                                    {data:11, label:LanguageManager.LANG["november"]},
	                                    {data:12, label:LanguageManager.LANG["december"]}];
   }
   
}

Let's examine some parts of the class code more closely. First of all, you usually need only one main control instance for your application. That's why the class "Main" uses the Singleton pattern to make sure that only one instance of the class is created:

   private static var _instance:Main = null;
  		
   // constructor
   private function Main() {
      // emtpy
   }
	
   // function getMain()
   public static function getMain():Main {
      if (Main._instance == null) {
         Main._instance = new Main();
      }
      return Main._instance;
   }

If you are not familiar with the Singleton design pattern I recommend reading chapter 17 in Colin Moock's book Essential ActionScript 2.0. Singleton is probably the most widely used design pattern, and it can be implemented in any object-oriented programming language.

Here is how it works in our example: Instead of creating an instance of the "Main" class with the "new()" operator, we let the class do it itself by calling the "getMain()" method. If there already is an instance of "Main" the method "getMain()" returns a reference to this instance, otherwise the instance is created automatically. On the main timeline "getMain()" is used in conjunction with calling the method "init()":

var defaultLanguage:String = "en";
Main.getMain().init(this, defaultLanguage);

"init()" takes two parameters, a movie clip and a string variable:

   // function init()
   public function init(main_mc:MovieClip, defaultLanguage:String): Void {
      _main_mc = main_mc;
      _defaultLanguage = defaultLanguage;
      initLanguageSelector();		
   }

In our example the movie clip is the root level of our Flash file, and the default language is defined by the timeline variable "defaultLanguage". If we were programming a real-world application we would probably provide the default language as an external variable to the Flash movie. This way we could load the same "main.swf" with different preselected languages. For simplicity, we leave it as it is.

At the end of "init()" the "initLanguageSelector()" method is called. This method populates the language selector ComboBox with the available languages ("de"/"German", "en"/"English") and preselects the default language:

   // function initLanguageSelector()
   private function initLanguageSelector(): Void {
      var languageDP:Array = [{data:"en", label:"English"}, {data:"de", label:"German"}];		
      _main_mc.language_cb.dataProvider = languageDP;		
      _main_mc.language_cb.addEventListener("change", Delegate.create(this, changeLanguage));
      // select default language
      for (var i:Number=0; i < languageDP.length; i++) {
         if (languageDP[i].data == _defaultLanguage) {
            _main_mc.language_cb.selectedIndex = i;
            break;			
         }
      }
      // dispatch change event
      _main_mc.language_cb.dispatchEvent({type:"change"});
   }

Again, for simplicity the availabe languages are hard coded into the array "languageDP" which is used as data provider for the ComboBox component. Usually you would provide the available languages also as external information to the Flash movie. (The advantage of providing this information externally is obvious: It let's you add new languages without recompiling the Flash movie!)

At the end of "initLanguageSelector()" we use "dispatchEvent()" to trigger the population of the ComboBox component with the month names. Every time the "change" event occurs the "changeLanguage()" method is called:

   // function changeLanguage()
   private function changeLanguage(eventObj:Object): Void {
      var lang:String = eventObj.target.selectedItem.data;
      LanguageManager.getLanguageManager().init(lang);
   }

This method takes the currently selected language and hands it over to the "LanguageManager", the second class in our sample application. So let's take a look at this class now.

Previous 2 of 4 Next