Friday, August 31, 2007

moock 's blog about how to Use Flash CS3 V3 Components in Flex Builder

nice post, see here

good resource about Java Memory Management

Alan Berg wrote an easy to understand article about the Java Memory Management , check it out from here

JVM Settings

c collection of JVM setting, You can find here

Thursday, August 30, 2007

IO Error Caused By URLLoader in Flex

we have same issue as Bruce Philips
described on his blog, he has a solution for it . go here to check.

Binding in AS

on Raghu 's blog, i found an example to Binding in MXML & AS

nice example of AdvancedDatagrid

there is a good example at Switch On The Code of advanced datagrid

check this out : http://blog.paranoidferret.com/index.php/2007/08/29/flex-fun-advanced-datagrid-topics/

Cairngorm Webservice and HTTPService Example

I found it on neil's blog

take a look at http://nwebb.co.uk/blog/?p=118

Monday, August 27, 2007

CSS in flex

on Ted's blog, i found a tutorial how to use runtime css in flex

go here

good AS3 xml e4x tutorial

Roger Braunstein wrote a good tutorial of using xml e4x in action script 3.0

go here and have a look

Wednesday, August 15, 2007

more flexbuilder short cut key

1. Ctrl +Shift after : in MXML tag

2.Ctrl+Shift+ Space. inside function () to see parameters

Tuesday, August 7, 2007

Using Flex™ 2.0.1 Language Reference offline

sourec : here

After playing with HTML Help Workshop for some time I have managed to compile the Flex™ 2.0.1 Language Reference in CHM format (CHM files are extensively used for documentation and help files).

This is similar to Help Window we get with the Flex Builder. FlexBuilder has a limitation that it doesnt allow using help unless FlexBuilder is open. This is where such a CHM is useful. It also has got search functionality and thus serves the purpose. Here are the steps to create a CHM file:

1. Download Flex Language Reference from livedocs or alternatively take the zip from {Flex Builder installed location}/plugins/doc.zip (thanks to Sreenivas for pointing out this) and unzip it.
2. Say the docs are located on PATH/flexapi.
3. Download HTML Help Workshop from the following link and install it.
4. Open HTML Help Workshop and go to File -> New and select Project. It will start a wizard.
5. Give a name (say flex2.0.1_asdoc ), when asked for name of the project file.
6. After clicking next, select HTML files checkbox (because we already have our doc created)
7. In the next dialog box, press Add and give path of the index.html (PATH/flexapi/index.html)
8. Click Finish to finish the wizard

Press Save to save the project and compile the project and click View Compile file button on the toolbar. You will find that the file created is broken because it has not included all the files. So we need to fix this. Actually HTML Help workshop has a limitation that it doesn’t pick files specified in CSS stylesheets and javascripts. Follow these steps to fix this:

1. Close the project. And go to the project folder and open the .hhp file in any editor. You will find a [FILES] section in the file with index.html listed.
2. Just do a find to find all the class-list.html files in the PATH/flexapi/ folder and add all those class-list files (with full path) after index.html
3. Save this template.html file in the PATH/flexapi/ folder.
4. Add template.html also to the list of [FILES] in .hhp file.

Now open the project again and re-compile the project. Use the CHM created when you are offline and not using FlexBuilder.

Here is a screenshot of CHM file I got. You can also take advantage of the search functionality and here is a screenshot for this.

Monday, August 6, 2007

Sorting an ArrayCollection using the SortField and Sort classes

http://blog.flexexamples.com/2007/08/05/sorting-an-arraycollection-using-the-sortfield-and-sort-classes/

10 Tips For Working With Cairngorm

source : here

These apply to Flex 2.0.1 with any version of Cairngorm. Since people’s programming background varies in Flex, these are not facts, just my opinions based on my experiences using ARP & Cairngorm for over 2 years. Furthermore, there are alternatives to Cairngorm, I just cannot try them as much as I like. Now that I’m doing product work, I can’t just “try this framework on this new project”. I live in the same code base longer supporting existing clients, and can’t do dramatic re-factoring without getting fired.

1. If Cairngorm looks complicated, don’t worry, it is, and you’re not alone

“Bunch of code on _root vs. all of these classes and conventions? This’ll take forever!”. It takes getting used to. I felt “comfortable with Cairngorm” on my 4th project with it. To this day, I still mod it though, and try different things. As more people come into Flex, there are more cool ideas and techniques floating around.

2. If it feels like it’s taking a long time just to do something in Cairngorm, it does.

“OMFG… 3 classes just to execute what would take me 1 line in Flash? Lamesauce!”. Code gen can help here, at least at the beginning of the project.

3. Only Commands set data on the Model; you can break this, just don’t if you can help it.

In Model View Controller, only the Controller sets data on the Model. In this case, the Commands are the Controller (usually), and as such, setting ModelLocator data is their job, and their job alone. If data is getting f’d up, you immediately know it’s in the Command. You never have to question “who’s setting my data, where, and when?”.

4. Delegates make the server call and parse the data (sometimes in a Factory)

This has only happened once in my career: I was hitting PHP for the back-end, parsing XML, and in the middle of the project, we switched to OpenAMF and Java where I had to parse objects. Using Delegates means you only have to re-code your Delegates, not the rest of your app. The Commands still get the same data.

The only reason I use Factories is because A) parsing can be a lot of code and you don’t want to make your Delegates look more complicated than they are and B) you can share parsing routines easily in the same Factory class.

5. If you see a Command parsing data, it’s coded wrong.

Parsing is differently from filtering, modifying, and assembling. IE, making Value Objects from XML should be done in the Delegate, not the Command. Making associations between ArrayCollections, injecting default values are both ok. Remember, the key here is if the Command is touching raw server data, you’re either not using Delegates correctly, or have AMFPHP/FDS/WebOrb working correctly, hehe.

