Tool

Photo by flattop341

Sometimes its good to have the right tools. One of my favorite classes in my Java days was the Hashtable class. It allowed you to store objects based on a key id. ActionScript somewhat allows the same with the Array object such as myArray[’myKey’] = myObject, but it does not allow for the same amount of robust tools as the Hashtable.

I written a Javascript, as2, and and as3 version of the Hashtable and still use it today. I thought it might be a good tool for someone’s toolbelt and thought I would share it. I have added some casting methods that are common such as nested DataContainers, MovieClips, Strings. etc. However, you can always extend this class to add more.

It works well when you have nested collections.

DataContainer Class

<br />
/***************************************************************<br />
* DataContainer Object<br />
*<br />
* This Class is used to store objects with a string key<br />
*<br />
* Company: NovoLogic<br />
* Developer: Kevin E. Crawford<br />
* Email: kcrawford@novologic.com<br />
*<br />
***************************************************************/<br />
package novologic.collections<br />
{<br />
// imports<br />
import flash.display.MovieClip;<br />
import flash.display.Sprite;</p>
<p>/**<br />
* NovoLogic DataContainer Class<br />
* This Class is used to store objects with a string key<br />
* @author		Kevin Crawford<br />
* @version		1.0.0<br />
*<br />
*/<br />
public class DataContainer extends Object<br />
{<br />
// Object Internal Variables<br />
private var _container:Array;<br />
private var _keys:Array;</p>
<p>/**<br />
* Constructor for Class<br />
*/<br />
public function DataContainer()<br />
{<br />
this.container = new Array();<br />
this.keys = new Array();<br />
}<br />
/**<br />
* Sets value for key value pair passed<br />
*<br />
* @param key:String<br />
* @param value:Object<br />
* @retrun void<br />
*/<br />
public function put(key:String, value:*):void<br />
{<br />
if ((key != null) && (value != null))<br />
{<br />
if (!this.contains(key))<br />
{<br />
this.keys[this.keys.length] = key.toLowerCase();<br />
}<br />
this.container[key.toLowerCase()] = value;<br />
}<br />
}</p>
<p>/**<br />
* gets array for iteration<br />
*<br />
* @retrun Array<br />
*/<br />
public function getArray():Array<br />
{<br />
return this.container;<br />
}</p>
<p>/**<br />
* gets value for the provided key as an Object<br />
*<br />
* @param key:String<br />
* @retrun Object<br />
*/<br />
public function get(key:String):*<br />
{<br />
return this.container[key.toLowerCase()];<br />
}</p>
<p>/**<br />
* gets value for the provided key as a String<br />
*<br />
* @param key:String<br />
* @retrun String<br />
*/<br />
public function getAsString(key:String):String<br />
{<br />
var str:String;<br />
try<br />
{<br />
str = String(this.get(key));<br />
}<br />
catch (e:Error)<br />
{<br />
str = ""<br />
}<br />
return str;<br />
}</p>
<p>/**<br />
* gets value for the provided key as a Number<br />
*<br />
* @param key:String<br />
* @retrun Number<br />
*/<br />
public function getAsNumber(key:String):Number<br />
{<br />
var num:Number;<br />
try<br />
{<br />
num = Number(this.get(key));<br />
}<br />
catch (e:Error) {<br />
num = 0;<br />
}<br />
return num;<br />
}</p>
<p>/**<br />
* gets value for the provided key as a Sprite<br />
*<br />
* @param key:String<br />
* @retrun Sprite<br />
*/<br />
public function getAsSprite(key:String):Sprite<br />
{<br />
var obj:Sprite;<br />
try<br />
{<br />
obj = Sprite(this.get(key));<br />
}<br />
catch (e:Error)<br />
{<br />
obj = new Sprite();<br />
}<br />
return obj;<br />
}</p>
<p>/**<br />
* gets value for the provided key as a MovieClip<br />
*<br />
* @param key:String<br />
* @retrun MovieClip<br />
*/<br />
public function getAsMC(key:String):MovieClip<br />
{<br />
var obj:MovieClip;<br />
try<br />
{<br />
obj = MovieClip(this.get(key));<br />
}<br />
catch (e:Error)<br />
{<br />
obj = new MovieClip();<br />
}<br />
return obj;<br />
}</p>
<p>/**<br />
* Gets value for the provided key.  If there is nothing stored for given key, then obj is stored as default and returned.<br />
*<br />
* @param key:String<br />
* @param obj:Object<br />
* @retrun Object<br />
*/<br />
public function getCreate(key:String, obj:Object):Object<br />
{<br />
var value:String = "";<br />
if (!this.contains(key))<br />
{<br />
this.put(key, obj);<br />
}<br />
value = this.container[key.toLowerCase()];<br />
return value;<br />
}</p>
<p>/**<br />
* gets value for the provided key as a DataContainer<br />
*<br />
* @param key:String<br />
* @return DataContainer<br />
*/<br />
public function getAsDC(key:String):DataContainer<br />
{<br />
var obj:DataContainer;<br />
try<br />
{<br />
obj = DataContainer(this.get(key));<br />
}<br />
catch (e:Error)<br />
{<br />
obj = new DataContainer();<br />
}<br />
return obj;<br />
}</p>
<p>/**<br />
* Returns keys Array<br />
* @return Array<br />
*/<br />
public function getKeys():Array<br />
{<br />
return this.keys;<br />
}</p>
<p>/**<br />
* Returns boolean indicating the DataContainer has data stored for provided key<br />
* @param key:String<br />
* @return Boolean<br />
*/<br />
public function contains(key:String):Boolean<br />
{<br />
return (this.container[key.toLowerCase()] != undefined);<br />
}</p>
<p>/**<br />
* Returns Boolean indicating if the DataContainer is empty of all data.<br />
* @return Boolean<br />
*/<br />
public function isEmpty():Boolean<br />
{<br />
return (this.keys.length == 0);<br />
}</p>
<p>/**<br />
* Clears all data from DataContainer<br />
* @return void<br />
*/<br />
public function empty():void<br />
{<br />
this.container = new Array();<br />
this.keys = new Array();<br />
}</p>
<p>/**<br />
* Getter for container Array<br />
* @return Array<br />
* */<br />
public function get container():Array<br />
{<br />
if (_container == null)<br />
_container = new Array();<br />
return _container;<br />
}<br />
/**<br />
* Setter for container Array<br />
* @param obj:Array<br />
* @return void<br />
* */<br />
public function set container(obj:Array):void<br />
{<br />
_container = obj;<br />
}</p>
<p>/**<br />
* Getter for keys Array<br />
* @return Array<br />
* */<br />
private function get keys():Array<br />
{<br />
if (_keys == null)<br />
_keys = new Array();<br />
return _keys;<br />
}<br />
/**<br />
* Setter for keys Array<br />
* @param obj:Array<br />
* @return void<br />
* */<br />
private function set keys(obj:Array):void<br />
{<br />
_keys = obj;<br />
}<br />
}<br />
}<br />

