Jeżeli chcesz, aby Twoje aplikacje nie ograniczały się tylko do użytkowników polskojęzycznych, prędzej czy później staniesz przed problemem wprowadzenia obsługi wielu języków w swoich aplikacjach. Wielojęzyczność aplikacji często nie ogranicza się tylko do zmiany napisów, ale być może będziesz musiał również zmieniać obrazki i multimedia w zależności od wybranej wersji językowej. W niniejszym poście pokażę w jaki sposób wprowadzić lokalizację w aplikacji Flex na przykładzie prostego formularza.

Pierwszą rzeczą jaką musisz zrobić, to przygotowanie plików, w których umieścisz tłumaczenia. W tym celu w katalogu swojego projektu stwórz katalog, który będzie przechowywał tłumaczenia dla poszczególnych języków. Zwyczajowo katalog ten dostaje nazwę locale lub loc.

Utworzenie folderu lokalizacyjnego

Następnie, dla każdego języka, dla którego chcemy stworzyć tłumaczenie, tworzymy oddzielne katalogi dla każdej wersji językowej. W moim przykładzie będę mieć tylko dwie wersje językowe: polską oraz angielską (American English). W związku z tym tworzę dwa katalogi wewnątrz katalogu locale: odpowiednio pl_PL oraz en_US.

Tworzenie katalogów dla poszczególnych wersji językowych

Teraz przechodzimy do najważniejszej części, czyli utworzenia tłumaczeń. Pliki zapisujemy w utworzonych właśnie katalogach, nadając im rozszerzenia .properties. Każdy plik zawiera pary: klucz=wartość. Za pomocą klucza będziemy pobierać tłumaczenie we Flex, więc dla poszczególnych wersji językowych powinny być takie same dla każdej pary.

W moim przykładzie poszczególne pliki wyglądają następująco:

# locale/pl_PL/RegistrationForm.properties
registration_title=Rejestracja
submit_button=Wyślij formularz
personname=Imię
thanks=Dziękujemy za rejestrację
flag=Embed(”images/polish.jpg”)

# locale/en_US/RegistrationForm.properties
registration_title=Registration
submit_button=Submit Form
personname=Name
thanks=Thank you for your registration
flag=Embed(”images/american.jpg”)

Nazwa pliku jest dowolna, ale polecam takie wybieranie takich nazw, które w jakiś sposób łączą się w tłumaczoną treścią. W moim przypadku tworzę prosty formularz rejestracji, stąd ta nazwa. Jak pewnie zauważyłeś, w pliku .properties, oprócz zwykłych String-ów, możesz również odwoływać się do takich zasobów jak np. obrazki. Robimy to za pomocą dyrektywy Embed.

Obecnie struktura moich katalogów i plików wygląda następująco:

Struktura katalogów lokalizacyjnych we Flex

Teraz należy zmienić parę ustawień w samym Flex Builder, abyśmy mogli korzystać z naszych tłumaczeń w aplikacji. Generalnie, ponieważ w moim przykładzie nie mam zbyt dużo plików lokalizacyjnych, zdecyduje się na wkompilowanie tłumaczeń do aplikacji. Jeżeli pracujesz z dużą aplikacją, gdzie plików lokalizacyjnych może być bardzo dużo, możesz skorzystać z możliwości wczytywania plików podczas działania aplikacji.

Oto jaki czynności należy wykonać:

  1. Z menu górnego w Flex Builder wybierz: Project->Properties->Flex Build Path->Source Path

    Ustawienie source path w Flex Builder

  2. Wybierz opcję “Add Folder…” z menu po prawej stronie, następnie podaj ścieżkę do katalogu w którym znajdują się tłumaczenia (w moim przypadku wskazuje na katalog locale):

    Wskazanie katalogu z tłumaczeniami w Flex Builder

  3. Do ścieżki dopisz “/{locale}”, czyli w przykładzie ścieżka będzie zapisana następująco: locale/{locale}. Naciśnij ok. Dzięki takiemu zapisowi, wszystkie katalogi z tłumaczeniami będą dołączane i nie trzeba za każdym razem w source path dopisywać nowego katalogu dla kolejnego języka.
  4. Pozostaje nam jeszcze zmodyfikowanie argumentów kompilatora. Przejdź do zakładki Flex Compiler i w polu “Aditional compiler arguments” wpisz:

    -locale=en_US,pl_PL

    Kolejne wersje językowe dopisujemy po przecinku do opcji locale kompilatora. Naciśniu ok.

  5. Ostatnią czynnością jest utworzenie zlokalizowanych źródeł frameworka. Język polski niestety nie ma domyślnie swoich źródeł więc trzeba o to zadbać samemu. W tym celu:

    - otwórz konsolę
    - wejdź do katalogu bin w katalogu instalacyjnym sdk np. C:\Program Files (x86)\Adobe\Adobe Flash Builder 4\sdks\4.0.0\bin
    - dla każdej dodawanej instalacji języka uruchom narzędzie copylocale.exe, tak by skopiować pliki z istniejącej lokalizacji do nowo tworzonej np. copylocale en_US pl_PL
    - wejdź do lokalizacji FLEX_HOME\frameworks\locale (w moim przypadku to jest C:\Program Files (x86)\Adobe\Adobe Flash Builder 4\sdks\4.0.0\frameworks\locale) i sprawdź czy został utworzony katalog dla nowej lokalizacji, czyli w tym przykładzie pl_PL.