6. There are 3 ways to use Commands & Delegates. I prefer A because it’s consistent, leads to short class files, and is very explicit.

A) For every use case, you make 1 Command and 1 Event. This can sometimes also mean 1 Delegate. (ie, LoginEvent, LoginCommand, LoginDelegate)

B) For every use case that’s related, you can consolidate them into a package path. So, Login, ChangePassword, and ForgotPassword would all be in the same class. You’d then use constants to determine which one to run. (ie, LoginEvent has LOGIN, CHANGE_PASSWORD, and FORGOT_PASSWORD as String constants. Your LoginCommand has a switch statement which determines which one to run. Your LoginDelegate has 3 methods; login, changePassword, and forgotPassword that your Command can use.

C) Variances on B. Maybe 1 Event and 1 Command, but multiple Delegates. This is not a cop-out bullet item, rather, I’ve seem many derivatives that can all be traced back to “B with mods”.

7. ViewLocators are considered bad practice.

That said, there are developers who still love and use them. The use case, however, is valid: Having a View “know” when something in a Command has occurred. I use callbacks, some set data on the Model to trigger callbacks on the Views (maybe via a setter function), and some use addEventListener in tandem with CairngormEventDispatcher.

8. ViewHelpers are considered bad practice.

That said, there are developers who love the idea of “code behind”. I’ve yet to see a consistent theme on the blogs and mailing lists. There are 2 reasons that are common:

A) They don’t like mixing ActionScript & MXML.

B) They want to separate their View’s from their “View controller code”

Some use the script tag to point to an external file (lame in my opinion; you have to define your controls as member variables and you end up with twice as many View classes). Some use inheritance where you extend your GUI MXML. Others take the reverse, and have the GUI MXML extend the ActionScript ViewHelper. Some will even take the Composition over extending MovieClip approach I’ve seen a lot of coders do in Flash. Instead of their ViewHelper extending a view class, it’ll instead take a UIComponent as a parameter, say in an init method, and use that UIComponent via composition.

To me, you’ll get over it as you get more comfortable with Flex. Code your components in MXML with code up top in a script tag. If you really need efficiency, or start doing some really low-level, abstract type classes, then you can start coding your components in ActionScript. If you want to get stuff done today, use MXML.

9. Don’t use flash.net.Responder, use mx.rpc.Responder instead.

Yes, it’s frustrating because Flex 2.0.1 doesn’t give you the source, but in my opinion, Flex Builder doesn’t handle same-named classes very well. Just go with what Flex uses, and call it a day. If someone requires flash.net.Responder, code a wrapper to bring him into Flex land. “Sir… you need a tie to get into this restaurant. We have one in the back, one moment.”

10.Try not to have View’s use CairngormEventDispatcher (or Events that extend CairngormEvent use event.disaptch()).

Instead, have those deeply nested views dispatch events. Either bubble them up so a master controller View can then fire off Cairngorm events, or bucket-brigade them up. The most common scenario is itemRenderers that are a custom class in DataGrids.

You:

- make the itemRenderer class. If you have something in it that is clickable, dispatch a custom click event. Make it bubble.

- extend the DataGrid that uses your custom itemRenderer, and put the custom event in the metadata up top. Otherwise, the class that houses the DataGrid will only be allowed to subscribe to the event via MXML, only ActionScript. If you use MXML, it’ll fail to compile because the DataGrid doesn’t have that event in it’s source code.

It may feel cool at first to have a LoginForm for example dispatch the LoginEvent, but if you need to use it for a different purpose elsewhere, you’re screwed; it’s hard-coded to use a specific CairngormEvent. This applies to all components. Encapsulate your components and do your best to do what BT does: “bubble it up”.

Removing duplicate items from an array using the Array.filter() method

source : here

<?xml version="1.0" encoding="utf-8"?>

<
mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" verticalAlign="middle" backgroundColor="white" creationComplete="init()">

<
mx:Script>
<![
CDATA[
private var
keys:Object = {};

/**
* Called by the Application container's creationComplete
* event handler. This method creates a new Array object
* which will be used as a data provider as well as a
* filtered view of that array which does not contain
* duplicated items.
*/

private function
init():void {
/* Create a dummy data source with some semi-random
data. */

var
arr:Array = [];

arr.push({data:1, label:"one"});
arr.push({data:1, label:"one"});

arr.push({data:1, label:"one"});
arr.push({data:1, label:"one"});

arr.push({data:2, label:"two"});
arr.push({data:2, label:"two"});

arr.push({data:2, label:"two"});
arr.push({data:1, label:"one"});

arr.push({data:3, label:"three"});
arr.push({data:3, label:"three"});

/* Filter the original array and call the
removeDuplicates() function on each item
in the array. */

var
filteredArr:Array = arr.filter(removedDuplicates);

arrColl.source = arr;
dedupedArrColl.source = filteredArr;
}


/**
* This method is used to filter an array so that no
* duplicate items are created. It works by first
* checking to see if a keys object already contains
* a key equal to the current value of the item.data
* value. If the key already exists, the current item
* will not be readded to the data provider. If the key
* does not already exist, add the key to the keys
* object and add this item to the data provider.
*/

private function
removedDuplicates(item:Object, idx:uint, arr:Array):Boolean {

if
(keys.hasOwnProperty(item.data)) {
/* If the keys Object already has this property,
return false and discard this item. */

return
false;
}
else {

/* Else the keys Object does *NOT* already have
this key, so add this item to the new data
provider. */

keys[item.data] = item;
return
true;
}
}
]]>

</
mx:Script>

<
mx:ArrayCollection id="arrColl" />
<
mx:ArrayCollection id="dedupedArrColl" />