Example

<br />
var dc:DataContainer = new DataContainer();<br />
dc.put("jeff",new Object());<br />
dc.put("kevin", new Object());<br />
dc.put("ben", new Object());<br />
for (each obj:Object in dc.getArray()) {<br />
trace(obj.toString());<br />
}<br />

Adobe AIR

I have been adding several Flex snippets lately and thought I would write a post about AIR. Provided is a quick sample and download of an AIR Application that loads a web page using the HTMLLoader class. Loading an HTML page is very easy and their are ways to track history and browser to new URLs. The important thing to remember on the HTMLLoader is that the default size of it is 0×0. Thus, if you do you not provide a width and height then you will never see the html page.

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
creationComplete="init();"
layout="absolute" width="1024" height="768">

<mx:Script>
<![CDATA[
// imports
import flash.html.HTMLLoader;
import flash.net.URLRequest;
import mx.core.UIComponent;

// called on creationComplete
public function init():void
{
var htmlLoader:HTMLLoader = new HTMLLoader();
var urlReq:URLRequest = new URLRequest("http://www.novologic.com");

// HTMLLoader Class size defaults to 0,0 so you must size it.
htmlLoader.width = 1024;
htmlLoader.height = 768;

// load URLRequest
htmlLoader.load(urlReq);

// Create UIComponent to add html object to
var myComponent:UIComponent  = new UIComponent();
myComponent.addChild(htmlLoader);

// now add component to stage
this.addChild(myComponent);
}
]]>
</mx:Script>
</mx:WindowedApplication>