Skoro wszystko mamy już przygotowane, czas użyć lokalizacji w naszej małej aplikacji. Aplikacja będzie zawierała formularz z jednym polem tekstowym, przyciskiem wyślij. Powyżej formularza będzie się znajdować ComboBox, który pozwoli nam na przełączanie się między wersjami językowymi. Naciśnięcie przycisku wysyłającego formularz, spowoduje wyświetlenie okienka na warstwie potwierdzającego rejestrację. Oto kod naszej aplikacji:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
			   creationComplete="init()">
	<s:layout>
		<s:VerticalLayout/>
	</s:layout>
	<fx:Script><![CDATA[
		import mx.resources.ResourceBundle;
		import mx.controls.Alert;

		[Bindable]
		private var locales:Array = [ "pl_PL","en_US" ];

		private function init():void{
			resourceManager.localeChain = ["pl_PL"];
		}

		private function registrationComplete():void {
		    //wyświetlenie komunikatu potwierdzającego rejestrację
			Alert.show(resourceManager.getString('RegistrationForm', 'thanks'));
		}  

		private function comboChangeHandler():void {
		    //ustawienie odpowiedniej wersji językowej
			resourceManager.localeChain = [ localeComboBox.selectedItem ];

		}
	]]></fx:Script>

	<fx:Metadata>
		[ResourceBundle("RegistrationForm")]
	</fx:Metadata> 

	<mx:Image source="{resourceManager.getClass('RegistrationForm', 'flag')}"/>

	<mx:ComboBox id="localeComboBox"
				 dataProvider="{locales}"
				 change="comboChangeHandler()"/>

	<s:Label text="{resourceManager.getString('RegistrationForm', 'registration_title')}"/>
	<mx:Form>
		<mx:FormItem label="{resourceManager.getString('RegistrationForm','personname')}">
			<mx:TextInput/>
		</mx:FormItem>
	</mx:Form>
	<mx:Button id="buttonSubmit"
			   label="{resourceManager.getString('RegistrationForm','submit_button')}"
			   click="registrationComplete()"/>
</s:Application>

W powyższym przykładzie, do pobrania kluczy lokalizacyjnych korzystamy z klasy ActionScript – ResourceManager. Dzięki temu uzyskujemy sporą elastyczność i możliwość dynamicznego ładowania tłumaczeń, np. możemy zmieniać wersję językową podczas działania aplikacji.

Kiedy korzystasz z tej klasy, na początku musisz zdefiniować skąd będą pobierane tłumaczenia. Zwróć uwagę na linię 32-43, gdzie określam metadata (podaję nazwę pliku skąd mają być pobrane tłumaczenia).

Kolejne klucze lokalizacyjne pobieram za pomocą metody getString klasy ResourceManager:

gdzie pierwszym argumentem jest nazwa pliku z kluczami lokalizacyjnymi, a drugi nazwa klucza z tłumaczeniem.

Zwróć uwagę, w jaki sposób pobieram obrazek dla wersji językowej. W tym przypadku używam metody getClass, a nie getString(linia 36).

Zmiana wersji językowych następuje na zdarzeniu onchange kontrolki ComboBox. Do właściwości localeChain klasy ResourceManager dopisuje tablicę jednoelementową zawierającą Stringi reprezentujące określone wersje językowe, z których ma być pobierane tłumaczenie. W moim przypadku jest to tablica jednoelementowa.