<
mx:HBox>
<
mx:VBox>
<
mx:Label text="Original ({arrColl.length} items):" />

<
mx:List dataProvider="{arrColl}" />
</
mx:VBox>
<
mx:VBox>

<
mx:Label text="Filtered ({dedupedArrColl.length} items):" />
<
mx:List dataProvider="{dedupedArrColl}" />

</
mx:VBox>
</
mx:HBox>

</
mx:Application>

Saturday, August 4, 2007

AS3 Data Structures For Game Developers

source : http://lab.polygonal.de/ds/

svn: http://as3ds.googlecode.com/svn/trunk/ as3ds

Description

‘AS3 Data Structures For Game Developers’ is a package containing common data structures useful for flash game programming and application development. The project was started because I wanted a unified library which I could reuse in my games.
Design Decisions

I have tried to provide just the bare algorithms, coupled with a minimum set of methods I think are most useful to work with. Simplicity and performance were the key guidelines for the whole package. Therefore,

- all structures are untyped and can be fed with any kind of data. This makes usage more flexible and simple, since you don’t have to create special container classes which extend base classes and/or implement interfaces.

- I’m often not following strict design patterns and OOP-practices. For example, to access a classes’ property, I just define it as public instead of writing functions to read/write the property (which is also faster).

- all classes reside in a single package, simply because its hard to separate them - e.g. a linked list can bee seen as a tree, and a tree on the other side is a loose linked list.

- many structures use custom code rather that utilizing the data structure classes themselves - for example the graph structure could be implemented by using the linked list and queue classes, but a plain array works faster behind the scenes.
Collections

Almost all classes implement the Collection interface, which defines the following methods:

contains(obj:*), for checking if an item exists
clear(), for removing all items
getIterator(), for creating an iterator object to step through all items
size, the total number of items and
toArray(), which simply converts the structure into an array.
Using Iterators

Every class that implements the Collection interface is also able to create an iterator object using the getIterator() method. Once you have an iterator, you can walk through the data and read/write the values like so:

var myItr:Iterator = getIterator();
var value:*;

//read all values
while (myItr.hasNext())
{
value = myItr.next();
}

//write new value
myItr.start();
while (myItr.hasNext())
{
myItr.data = "newValue";
next();
}

//the same with a for loop
for (myItr.start(); myItr.hasNext(); myItr.next())
{
value = myItr.data;
}

Keep in mind that an iterator implies no order in which the items are processed. Some classes also support a more complex iterator like the linked list or the tree. This is necessary because you can iterate in more directions (forth, back, up, down..). You get those iterators by performing a downcast or simply calling a special method:

var listItr:ListIterator = myLinkedList.getIterator() as ListIterator;
var listItr:ListIterator = myLinkedList.getListIterator();

The Structures
Multi-Dimensional Arrays

The library contains a two-dimensional and three-dimensional array. They are both implemented by a single linear array rather than nested arrays. This is the fastest method in flash to simulate multi-dimensional arrays and outperforms the nested array method because multiple array lookups are slower compared to one lookup combined with a simple arithmetic expression (which you can also often precompute in the outer loop). The most obvious application would be a tilemap in 2d or a layered tilemap in 3d.
Queue

This is also called a FIFO structure (First In - First Out). The queue comes in two variations, which have the same methods, but differ in their implementations: There is the arrayed queue, which obviously uses an array internally, and the linked queue, which is build upon a linked list. They are both very similar, except that the arrayed version has a fixed size and is faster.
A common application would be a command queue - imagine you have a unit in a strategy game and apply many commands which the unit should follow. All commands are enqueued and afterwards dequeued and processed in order.
Stack

Also commonly know as a FILO structure (First In - Last Out). Like the queue, this comes in two flavors: arrayed and linked. A stack is often not used directly, but a very important concept in programming. Please note, that a queue and a stack are not real structures, because they just define how data is accessed rather then stored.
Tree

A node-based structure. Every tree starts from a single node, called the root node. The root node can contain any number of child nodes, and every child node can again contain children. A tree node with no children is called a leaf node. In fact if you draw the nodes of a tree it looking like a real tree with branches. The AS3 display architecture is also a tree structure, so you could use this to manage your display objects and update them by traversing through the tree. Also, this is useful for decision trees, BVHs, storing a plot line or storing data recursively by applying the composite pattern.
Binary Tree

This is just a specialized kind of tree where each node is only allowed to have up to two children, called the left and right node. Binary trees are very often used for parsing input data, for example arithmetic expressions or when building a scripting system.
Binary Search Tree (BST) and Hash Table

Both structures store data that can be retrieved quickly by using a key. The method however differers greatly: The BST uses a recursive approach to split up large amounts of data into smaller sets. A hash table stores sparse key-based data using a hash-key in a small amount of space.
Linked Lists

A linked list is similar to an array. The main difference is that in an array, each cell contains just the data and is accessed by an index. A linked list consists of several node objects, which in addition to storing the data, manage a reference to the next node (singly linked) or to the next and previous node (doubly linked) in the list. Think of it as a more natural approach to work with sequential data.
Other benefits are that you can insert and remove data quickly by just calling the appropriate method on the node itself - you don’t have to manage array indexes. Also in AS3 object access is faster than array access, so it competes very well in terms of performance when iterating over the list.
Heap and Priority Queue

A Heap is a special kind of binary tree in which every node is bigger than its child nodes. Whatever you throw into a heap, it’s automatically sorted so the item with the ‘most significant’ value (depending on the comparison function) is always the front item. A priority queue is build upon the heap structure, and can manage prioritized data - which can be used in limitless ways.
Graph

A graph is a loose node-based structure. Nodes are connected with arcs, and every node can point to any other node. They can also point to each other creating a bi-directional connection. It is essential for path finding, AI, soft-body dynamics with mass-springs systems and a lot more.
Bit Vector