Download Application

picture by “visual velocity pc’s photostream

Flex has a very nice feature that allows you to break up your application called Modules. Modules can be created in FlexBuilder and are compiled out as their own SWF files. They can then be loaded into your main application via a ModuleLoader class. The ModuleLoader class is very similar to the SWFLoader but it loads Modules and not normal Flash/Flex SWF files. If your application has multiple pages or functional areas then you can minimize your initial application size be spreading the application out into their appropriate Modules. Then as you need them you can load them into your application. It is important to note that Modules can ONLY be loaded and viewed by a ModuleLoader class. If you try to run them by themselves they will not render.

Provided is a quick example that demonstrates two modules being loaded. Both modules are very similar but the first module inherits froma BaseModule Class. I experienced problems with this initially and found online that sometimes there is code confusion between modules. I was able to resolve this issue by making sure the currently installed module was removed from the application and was set to null so it could be garbage collected.

Source:

Main Application:


<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" width="400" height="330" backgroundGradientAlphas="[1.0, 1.0]">

<mx:Script>
<![CDATA[
import mx.modules.ModuleLoader;
public var moduleLoader:ModuleLoader = new ModuleLoader();

public function loadModule(source:String):void
{
if (this.contains(moduleLoader))
{
this.removeChild(moduleLoader);
moduleLoader.removeAllChildren();
moduleLoader = null;
}
moduleLoader =  new ModuleLoader();
moduleLoader.url = source;
moduleLoader.loadModule();
this.addChild(moduleLoader);
}
]]>
</mx:Script>

<mx:Button x="120" y="303" label="Module 1" id="modBtn1" click="loadModule('Module1.swf');"/>
<mx:Button x="204" y="303" label="Module 2" id="modBtn2" click="loadModule('Module2.swf');"/>

</mx:Application>

Module #1


<?xml version="1.0" encoding="utf-8"?>
<base:BaseModule xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:base="*" layout="absolute" width="400" height="300" backgroundColor="#941B1B">
<mx:Text x="101.5" y="30" text="Module #1" fontSize="36" color="#F5F8F9"/>
<mx:Button x="167" y="88" label="Show Alert" id="alertBtn" click="alert('HIT');" enabled="true"/>

</base:BaseModule>

Module #1 Super Class


package
{
import mx.controls.Alert;
import mx.modules.Module;

public class BaseModule extends Module
{
public function BaseModule()
{
}

public function alert(msg:String):void
{
try
{
Alert.show(msg,"Module Loader Test",Alert.OK);
}
catch (e:Error)
{
Alert.show("Error:\n" + e.toString(),"Module Loader Test",Alert.OK);
}
}
}
}

Module #2


<?xml version="1.0" encoding="utf-8"?>
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"     width="400" height="300" backgroundColor="#1E2A68">
<mx:Text x="101.5" y="30" text="Module #2" fontSize="36" color="#F5F8F9"/>
</mx:Module>

GPS Rating

GPS 8.0

Sprout is an online tool that will allow you to build Flash based widgets. This is very helpful in the marketing world for quickly and easily building banner emercials for the internet. They have a SDK that has support for Twitter, Seesmic, and Google forms.

The online tool is built in Flex and is a very impressive toolset. If you are interested in Flex or building simple flash widgets then I would check it out.

Sprout

Sprout Builder

AWS

Amazon sent out an email earlier this week announcing better technical support for their AWS products. They have had a few glitches the past few weeks and are proactively addressing those and providing a “Service Health Dashboard” for you see the current statuses of the AWS system. You can find the dashboard at the following url http://status.aws.amazon.com.

In addition, Amazon announced plans for tier support plans for a more personalized experience. I’m not high on this seeing that it should work right in the first place. However, you can find out more at this url: http://www.amazon.com/gp/browse.html?node=566801011

I am a big fan of AWS and think they have a very bright future. I think these outages are due to growing pains and will be resolved shortly. However, I’m not sure of any system that is always operational. :) In life things do happen but they do need to increase their support to make that as seldom as possible.