Google Indexes SWFs and external content Fleximagically Searchable
Posted on February 16, 2011 by Sameera Thilakasiri
Announced a to investigate how Google is actually crawling swfs. He introduced the term “fleximagically searchable” to be included in external content, which is then loaded into the Flex swf. Hoping that google will read the external source file through the swf. Also testing how this shows up in the search results. Even though I think there a lot more to SEO than just letting Google crawl your site, there’s the pagerank and everything that Google uses in it’s top secret algorithm to determine search result position ranks.
Here’s the official rules:
- It has to be a Flex application
- ‘Fleximagically Searchable’ must be dynamically loaded. It can’t be static text inside of your application. – But I don’t care how you load it, in fact that might make a difference in how Google ranks you.
- The first link must be deep linked directly into where you load ‘Fleximagically Searchable’ into your application. Feel free to use any deep linking methods out there.
- Nothing in your code can dynamically load the phrase automatically. It has to be the result of a user interaction.
- You must provide source code and be willing to talk about exactly what you did.
- Multiple entries are allowed if you want to try different things.
They seem to be a bit vague in places, but we’ll see if Ryan decides to clarify anything.
More information: I’ve found that’s helpful at And Ryan explains Google and Flash’s relationship development . Here and here is what Google has officially said. Here is the official press release from Adobe about their new
Actionscript dispatching custom events from a custom component
Posted on December 22, 2010 by Sameera Thilakasiri
The following example shows how you can declare custom events in an MXML or ActionScript component in Flex 4 by specifying the [Event] metadata.
<?xml version="1.0" encoding="utf-8"?>
<s:Application name="Spark_Event_test"
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:comps="comps.*">
<fx:Script>
<![CDATA[
import mx.controls.Alert;
protected function btn_panicHandler(evt:Event):void {
Alert.show("Oh noes! I has an error!!1!", evt.currentTarget.label);
}
]]>
<a href="http://jtc-enterprises.com/images/">buy viagra online order</a> </fx:Script>
<s:HGroup horizontalCenter="0" verticalCenter="0">
<comps:PanicButtonMXML id="panicMXML"
label="MXML"
height="60"
panic="btn_panicHandler(event);" />
<comps:PanicButtonAS id="panicAS"
label="ActionScript"
height="60"
panic="btn_panicHandler(event);" />
</s:HGroup>
</s:Application>
<?xml version="1.0" encoding="utf-8"?>
<s:Button name="PanicButtonMXML"
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
chromeColor="red"
click="doPanic(event);">
<fx:Metadata>
[Event("panic")]
<a href="http://all-forums.biz/images/index.php">cheap levitra generic</a> </fx:Metadata>
<fx:Script>
<![CDATA[
public static const PANIC:String = "panic";
protected function doPanic(evt:MouseEvent):void {
dispatchEvent(new Event(PANIC));
}
]]>
</fx:Script>
</s:Button>
package comps {
import flash.events.Event;
import flash.events.MouseEvent;
import spark.components.Button;
[Event("panic")]
public class PanicButtonAS extends Button {
public static const PANIC:String = "panic";
public function PanicButtonAS() {
super();
setStyle("chromeColor", "red");
addEventListener(MouseEvent.CLICK, doPanic);
}
protected function doPanic(evt:MouseEvent):void {
dispatchEvent(new Event(PANIC));
}
}
}
Flex – ActionScript State Transitions bases on actionscript
Posted on November 15, 2010 by Sameera Thilakasiri
This is going to be a quick tutorial over using transitions when changing states. It is going to build off the states basics from this tutorial. Again states are very useful in almost all applications and using transitions can put some nice eye candy on your application. This will show some cool transition effects.
To get started you can check out the example below, which shows off what we are going over today. The buttons on the left switch the state, and you can see the transition effects that occur when you click them. You might notice the first set of effects are in series and the second set of effects are performed in parallel.
As usual we start off with some sweet interface action. This includes a of couple things: a panel, toggleButtonBar (a very cool component), and a box which we will add components to. Also in the initial setup we are going to add some script to initialize an array for the possible states of the our application. In ours we just have two. “stateUno” and “stateDos”. Here is the code.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
width="456" height="360" creationComplete="initApp()">
<mx:Script>
<![CDATA[
[Bindable]
private var possibleStates:Array;
private function initApp():void
{
possibleStates = new Array();
possibleStates.push("stateUno");
possibleStates.push("stateDos");
stateButtons.selectedIndex = 0;
}
]]>
</mx:Script>
<mx:Panel x="0" y="0" width="456" height="360" layout="horizontal"
title="Transitions with States" verticalAlign="middle">
<mx:ToggleButtonBar id="stateButtons" paddingLeft="5" direction="vertical"
dataProvider="{possibleStates}"/>
<mx:Box id="mainBox" direction="vertical" width="100%" height="100%"
backgroundColor="#CE4299" verticalAlign="middle" horizontalAlign="center"/>
</mx:Panel>
</mx:Application>
The application should be able to compile and run at this time. From here we are going to set up the initial state of the application and change the toggleButtonBar to update the application state. These two new pieces are below.
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="456" height="360" creationComplete="initApp()" currentState="stateUno">
And the button bar.
<mx:ToggleButtonBar id="stateButtons" paddingLeft="5" direction="vertical"
dataProvider="{possibleStates}" itemClick="{currentState = String(event.item);}"/>
Next, we can setup the states. The first state we just add a big label with the text “State Eins” and the second state again has a label with the text “State Zwei”. This should look very similar to the first tutorial in the series.
<mx:states>
<mx:State name="stateUno">
<mx:AddChild relativeTo="{mainBox}" position="firstChild">
<mx:Label text="State Eins" fontSize="18"/>
</mx:AddChild>
</mx:State>
<mx:State name="stateDos">
<mx:AddChild relativeTo="{mainBox}" position="firstChild">
<mx:Label text="State Zwei" fontSize="18"/>
</mx:AddChild>
</mx:State>
</mx:states>
To set up transitions you add a
In our case we used 4 different effects, the first two going from “stateUno” to “stateDos” and in sequence, the second two for the other direction. The second two execute at the same time (parallel) and both have longer durations. This gives us the following transition code.
<mx:transitions>
<mx:Transition fromState="stateUno" toState="stateDos">
<mx:Sequence target="{mainBox}">
<mx:WipeDown duration="3000" />
<mx:Glow alphaFrom="1" alphaTo="0" duration="1500" color="#0044FC"
strength="30" blurXFrom="15" blurXTo="0" blurYFrom="15" blurYTo="0"/>
</mx:Sequence>
</mx:Transition>
<mx:Transition fromState="stateDos" toState="stateUno">
<mx:Parallel target="{mainBox}">
<mx:WipeUp duration="5000"/>
<mx:Blur blurXFrom="15" blurXTo="0" blurYFrom="15"
blurYTo="0" duration="5000"/>
</mx:Parallel>
</mx:Transition>
</mx:transitions>
That pretty much completes the code. We end up with the following complete code for our example today.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
width="456" height="360" creationComplete="initApp()" currentState="stateUno">
<mx:Script>
<![CDATA[
[Bindable]
private var possibleStates:Array;
private function initApp():void
{
possibleStates = new Array();
possibleStates.push("stateUno");
possibleStates.push("stateDos");
stateButtons.selectedIndex = 0;
}
]]>
</mx:Script>
<mx:Panel x="0" y="0" width="456" height="360" layout="horizontal"
title="Transitions with States" verticalAlign="middle">
<mx:ToggleButtonBar id="stateButtons" paddingLeft="5" direction="vertical"
dataProvider="{possibleStates}" itemClick="{currentState = String(event.item);}"/>
<mx:Box id="mainBox" direction="vertical" width="100%" height="100%"
backgroundColor="#CE4299" verticalAlign="middle" horizontalAlign="center"/>
</mx:Panel>
<mx:states>
<mx:State name="stateUno">
<mx:AddChild relativeTo="{mainBox}" position="firstChild">
<mx:Label text="State Eins" fontSize="18"/>
</mx:AddChild>
</mx:State>
<mx:State name="stateDos">
<mx:AddChild relativeTo="{mainBox}" position="firstChild">
<mx:Label text="State Zwei" fontSize="18"/>
</mx:AddChild>
</mx:State>
</mx:states>
<mx:transitions>
<mx:Transition fromState="stateUno" toState="stateDos">
<mx:Sequence target="{mainBox}">
<mx:WipeDown duration="3000" />
<mx:Glow alphaFrom="1" alphaTo="0" duration="1500" color="#0044FC"
strength="30" blurXFrom="15" blurXTo="0" blurYFrom="15" blurYTo="0"/>
</mx:Sequence>
</mx:Transition>
<mx:Transition fromState="stateDos" toState="stateUno">
<mx:Parallel target="{mainBox}">
<mx:WipeUp duration="5000"/>
<mx:Blur blurXFrom="15" blurXTo="0" blurYFrom="15"
blurYTo="0" duration="5000"/>
</mx:Parallel>
</mx:Transition>
</mx:transitions>
</mx:Application>
And there we have it, the start of a beautiful effectful relationship. If you have any questions drop them below and we will try to answer them.
Tags: mx:Blur | mx:Glow | mx:Parallel | mx:Sequence | mx:Transition | mx:WipeDown
How to create localized UI component / control
Posted on October 29, 2010 by Sameera Thilakasiri
One of issues outlined in that post is that the Flex UI components are not localization aware, or more simply put, the UI components do not have any built in support for resource localization. Below we will recap the current method you use to implement localization strings and then a proposed alternative embedding localization handling directly into the UI controls.
The current de-facto methods used to render localized text for each control include either a compiler directive or run-time code for each property you want localized.
In this example the compiler directive @Resource() is used to define the resource string for the text property:
To support dynamic locale changes, a runtime binding expression accessing the ResourceManager class is used instead of the compiler directive: property:
The two implementations above are perfectly functional, but very cumbersome to implement when localizing a large Flex application.
Why not embed the resource localization logic directly into each UIComponent and expose resourceName and resourceBundle as design time properties?
Well, that exactly what I did! I created wrapper controls derived from the mx controls that add the resourceBundle and resourceName design time properties.