A bit vector is some kind of array in which you can store boolean values (true/false - 1/0) as close as possible without wasting memory. I currently can’t think of a reasonable application, because usually you should have enough memory - but it’s nice to have because it shows basic bit masking operations.

Duplicating images using the Bitmap and BitmapData classes

original author : Peter deHaan

original source : Peter deHaan's blog

== quote from his blog ==
In a previous post (Finding a pixel’s color value using the Bitmap classes and getPixel()) we looked at copying an image so we could build a simple color-picker like app. In this post, we explore duplicating a loaded image and copying it into a TileList control. Each time you press the “Copy image” button, a new instance of the source image is created and added to the TileList control’s data provider.

As an added bonus, we also create a custom item renderer consisting of an HBox container, Image control, and a Label control.

Full code after the jump.

<?xml version="1.0" encoding="utf-8"?>

<
mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" verticalAlign="middle" backgroundColor="white">

<
mx:Script>
<![
CDATA[
import
mx.collections.ArrayCollection;

[
Bindable]

private var
arrColl:ArrayCollection = new ArrayCollection();

private function
dupeImage(source:Image):void {

var
data:BitmapData = Bitmap(source.content).bitmapData;

var
bitmap:Bitmap = new Bitmap(data);

arrColl.addItem({image:bitmap, label:"item #" + (arrColl.length + 1)});
}
]]>

</
mx:Script>

<
mx:HBox>
<
mx:Panel title="Source image">

<
mx:HBox verticalAlign="middle" horizontalAlign="center" width="100%" height="100%">

<
mx:Image id="img1" source="assets/logo.png" />
</
mx:HBox>

<
mx:ControlBar>
<
mx:Button label="Copy image" click="dupeImage(img1)" />

</
mx:ControlBar>
</
mx:Panel>

<
mx:TileList id="tileList" dataProvider="{arrColl}" width="300" height="200" columnCount="4" verticalScrollPolicy="on">

<
mx:itemRenderer>
<
mx:Component>
<
mx:VBox>
<
mx:Image source="{data.image}" />

<
mx:Label text="{data.label}" />
</
mx:VBox>

</
mx:Component>
</
mx:itemRenderer>
</
mx:TileList>

</
mx:HBox>

</
mx:Application>

Setting status bar message in AIR Application

source : here

Here is a small tip to set status bar messages in AIR Application.

Application.application.statusBar.status = "Hello World..";

Using the to ArrayCollection's filterFunction

source : here
and here

Problem Summary
Finding a way to to filter data in a DataGrid regardless of the data in question case.

 Solution Summary

Use ArrayCollection's filterFunction and compare the data's string with a string you provide using RegEx to disregard the strings case (upper, lower or whatever)

Explanation

1.
First create an array.
2.
Pass that array to an ArrayCollection.
3.
Pass ArrayCollection as DataProvider for a DataGrid

4.
Create a textInput
5.
Create a function that will filter data from the textInput text, return type Boolean

6.
Now call the filterFunction method of the ArrayCollection class, pass the filterFunction to created
7.
create an Event listener for knowing when to filter (eg. textinput, click)

8.
create a reset button for clearing the filter.
9.
That's essentially it. See example and code to see the full scope and that should explain it self


<?xml version="1.0" encoding="utf-8"?>

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="init();" viewSourceURL="srcview/index.html">
<mx:Script>
<![CDATA[
import mx.collections.*;


private var collectionArray:Array;
[Bindable]
private var collectionData:ArrayCollection;

private var selectedName:String = "first";
import mx.controls.Alert;
import mx.events.ItemClickEvent;

private function init():void
{
collectionArray = [{first: '
Dave', last: 'Matthews'},
{first: '
Dave', last: 'Chappelle'},
{first: '
Amy', last: 'Grant'},
{first: '
Bilbo', last: 'Baggins'},
{first: '
Jessica', last: 'Tandy'},
{first: '
Jessica', last: 'Simpson'},
{first: '
Paris', last: 'Hilton'}];
collectionData = new ArrayCollection(collectionArray);
}

public function filter():void {


collectionData.filterFunction = filterFirst;
collectionData.refresh();

}

public function filterReset():void {


collectionData.filterFunction = null;
collectionData.refresh();

}

private function filterFirst(item:Object):Boolean
{
return item[selectedName].match(new RegExp(searchField.text, '
i'))
}

private function search():void
{
if(searchField.text !='')
{
filter()
}
else
{
filterReset()
}
}



private function handleCard(event:ItemClickEvent):void {

selectedName = event.currentTarget.selectedValue as String;


}

private function eraseText(event:MouseEvent):void
{
searchField.text ='';
}

]]>

</mx:Script>
<mx:DataGrid id="nameGrid" dataProvider="{collectionData}" height="210"/>
<mx:VBox y="{nameGrid.height + 10}">
<mx:TextInput tabEnabled="true" tabIndex="1" text="Search First Name" id="searchField" toolTip="Filter First Name" change="search()" rollOver="eraseText(event)" />
<mx:HBox>
<mx:RadioButtonGroup id="nameGroup" itemClick="handleCard(event)"/>

<mx:RadioButton tabEnabled="true" tabIndex="2" label="first" selected="true" groupName="nameGroup"/>
<mx:RadioButton tabEnabled="true" tabIndex="3" label="last" groupName="nameGroup" />
<mx:Button tabEnabled="true" tabIndex="4" click="searchField.text='';search()" label="Reset" />
</mx:HBox>
</mx:VBox>

</mx:Application>

as3 duplicateMovieClip Replacement

source : here

ActionScript 3 no longer has a duplicateMovieClip method for MovieClip instances (or any DisplayObject instances). Instead, it's suggested that you just create a new instance of the display object you wish to duplicate using its constructor. This, however, is not the same as duplicateMovieClip, and, really, is more like using AS1 and AS2's attachMovieClip. For a more accurate representation of duplicateMovieClip in AS3, consider the following function:

package com.senocular.display {

import flash.display.DisplayObject;
import flash.geom.Rectangle;

/**
* duplicateDisplayObject
* creates a duplicate of the DisplayObject passed.
* similar to duplicateMovieClip in AVM1
* @param target the display object to duplicate
* @param autoAdd if true, adds the duplicate to the display list
* in which target was located
* @return a duplicate instance of target
*/
public function duplicateDisplayObject(target:DisplayObject, autoAdd:Boolean = false):DisplayObject {
// create duplicate
var targetClass:Class = Object(target).constructor;
var duplicate:DisplayObject = new targetClass();

// duplicate properties
duplicate.transform = target.transform;
duplicate.filters = target.filters;
duplicate.cacheAsBitmap = target.cacheAsBitmap;
duplicate.opaqueBackground = target.opaqueBackground;
if (target.scale9Grid) {
var rect:Rectangle = target.scale9Grid;
// Flash 9 bug where returned scale9Grid is 20x larger than assigned
rect.x /= 20, rect.y /= 20, rect.width /= 20, rect.height /= 20;
duplicate.scale9Grid = rect;
}

// add to target parent's display list
// if autoAdd was provided as true
if (autoAdd && target.parent) {
target.parent.addChild(duplicate);
}
return duplicate;
}
}

usage:
import com.senocular.display.duplicateDisplayObject;

// create duplicate and assign to newInstance variable
// using true for autoAdd automatically adds the newInstance
// into the display list where myOldSprite is located
var newInstance:Sprite = duplicateDisplayObject(myOldSprite, true);
newInstance.x += 100; // shift to see duplicate


The only thing duplicateMovieClip does that this does not is copy dynamic drawing information. Currently, the graphics object in display objects cannot be duplicated so there is no way to obtain that information for duplicates in duplicateDisplayObject.

Thursday, August 2, 2007

puremvc Reusing components as subcomponents / dynamic mediators

from cliff

Multiplicity
You might go with multiple instances of the same VideoPlayerMediator. The idiom of using a constant for the Mediator name won't work though, and you'll have to dynamically give the Mediator a name. Dynamically-named Mediators can best take their name by appending 'Mediator' to their View Component's instance name. The Rather than having a constant NAME, the Mediator would have a private name variable, which it sets at construction time based upon its View Component's id. Then in getMediatorName, we return this property. (Multiplicity in Mediators will be covered in the upcoming courseware).

Uber-component/Mediator
Make the tile component that holds the multiple video components be a custom component that passes events from its children to its Mediator. The Mediator for the tile component knows about how to deal with the video components it contains.

The first one is probably the best option since it would be more reusable.

-=Cliff>

puremvc proxyFactory to manage many proxies

from cliff

Good point, Carl.

Most times, your Proxies will only have one instance created, though we won't go to the trouble to make them Singletons. So having a NAME constant to register and retrieve the Proxy with makes sense most of the time.

But lets imagine you have a particle system, where a Proxy is responsible for holding a single particle and you have thousands of particles. The ParticleProxy holds the physics implementation; the math for affecting the particle state. Its Data Object is a ParticleVO that holds the properties for a single particle.

You probably have a ParticleFactoryProxy that dynamically creates and registers these ParticleProxies, giving them unique names and properties at creation time.

The only thing that changes since we have multiple instances registered is the fact that we can't predetermine the name assign it to a constant and refer to with a singular idiom.

The ParticleFactoryProxy will only have a single instance created, so to retrieve it:

Quote
var facade:ApplicationFacade = ApplicationFacade.getInstance();
var pfProxy:ParticleFactoryProxy = facade.retrieveProxy(ParticleFactoryProxy.NAME) as ParticleFactoryProxy;

However since we have more than one instance of ParticleProxy, we'll have to have a different way of getting the name of the one we want. We'll probably have the ParticleFactoryProxy keep a list of all the names of the particles it has generated. Then to access them, perhaps from a command, we might do something like this:

Quote
var particleNames:Array = pfProxy.getParticleNames();
for (var k:int = 0; k< particleNames.length; k++) {
var particleProxy:ParticleProxy = facade.retrieveProxy(particleNames[k]) as ParticleProxy;
particleProxy.updateVector();
}

puremvc Model Locator pattern in PureMVC

from cliff
In the sense that the Model/ModelLocator is like a Christmas tree and we adorn it with all our cheery holiday data objects, yes the PureMVC Model is similar to the ModelLocator.

However it differs quite a bit in terms of how we actually access to the data.

In Cairngorm, typically you:

* Define the ModelLocator class as a Singleton.
* Add properties to it.
* Fetch the ModelLocator Singleton at various places in the View by calling its getInstance method.
* Bind to its properties.


Binding is something else that is very Flex/Flash-centric that was verboten to rely upon for the PureMVC implementation. In an environment that doesn't have the Flex and Flash classes, events and binding can't be counted upon being there there for you. At least not with the Flash/Flex implementations. (Think Mozilla Tamarin, or even J2ME, or maybe curl).

In PureMVC, you:

* Define proxies to hold the data
* Register them with the Model, typically via the Facade
* Retrieve the Proxies elsewhere with Commands or Mediators
* Set the data on the View Components with Mediators


Of course there's nothing to stop you from fetching the Proxies inside your View Components, and binding to their data. But that makes the View Components less portable since they now have this inherent PureMVC stuff in them.

Look at the Architecture 101 demos. All custom components have no knowledge of the PureMVC system or where their data comes from at all. This means you could carry them away and make a Cairngorm demo around them without having to remove any PureMVC framework stuff at all. Instead they expose an API to that their Mediators use to communicate with them, using public properties and Events. Internally they use binding all they wish to move data around and change their behavior based on the current data in the controls.

This is the path to reusability in View Components.

puremvc Mediator notification handling

from Cliff
Mediators should play a fairly simple and mechanical role in the architecture:

* Receive Event information from their View Components, gather information from the View Component and/or custom Event and send it off in a Notification.
* Receive Notifications, extract the data mostly from the Notification, and update the View Component.


Similar to a switchboard operator. Who are you calling, sir? Ok, I'll route you through.

Although you can do most anything in a Mediator, limiting it to this role and pushing more complicated stuff, (the sort of stuff you might actually want to reuse) into a Command is a better idea. This keeps the Mediator simple and lightweight, doing only the minimum work necessary to adapt the View Component to the system.

For guidance about the Mediator's role, examine the three Mediators of the Architecture 101 demo, and how they adhere to this simple ambition. Note that a more complicated activity such as deleting a User (and their associated Roles) are done in a Command.

Because they are special case adapters for custom View Components, it is not expected that Mediators will be the most reusable aspect of a system. Due to the relatively simple role Mediators play, I sought the simplest way of 'plugging' them into the system.

But of course this doesn't change the way you feel about the particular implementation. This is why I did my best to make PureMVC a system where you could take or leave as much as you want. If you're down with the out of box way of doing things, great. If not, there are plenty of ways to customize it to your like.

So as to how you might override this Mediator Notification behavior:

When the the View class's registerMediator method is called, it interrogates the Mediator for a list of Notification interests, by calling its listNotificationInterests method. The View maps each Notification name returned to an Observer object that points the Mediator instance and a predetermined callback method - handleNotification.

Examine the View.registerMediator method to see how this happens.

Inside View.registerMediator, when an Observer object is created, it is registered with the View's Observer Map through a call to the public method registerObserver. We typically don't create Observers, they're usually used internally by the Core actors to map Commands and Mediators to Notifications.

Consequently, the Facade does not have a registerObserver method, and it is not required by IFacade, which exposes the Core actor methods that are expected to be in typical use, and not actually the full IView, IModel and IController interfaces.

Your first step is to simply not return anything from listNotificationInterests in your Mediator. This way the View simply registers the Mediator in its Mediator Map and goes on about its business.

Then you want to add a registerObserver method to your concrete ApplicationFacade. This method should in turn call registerObserver on the View. It is not governed by an interface, so its signature can be different from that of the View. This means it can save the Mediator the work of constructing the Observer object, as sendNotification does for INotifiers.

Have your registerObserver method accept the Notification name, a reference to the Mediator instance, and a reference to the callback function. Then it would construct an appropriate Observer instance and call view.registerObserver. (the Facade has a local protected reference to the View Singleton called 'view')

Next, in your Mediator constructor, for each Notification you want to be notified of, do this:

facade.registerObserver( ApplicationFacade.SOME_NOTIFICATION_NAME, this, handleSomeNotification );

That should get you where you're wanting to go.

If I get a chance I'll work this into the courseware. I'm coming up on the section about Mediators, and clarifying this subject with hands on examples would probably be good. This is one of those areas, where the out of box way is simple and will cover most cases, but if you want a different flavor of behavior, you can get to it quickly.

pureMVC Coarse-grained interface concept

in doc:
it's said :
Mediator and Proxies should expose coarse-grained interface to
commands( and each other ), that hides the implementation of
their stewarded View component or Data model


Fine-grained PO一般来说管理着持久数据与表列的一对一映射. Coarse-grained PO通过多个Fine-grained PO 来管理持久数据. 这样, 属于Coarse-grained中的Fine-grained PO, 其生命期受制于Coarse-grained PO, 超过了Coarse-grained PO生命期的Fine-grained PO是没有意义的, 因为它们是做为一个整体出现的. 另外, 客户只能通过Coarse-grained PO来间接的访问其中的Fine-grained PO.
因为Coarse-grained是做为一个整体出现的, 所以Lazy initialization是不可能的, 对Coarse-grained来说, 要么一起装入, 要么什么也不装入, 一起装入也就造成了较长的响应时间, 另外, Coarse-grained也会影响我们写程序时运用inheritance 和 polymorphism(这一点, 希望能得到其它朋友的见解)
EJB就其本身只能做成一种Coarse-grained PO(Sun网站上也不得不这样说), 而Hibernate PO 则可以做成Fine-grained 和Coarse-grained, 显然选择的余地多.


Fine-grained和Coarse-grained 一般是指远程方法调用的接口的颗粒大小.
比如, 我有一个远程对象, 他有很多属性和对应的getter和setter方法,
如果我们远程调用对象每个属性的getter和setter方法, 就会产生很多远程方法调用. 这就是Fine-grained interface, 会造成性能问题

所以我们可以用一个setdata或getdata的方法把一些属性的访问封装起来, 只用一个远程方法传输一个data transfer object来对该对象进行赋值和访问, 这就是Coarse-grained interface

[AS3] Full browser background with smoothing

source

This will load a image and scale it to the browsers scale.

Demo:
http://gfxcomplex.com/labs/full_browser_bg_as3.html

Background image by darkmotion:
http://www.deviantart.com/deviation/46131446/

AS3 source:
http://gfxcomplex.com/labs/full_browser_bg_as3.zip

:: Added two Events and two read only public methods for preloading.
Plus new fade image in Timer.

Methods————————
BrowserBackground.bytesLoaded; returns a :Number and is read only
BrowserBackground.bytesTotal; returns a :Number and is read only

Events————————–
BrowserBackground.BACKGROUND_LOADING dispatchis a events for progress of a Loader object, as well updates the BrowserBackground.bytesLoaded and BrowserBackground.bytesTotal.

BrowserBackground.BACKGROUND_LOADED dispatchis an event upon a full and complete load of the Load object.

Sample use code.

package {
import com.gfxcomplex.display.BrowserBackground;
import flash.display.Sprite;
import flash.events.Event;
public class MainDoc extends Sprite {
private var _bg:BrowserBackground;
public function MainDoc() {
_bg = new BrowserBackground(”http://gfxcomplex.com/images/Damn_utensils_by_darkmotiondotcom.jpg”);
addChild(_bg);
_bg.addEventListener(BrowserBackground.BACKGROUND_LOADING, loading);
_bg.addEventListener(BrowserBackground.BACKGROUND_LOADED, loaded);
}
private function loaded(e:Event):void {
_bg.removeEventListener(BrowserBackground.BACKGROUND_LOADING, loading);
_bg.removeEventListener(BrowserBackground.BACKGROUND_LOADED, loaded);
}
private function loading(e:Event):void {
var bL:Number = _bg.bytesLoaded;
var bT:Number = _bg.bytesTotal;
}
}
}

Source Code::

*////////////////////////////////////////////////////
//////////////////////////////////////////////////////
////
//// Full Browser background image
////
//// by Josh Chernoff ( GFX Complex )
//// Copy right ~ josh chernoff ~ 2007
//// All rights reserved
////
////
//// May be redistributed under The
//// GNU General Public License (GPL) Agreement
////
//////////////////////////////////////////////////////
*//////////////////////////////////////////////////////*
Class constructor requires only one argument
url:String for loading the background
public class BrowserBackground(url:String);
*/package com.gfxcomplex.display{import flash.display.Sprite;
import flash.system.LoaderContext;import flash.display.StageAlign;

import flash.display.StageScaleMode;

import flash.display.Bitmap;

import flash.display.Loader;

import flash.events.Event;

import flash.events.TimerEvent;

import flash.events.ProgressEvent;

import flash.net.URLRequest;

import flash.utils.Timer;

public class BrowserBackground extends Sprite{

public static const BACKGROUND_LOADED:String = “backgroundLoaded”;

public static const BACKGROUND_LOADING:String = “backgroundLoading”;

private var _bytesLoaded:Number;

private var _bytesTotal:Number;

private var _imageHolder:Sprite;

private var _bitmap:Bitmap;

private var _loader:Loader;

private var _timer:Timer;

public function get bytesTotal():Number{

return _bytesTotal;

}

public function get bytesLoaded():Number{

return _bytesLoaded;

}

function BrowserBackground(url:String) {

var context:LoaderContext = new LoaderContext();

context.checkPolicyFile = true;

_loader = new Loader();

_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);

_loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progressHandler);

_loader.load(new URLRequest(url), context);

}

private function completeHandler(event:Event):void {

var sW:Number = stage.stageWidth;

var sH:Number = stage.stageHeight;

_imageHolder = new Sprite();

_timer = new Timer(50, 44);

_bitmap = Bitmap(event.target.loader.content);

_bitmap.y -= _bitmap.height;

_bitmap.smoothing = true;

addChild(_imageHolder);

_imageHolder.addChild(_bitmap);

_imageHolder.width = sW;

_imageHolder.scaleY = _imageHolder.scaleX;

if (_imageHolder.height < sH) {

_imageHolder.height = sH;

_imageHolder.scaleX = _imageHolder.scaleY;

}

_imageHolder.y = sH ;

_imageHolder.alpha = 0;

_timer.addEventListener(TimerEvent.TIMER, timerListener);

_timer.start();

stage.scaleMode = StageScaleMode.NO_SCALE;

stage.stage.align = StageAlign.TOP_LEFT;

stage.addEventListener(Event.RESIZE, stageResized);

dispatchEvent(new Event(BrowserBackground.BACKGROUND_LOADED));

_loader = null;

}

private function progressHandler(event:ProgressEvent):void {

_bytesLoaded = event.bytesLoaded;

_bytesTotal = event.bytesTotal;

dispatchEvent(new Event(BrowserBackground.BACKGROUND_LOADING));

}

private function timerListener(e:TimerEvent){

_imageHolder.alpha += .025;

if(_imageHolder.alpha >= 1){

_imageHolder.alpha = 1;

_timer.stop();

_timer.removeEventListener(TimerEvent.TIMER, timerListener);

_timer = null;

}

e.updateAfterEvent();

}

private function stageResized(event:Event):void {

var sH:Number = stage.stageHeight;

_imageHolder.width = stage.stageWidth;

_imageHolder.scaleY = _imageHolder.scaleX;

if (_imageHolder.height < sH) {

_imageHolder.height = sH;

_imageHolder.scaleX = _imageHolder.scaleY;

}

_imageHolder.y = sH;

}

}
}

Flex and Flash file uploading with return data

source: here

The addition of the FileReference class in AS2 made file uploading significantly easier in Actionscript. However, one issue that remained problematic was the ability to get detailed information back from the server once the upload was complete. The best you could do was to get a '200' response saying the file upload had completed, but there was no easy way to return additional data from the server with respect to the uploaded process .... until now.

Adobe has finally added the missing piece to accomplish a nice tight uploading process, the UPLOAD_COMPLETE_DATA event (Flash Player 9.0.28.0). This event fires after the COMPLETE event and contains an important piece of information. The data property of the DataEvent contains the raw data returned from the server after a successful file upload. Finally, a way to return from the server information about the file and/or process. This is especially useful if during the upload process you need to do additional things like create a database record and then return the new database id, or possibly put the file in a different path based on the user, and return the path where the file exists back to the client.

Here's a quick sample of implementing the new event in Flex and also a Coldfusion and PHP script to upload a file and then output and return data back to the client in a clean consistent fashion.

The Flex code. As you can see, this is a very simple example, you select a file and when the upload has completed the results from the server are output into a text area.

Event.bubbles, Event.cancelable, and Event.currentTarget

original author : Ruben Swieringa

source: Ruben Swieringa's blog

== some quote for mhis blog ==
Perhaps some of you may not know this, but event-bubbling in Actionscript3.0 is way cool and well worth your attention. So read on.

With event-bubbling you can let one Event subsequently call on every ancestor (containers of containers of etc.) of the DisplayObject that originally dispatched the Event, all the way up to the surface (read: Stage), hence the name ‘bubbling’.
Perhaps noteworthy is that bubbling for an Event instance is disabled by default, and can only be activated by setting the bubbling parameter in the Event constructor.

Although the documentation doesn’t seem to make it all too apparent, event-bubbling is actually the reason why the Event class has a currentTarget property (as well as a target property).
So what is the use of Event.currentTarget? While the target property will always have its value set to the DisplayObject that originally dispatched the Event, the currentTarget property always points to the DisplayObject that the event is currently processing (i.e. bubbling at).

Now, you will probably not always want your Event to bubble all the way up to the Stage of your movie. This is where the cancelable property comes into the picture.
Setting the cancelable property contructor-parameter to true allows you to call the stopPropagation() and stopImmediatePropagation() methods later on. Both methods basically abort the bubbling process.
The difference here is that the latter also aborts execution of other listeners for the same Event-type on the same currentTarget, whereas the former only aborts execution of listeners to subsequent targets.

The following example attempts to visualize the concept of event-bubbling in AS3. Click the big button in the middle to dispatch a bubbling Event, and tick the CheckBoxes to have that Event canceled at a specific parent of the Button. Right-click to view source.

=====
you can also find a great example on his blog.

FlashDevelop 3, unsorted plugins

source: here

many of flashdevelop plugin

1. SourceControl: this is the very first I did and in fact it doesn't do anything special. In AS2 and AS3 files it adds to the scintilla contextual menu three more options: "organize imports" (similar to the one in flex), "add getter/setter method" and "add accessor method" (when you click on a class variable)

2. Bookmarks panel: This create a docking panel displaying all the current opened files and keep updated their bookmarks.

3. Flash API panel: Similar to the one included in the Flash IDE. Just give (in the plugin settings) the path (one or more) of the xml included in the ActionsPanel flash directory and it will display the full list of all the language available actions/methods/classes. Double click on an item will insert the command in the document text giving also the description of the selected command in a tooltip.

4. ASClassWizard: It overrides the "New Class" project menu command and displays a wizard dialog for creating a new ActionScript 2/3 class. Give the package, the classname, super class, implementing interfaces and it will create your class

Wednesday, August 1, 2007

AS3: Layout class for Flash CS3

Once again Senocular present us some examples of Flash CS3, this time handling the Layout Class. For those don’t know, this class let you constrain objects to the top, right, bottom, left, or center them horizontally or vertically within a layout. There are also controls for height and width as well as a property for maintaining aspect ratio.

You can find the examples and documentation here.

Brgds,

Datagrid runtime item renderers

source : here

Step 1.

Create the basic item renderer. One of the things I needed to accomplish with my item renderer was the ability to add it to different columns (ie the dataField was not always the same). This meant I needed a way from within the renderer to determine what column it was bound to so I could get and display the correct data. To do this the renderer needs to implement the IDropInListItemRenderer. This interface allows the renderer to have access to information about the list and column it is in via the BaseListData and DataGridListData classes. The DataGridListData gives you everything you need to get the data required to make a flexible, reusable renderer.

Here is my basic image item renderer. Nothing to exciting, but it is very reusable. I can drop this into any datagrid to render an image column and it will work.

<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" 
implements
="mx.controls.listClasses.IDropInListItemRenderer">


<
mx:Script>
<![
CDATA[
import
mx.controls.dataGridClasses.DataGridListData;

import
mx.controls.listClasses.BaseListData;

// Make the listData property bindable.
[Bindable("dataChange")]

private var
_listData : BaseListData;


public function
get listData() : BaseListData

{

return
_listData;
}


public function
set listData( value : BaseListData ) : void

{

_listData = value;

}
]]>
</
mx:Script>

<
mx:Image source="{data[(DataGridListData(listData).dataField)]}"/>
</
mx:Canvas>


Step 2.

Modify the renderer so that it can be added at runtime. To do this the renderer needs to implement the IFactory interface. This will allow the renderer to be added at any point during runtime. Without implementing this interface it won't work, period. Below is the code to implement the interface.

<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" 
implements
="mx.controls.listClasses.IDropInListItemRenderer, mx.core.IFactory">


public function newInstance():*
{
return new ImageRenderer();
}

Step 3.

The code to change a column at runtime from a basic column to an item renderer column. Get the columns from the datagrid, modify the column you are interested in and then reassign the columns to the datagrid. Notice that when you set the column's itemRenderer value you must create a new instance of the desired item renderer.

private function switchStatusColumn(event:MouseEvent):void
{
var cols:Array = users_dg.columns;
var col:DataGridColumn = cols[1] as DataGridColumn;
col.itemRenderer = new CheckBoxRenderer();
users_dg.columns = cols;
}

Step 4.

The code to add a new column with an item renderer at runtime. This is almost identical to modifying an existing column. The only difference is that we push the new column into the columns array.

private function addImageColumn(event:MouseEvent):void
{
var cols:Array = users_dg.columns;
var col:DataGridColumn = new DataGridColumn();
col.itemRenderer = new ImageRenderer();
col.dataField = 'emoticon';
col.headerText = 'Image';
cols.push(col);
users_dg.columns = cols;
}