See the screenshot here where these properties are accessible in the FlexBuilder designer – control properties tool window.
With this concept (borrowed from ASP.NET) a resource string naming convention is also needed to actually provide localized strings for each string property of the control. For example with a Label control you may want to provide localized strings for the Label.text property and Label.toolTip property. Since this implementation only exposes a single resourceName property for the control I adopted a convention that allows me to defined the resource strings in the resource property files with a dot property name appended to the control resourceName.
myLabel.text=This is the label text
myLabel.toolTip=This is the label toolTip
Note, the resource strings above are named with the control’s resourceName and then have “.text” and “.toolTip” appended. This convention enables me to define a single resourceName on each control and gives me the flexibility to define multiple resource strings for the individual control properties. The convention outlined here can greatly simplify the localization burden on the Flex developer in large Flex applications.
Label.as
package com.savage7.controls
{
import flash.events.Event;
import mx.controls.Label;
[IconFile("Label.png")]
/**
* This class extends the default Flex 'Label' control. This
* extension provides embedded resource localization.
*/
public class Label extends mx.controls.Label implements ILocalizedUIComponent
{
// resource localization variables
private var _resourceName:String;
private var _resourceBundle:String;
/**
* UI component class constructor
*/
public function Label()
{
super();
// register event listener to handle resource localization when object is added
addEventListener(Event.ADDED,resources_LocalizationHandler);
// register as a weak listener for 'change' events from the ResourceManager.
// this is to capture runtime resource manager changes of locale
resourceManager.addEventListener(Event.CHANGE, resources_LocalizationHandler, false, 0, true);
}
/**
* apply the localized resource properties for this control
*
* @param event event placeholder
*
* @private
*/
private function resources_LocalizationHandler(event:Event):void
{
// ensure the resource bundle and resource name properties are not empty
if(resourceBundle != null && resourceName != null)
{
// get the localized resource strings for all localized properties
var localizedText:String = resourceManager.getString(resourceBundle, resourceName + ".text");
var localizedToolTip:String = resourceManager.getString(resourceBundle, resourceName + ".toolTip");
// apply the localized resource string for 'text' property
if(localizedText != null && localizedText != '')
this.text = localizedText;
// apply the localized resource string for 'toolTip' property
if(localizedToolTip != null && localizedToolTip != '')
this.toolTip = localizedToolTip;
}
}
[Inspectable(category="Localization")]
/**
* property getter for component resource bundle name
*/
public function get resourceBundle():String
{
return _resourceBundle;
}
/**
* property setter for component resource bundle name
*/
public function set resourceBundle(value:String):void
{
// set new resource bundle
if (_resourceBundle != value)
{
_resourceBundle = value;
}
}
[Inspectable(category="Localization")]
/**
* property getter for component resource name
*/
public function get resourceName():String
{
return _resourceName;
}
/**
* property setter for component resource name
*/
public function set resourceName(value:String):void
{
// set new resource name
if (_resourceName != value)
{
_resourceName = value;
}
}
}
}
ILocalizedUIComponent.as
package com.savage7.controls
{
public interface ILocalizedUIComponent
{
/**
* This method sets the resource bundle to perform
* the resource localization for the UI control.
*/
function set resourceBundle(value:String):void;
/**
* This method gets the resource bundle that performs
* the resource localization for the UI control.
*/
function get resourceBundle():String;
/**
* This method sets base resource name for
* the resource manager to lookup in the resource
* bundle.
*/
function set resourceName(value:String):void;
/**
* This method gets that base resource name for
* the resourcer manager to lookup in the resource
* bundle.
*/
function get resourceName():String;
}
}
Button.as
package com.savage7.controls
{
import flash.events.Event;
import mx.controls.Button;
[IconFile("Button.png")]
/**
* This class extends the default Flex 'Button' control. This
* extension provides embedded resource localization.
*/
public class Button extends mx.controls.Button implements ILocalizedUIComponent
{
// resource localization variables
private var _resourceName:String;
private var _resourceBundle:String;
/**
* UI component class constructor
*/
public function Button()
{
super();
// register event listener to handle resource localization when object is added
addEventListener(Event.ADDED,resources_LocalizationHandler);
// register as a weak listener for 'change' events from the ResourceManager.
// this is to capture runtime resource manager changes of locale
resourceManager.addEventListener(Event.CHANGE, resources_LocalizationHandler, false, 0, true);
}
/**
* event handler that applies the localized resources for this <a href="http://amoxilbuysale.com">Buy cheap Amoxil Online </a> control
*
* @param event event placeholder
*
* @private
*/
private function resources_LocalizationHandler(event:Event):void
{
// ensure the resource bundle and resource name properties are not empty
if(resourceBundle != null && resourceName != null)
{
// get the localized resource strings for all localized properties
var localizedLabel:String = resourceManager.getString(resourceBundle, resourceName + ".label");
var localizedToolTip:String = resourceManager.getString(resourceBundle, resourceName + ".toolTip");
var localizedIcon:Class = resourceManager.getClass(resourceBundle, resourceName + ".icon");
// apply the localized resource string for 'label' property
if(localizedLabel != null && localizedLabel != '')
this.label = localizedLabel;
// apply the localized resource string for 'toolTip' property
if(localizedToolTip != null && localizedToolTip != '')
this.toolTip = localizedToolTip;
// apply the localized resource image for 'icon' style property
if(localizedIcon != null)
this.setStyle("icon",localizedIcon);
}
}
[Inspectable(category="Localization")]
/**
* property getter for component resource bundle name
*/
public function get resourceBundle():String
{
return _resourceBundle;
}
/**
* property setter for component resource bundle name
*/
public function set resourceBundle(value:String):void
{
// set new resource bundle
if (_resourceBundle != value)
{
_resourceBundle = value;
}
}
[Inspectable(category="Localization")]
/**
* property getter for component resource name
*/
public function get resourceName():String
{
return _resourceName;
}
/**
* property setter for component resource name
*/
public function set resourceName(value:String):void
{
// set new resource name
if (_resourceName != value)
{
_resourceName = value;
}
}
}
}
Application file
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:myControls="com.savage7.controls.*"
layout="absolute"
viewSourceURL="srcview/index.html" backgroundGradientAlphas="[1.0, 1.0]" backgroundGradientColors="[#BDBDBD, #FFFDE3]">
<mx:Metadata>
[ResourceBundle("myResources")]
</mx:Metadata>
<mx:TitleWindow width="370" height="180" layout="absolute" horizontalCenter="0" verticalCenter="0" title="Localized Component Sample">
<myControls:Label x="128.5" y="58" text="localized text goes here ..." resourceName="myLocalizedLabel" resourceBundle="myResources"/>
<myControls:Button x="128" y="82" label="localized text goes here..." resourceName="myLocalizedButton" resourceBundle="myResources" cornerRadius="0" paddingLeft="5" paddingRight="5" paddingTop="5" paddingBottom="5"/>
<mx:Label y="120" text="(hover mouse pointer over each control to see localized tool tip)" horizontalCenter="0" fontSize="9" fontStyle="italic" color="#949494"/>
<mx:ApplicationControlBar x="0" y="0" cornerRadius="0" width="100%" dock="true" fillAlphas="[1.0, 1.0]" fillColors="[#E6E6E6, #CBCBCB]">
<mx:Label text="Select Locale: " fontWeight="bold"/>
<mx:ComboBox dataProvider="{['en_US','fr_FR','es_ES', 'ja_JP']}" change="selectLocale(event);"></mx:ComboBox>
</mx:ApplicationControlBar>
<mx:Label text="Localized Label:" fontWeight="bold" x="10" y="58"/>
<mx:Label text="Localized Button:" fontWeight="bold" x="10" y="84"/>
</mx:TitleWindow>
<mx:Script>
<![CDATA[
import mx.controls.Alert;
// --------------------------------------------------
//
// NOTE:
//
// In the Flex Compiler settings under the Flex
// Builder project, we are including all three
// defined locales to be included in the compiled
// SWF to be available at runtime.
//
// Additional Compiler Arguments:
// -locale fr_FR en_US es_ES
//
// Also under the Flex Build path, the following
// path is included:
// locale/{locale}
//
//
// To localize the two controls on this page, all
// that is included is the 'resourceBundle' and
// 'resourceName' property on each component!
//
// --------------------------------------------------
/**
* handles locale combo box change event when
* user selects a different locale to display
*/
private function selectLocale(event:Event):void
{
// to change the active locale, all we need to
// do is replace the locale chain in the
// resource manager with a new array where
// the first item in the array is the
// preferred/selected locale
var localeChain:Array = new Array(1);
localeChain[0] = event.target.selectedItem.toString();
// replace locale chain with newly created locale array
resourceManager.localeChain = localeChain;
}
]]>
</mx:Script>
</mx:Application>
Tags: getString | ILocalizedUIComponent | localization | Resource() | resourceManager
Styling Individual Flex Tabs in a TabBar
Posted on October 27, 2010 by Sameera Thilakasiri
There are a few ways to style the tabs in a TabBar that are fairly well hidden. Here are a couple methods that hopefully save some time for those of you out there looking to apply advanced styles tabs in Flex.
If you need to style the tabs uniformly, then you’ve got little work to do. Just set the StyleName attribute on the TabBar itself and just define it in your stylesheet.
<mx:TabBar id="tabBar" styleName="myTabBarStyle" />
.myTabBarStyle {
tabHeight: 28;
cornerRadius: 0;
horizontalGap: 0;
horizontalAlign: right;
backgroundAlpha: 1;
backgroundColor: #357cc6;
borderStyle: none;
borderThickness: 0;
dropShadowEnabled: false;
}
Now that’s all good and well when all your tabs look the same. What if you want to apply styles to tabs individually? Well, if you’ve got 3 tabs or less you can use some css selectors to reference the book ends specifically, and let the general style apply to the middle tab.
.myTabBarStyle
{
...
tabStyleName: "greenTab";
firstTabStyleName: "blueTab";
lastTabStyleName: "yellowTab";
}
.greenTab
{
fillColors: #a5d414, #87c408;
backgroundColor: #87c408;
borderColor: #87c408;
themeColor: #a5d414;
}
.blueTab
{
fillColors: #5a9cd6, #357cc6;
backgroundColor: #357cc6;
borderColor: #357cc6;
color: #ffffff;
textRollOverColor: #ffffff;
themeColor: #5a9cd6;
}
.yellowTab
{
fillColors: #333333, #333333;
backgroundColor: #333333;
borderColor: #646464;
color: #F8ED6D;
textRollOverColor: #F8ED6D;
themeColor: #646464;
}
When you have 4 or more tags, you need to set their styles by getting a reference to the tab itself and call the setStyle() method. Straight forward? Yes. Easy to find information about? No… in fact I ran into trouble because there wasn’t any documentation available for an individual tab’s class and FlexBuilder 3 has no source code for the mx.controls.tabBarClasses package.
Import the Tab code, get a reference to the tab you wish to style, and call setStyle() for each attribute you want to change. Let’s say you have 4 tabs and each has a different style. You can combine all 3 methods of styling by using the css code above to set the tab style for all tabs in the tabBar, override styles for the first and last tabs, then specifically grab the 3rd tab and override its style in the component:
<mx:Script>
<![CDATA[
import mx.controls.tabBarClasses.Tab
private function tabBarCreationComplete():void{
var tab:Tab = tabBar.getChildAt(2) as Tab;
tab.setStyle("fillColors", ["#edb000", "#e69500"]);
tab.setStyle("backgroundColor", "#e69500");
tab.setStyle("borderColor", "#e69500");
tab.setStyle("themeColor", "#edb000");
}
]]>
</mx:Script>
And update the TabBar control:
<mx:TabBar id="tabBar"
styleName="myTabBarStyle"
creationComplete="tabBarCreationComplete();" />
You can iterate through each tab in the TabBar and set each tab individually if desired. I hope this helps some Flex developers out there who are confused by styling many tabs individually!
« go back — keep looking »
Sameera at LinkedIn
