View all posts filed under 'Tutorials'

Cairngorm Getting Started Part Six – Displaying the Data

Thursday, 31. July 2008 10:24

Now we’ve got the data back we need somewhere to store it.  This is where the model comes in.  Let’s create a ModelLocator called MemoryModelLocator.  It implements IModelLocator.  The interface doesn’t actually require any functions, it is just there to type the class.  Here’s the class

package com.worthyashes.simpleCairngorm.model
{
	import com.adobe.cairngorm.model.IModelLocator;
	[Bindable]
	public class MemoryModelLocator implements IModelLocator
	{
		//Singleton code
		private static var _instance:MemoryModelLocator;

		public function MemoryModelLocator(enforcer:SingletonEnforcer)
		{
			if (enforcer == null)
			{
				throw new Error("Like at the end of Highlander, before the crap sequal, there can be only one");
			}
		}

		public static function getInstance():MemoryModelLocator
		{
			if (_instance == null)
			{
				_instance = new MemoryModelLocator(new SingletonEnforcer());
			}
			return _instance;
		}
		//End of singleton code

		//Pop your vars into the model from here on
		public var loadedData:XMLList = new XMLList();
	}
}
class SingletonEnforcer{}

This is pretty much what we did in part two, the only addition being the variable loadedData which is of type XMLList.  Remember the most important thing is that this whole class is bindable.  This allows us to access the variables in this class using dynamic data binding.

Lets get the data in.  Back to our LoadXMLResponder class, remember Models in Cairngorm should ONLY be modified by a Command or a Responder.

package com.worthyashes.simpleCairngorm.responder
{
	import com.worthyashes.simpleCairngorm.model.MemoryModelLocator;

	import mx.rpc.IResponder;
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;

	public class LoadXMLResponder implements IResponder
	{
		public function LoadXMLResponder()
		{
		}

		public function result(data:Object):void
		{
			var resultEvent:ResultEvent = data as ResultEvent;
			trace("XML loaded");

			var memoryModel:MemoryModelLocator = MemoryModelLocator.getInstance();
			memoryModel.loadedData = resultEvent.result.block as XMLList;
		}

		public function fault(info:Object):void
		{
			var faultEvent:FaultEvent = info as FaultEvent;

			trace("Fault at [LoadXMLResponder] " + faultEvent.message);
		}

	}
}

Obviously we populate the data in the result function.  We create a local variable of the memoryModel, don’t forget that as a Singleton we can’t access it directly, we need to call the static getInstance() function on the class.  This ensures that we always get the same singleton back regardless of where we are in the application.  As we are using the e4x result format we can use dot notation to drill down the XML to return the XML <block> nodes as an XMLList.

So – great we’ve populated the Model.  Whoopy do.  Well whoopy do indeed, because we’ve got the data in a class that is the same at every point in the application and it’s bindable.

Look back at the main application file, currently we have a Tree component and a TextArea component.  Lets ignore the TextArea component for a mo and we’ll focus on the Tree.  I’m going to take the Tree and it’s holding Box out of this file and create it as a custom component in the view folder.

<?xml version="1.0" encoding="utf-8"?>
<mx:Box  xmlns:mx="http://www.adobe.com/2006/mxml">
	<mx:Script>
		<![CDATA[
			import com.worthyashes.simpleCairngorm.model.MemoryModelLocator;
			[Bindable]
			private var memoryModel:MemoryModelLocator = MemoryModelLocator.getInstance();

			private function renderLabel(item:Object):String
			{
				var node:XML = item as XML;

				if (node.localName() == "block")
				{
					return node.@title;
				}
				else if (node.localName() == "item")
				{
					return node.@name;
				}
				return "Something went wrong!!";
			}
		]]>
	</mx:Script>

	<mx:Tree dataProvider="{memoryModel.loadedData}"
			 width="100%"
			 height="100%"
			 labelFunction="renderLabel"/>
</mx:Box>

So what’s happening here?  What we are doing is creating an instance of the MemoryModelLocator class, and binding it to the tree as it’s data provider.  This means that when the LoadXMLResponder loads the XML and changes the property loadedData it updates the Tree component.  This is what we mean when we say the model updates the view.  The model doesn’t ‘know’ it has a view watching it, but when it changes regardless it updates the data being used by the views bound to it.  Pretty cool.  All we need to do now is render the label for the Tree and we are done!

Pop this into the main application file

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
				xmlns:view="com.worthyashes.simpleCairngorm.view.*"
				xmlns:control="com.worthyashes.simpleCairngorm.control.*"
				xmlns:business="com.worthyashes.simpleCairngorm.business.*"
				creationComplete="creationCompleteHandler();"
				layout="vertical">

	<mx:Script>
		<![CDATA[

			private function creationCompleteHandler():void
			{
				var loadXMLEvent:LoadXMLEvent = new LoadXMLEvent();
				loadXMLEvent.dispatch();
			}

		]]>
	</mx:Script>

	<control:SimpleFrontController id="frontController"/>

	<business:Services id="services"/>

	<mx:Panel title="XML Display" width="600" height="500">
		<mx:ViewStack width="100%" height="100%">
			<view:XMLTree id="xmlTree"/>
			<mx:Box>
            	<mx:TextArea/>
            </mx:Box>
		</mx:ViewStack>
		<mx:ControlBar>
			<mx:Button id="btn_tree" label="Display as Tree"/>
			<mx:Button id="btn_datagrid" label="Display as Datagrid"/>
		</mx:ControlBar>
	</mx:Panel>

</mx:Application>

We’ve again created an xmlns with the name of view to allow us to access the com.worthyashes.simpleCairngorm.view package.  So now when we run this we will display the XML in the tree.

Next let’s have a look at using a ModelLocator to manage state.

Category:Cairngorm, Flex, Frameworks, Tutorials | Comment (0) | Autor: admin

Cairngorm Getting Started Part Five : Delegates and Responders

Wednesday, 30. July 2008 16:09

We’ve created our LoadXMLEvent, created our FrontController and that has linked the event with the command to get the XML. Now we need to create our next set of classes. The Delegate class deals with retriving the data, it does this by using another Cairngorm class called the ServiceLocator. As the Delegate is getting some data we need to create a Responder to recieve and deal with the data. As this is a simple application we could make the Command the Responder too, but as I want this to be a pucker representation of how Cairngorm works I’m going to go ahead and create the Responder.

So – lets create the ServiceLocator. The ServiceLocator is a ModelLocator really, and is where you keep all of the data calls for the application. This is a great thing to do as the service locator is where you call the server side code, or as in this case load the XML. This means that if you’d developed an application with a ColdFusion backend and needed to port it over to AMFPHP then you should only need to swap out this class and it should all function as expected. (Note the use of the word ’should’)

Anyway lets have a look at it.

<?xml version="1.0" encoding="utf-8"?>
<cairngorm:ServiceLocator xmlns:mx="http://www.adobe.com/2006/mxml"
		          xmlns:cairngorm="com.adobe.cairngorm.business.*">

	<mx:HTTPService id="xmlService"
			resultFormat="e4x"
			showBusyCursor="true"/>

</cairngorm:ServiceLocator>

So to create this right click on the business folder and select new -> MXML component. It doesn’t matter what you choose as the component as you can see from above we are going to use our own tag to identify it. Add the xmlns declaration so we can reference the com.adobe.cairngorm.business package. Once you’ve done that pop the HTTPService tag in. This is what will load the XML and we’ve set the result format to e4x so we can use the e4x syntax to work with the XML returned.

Right one down. Now we’ll create the responder. Right click on the responder folder…..actually, by now I think you’ve got the hang of creating classes. I’ll just describe them. The responder classes live in the responder folder need to implement the IResponder interface.

package com.worthyashes.simpleCairngorm.responder
{
	import com.worthyashes.simpleCairngorm.model.MemoryModelLocator;

	import mx.rpc.IResponder;
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;

	public class LoadXMLResponder implements IResponder
	{
		public function LoadXMLResponder()
		{
		}

		public function result(data:Object):void
		{
			var resultEvent:ResultEvent = data as ResultEvent;
			trace("XML loaded");
		}

		public function fault(info:Object):void
		{
			var faultEvent:FaultEvent = info as FaultEvent;

			trace("Fault at [LoadXMLResponder] " + faultEvent.message);
		}

	}
}

The result and fault events are called by either a -er- result or fault. To implement the interface correctly they have Objects passed in as parameters, but they are actually ResultEvents and FaultEvents respectively. This is why I’ve immediately created a local variable of type either ResultEvent or FaultEvent and cast the objects into it. If you’ve been hunting for tutorials on Cairngorm you’ll probably have seen something similar to “Fault at [LoadXMLResponder] “. I can’t remember which tutorial uses this, I’ll pop a link in when I find it, but this has been a lifesaver a number of times for debugging.

OK now we create the Delegate class that sticks this all together. The delegate also lives in the business folder, but doesn’t extend or implement anything.

package com.worthyashes.simpleCairngorm.business
{
	import com.adobe.cairngorm.business.ServiceLocator;

	import mx.rpc.AsyncToken;
	import mx.rpc.IResponder;
	import mx.rpc.http.mxml.HTTPService;

	public class LoadXMLDelegate
	{
		private var responder:IResponder;
		private var service:HTTPService;

		public function LoadXMLDelegate(responder:IResponder)
		{
			this.responder = responder;
			this.service = ServiceLocator.getInstance().getHTTPService("xmlService") as HTTPService;
			this.service.url = "xml/example.xml";
		}

		public function loadXML():void
		{
			var token:AsyncToken = service.send();
			token.addResponder(responder);
		}

	}
}

There we go. The delegate holds a referenced to the responder and the service to call. Then when called to load the XML it triggers the load on the service and adds the responder to the service. This is why the Responder needs to implement IResponder and have the result and fault events. Now we get the Command to create the Delegate and trigger it.

package com.worthyashes.simpleCairngorm.commands
{
	import com.adobe.cairngorm.commands.ICommand;
	import com.adobe.cairngorm.control.CairngormEvent;
	import com.worthyashes.simpleCairngorm.business.LoadXMLDelegate;
	import com.worthyashes.simpleCairngorm.events.LoadXMLEvent;
	import com.worthyashes.simpleCairngorm.responder.LoadXMLResponder;

	public class LoadXMLCommand implements ICommand
	{
		public function LoadXMLCommand()
		{
		}

		public function execute(event:CairngormEvent):void
		{
			var e:LoadXMLEvent = event as LoadXMLEvent;

			var delegate:LoadXMLDelegate = new LoadXMLDelegate(new LoadXMLResponder());
			delegate.loadXML();
			trace("Getting the XML");
		}

	}
}

All we’ve added is

var delegate:LoadXMLDelegate = new LoadXMLDelegate(new LoadXMLResponder());
delegate.loadXML();

Finally we need to instantiate the ServiceLocator, otherwise we won’t be able to use it.  Back in the main application file add the xml name space in the opening tag of

xmlns:business=”com.worthyashes.simpleCairngorm.business.*”

and add this MXML tag

<business:Services id=”services”/>

That’s it.  If you run the code now all being well you’ll get a trace to tell you the XML is loaded.

So now we’ve got the data loaded we need somewhere to put it, which takes us all the way back to the discussion of singletons. Next we are going to create a ModelLocator to hold the data.

Category:Cairngorm, Flex, Frameworks, Tutorials | Comment (0) | Autor: admin

Cairngorm Getting Started Part Four : Events, Commands and Controllers

Wednesday, 30. July 2008 15:20

So we’ve had a chat about the MVC design pattern and how that relates to Cairngorm, set up the environment and we’ve discussed how Singletons work.  Now we are ready to start using the framework to create a basic application.

Frameworks like Cairngorm really come into their own when you are creating a large or relatively complicated application.  For the purposes of this little demonstration we will load an XML file and display it in either a Tree component or in a TextArea component.  No great shakes and I know that if this was all you really needed to to then using Cairngorm is a little bit of an overkill, but keeping it simple means we’ll clearly be able to look at what the framework does without having to go over lots of code.

To just go back a step for a moment we are going to quickly recap how the Cairngorm framework operates.

The view dispatches events to the controller.  The controller then either modifies the model directly or in the case of getting some data, creates a delegate and a responder.  The delegate gets the data and returns it to the responder that modifies the model.  Then the model tells the view what to display.

Ideally each set of classes should only operate in an expected way on the other classes.  IE the models should only ever be modified by Controllers or Responders, the Delegates should be the only classes that get data, the views should only do view stuff.  This is the delegation of responsibility.

Lots of books and tutorials almost talk about classes as if they are sentient beings, the view shouldn’t know about the model, the model shouldn’t know about the controller.  This sort of worked for me, but I can’t really anthropomorphise what I know is just a set of classes.

Another way of looking at this, and one which makes sense to me, is that it’s all about organisation.  You wouldn’t file your car tax in the fridge, otherwise you’ll spend ages looking for it when you need to renew it.  Likewise with a Cairngorm app if something is wrong with the data call you know to start at the Delegate and see what is happening there.  (If you wanted a new car you wouldn’t want to have to change the fride too.  This analogy doesn’t quite hold up, but you know what I mean).

So if we’re happy with that lets get on with the code.

We’ll start first with the base mxml application file.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application layout="vertical">

<mx:Script>
<![CDATA[
]]>
</mx:Script>

<mx:Panel title="XML Display" width="600" height="500">
<mx:ViewStack width="100%" height="100%">
<mx:Box>
<mx:Tree/>
</mx:Box>
<mx:Box>
<mx:TextArea/>
</mx:Box>
</mx:ViewStack>
<mx:ControlBar>
<mx:Button id="btn_tree" label="Display as Tree"/>
<mx:Button id="btn_datagrid" label="Display as TextArea"/>
</mx:ControlBar>
</mx:Panel>

</mx:Application>

Nice and simple.  So first things first we need to get the XML.  I’ve created a very very simple XML file.

<?xml version="1.0" encoding="utf-8"?>
<exampleXML>
<block title="Block One">
<item name="Item One"/>
<item name="Item Two"/>
<item name="Item Three"/>
<item name="Item Four"/>
</block>
<block title="Block Two">
<item name="Item One"/>
<item name="Item Two"/>
<item name="Item Three"/>
<item name="Item Four"/>
<item name="Item Five"/>
<item name="Item Six"/>
<item name="Item Seven"/>
</block>
<block title="Block Three">
<item name="Item One"/>
<item name="Item Two"/>
<item name="Item Three"/>
<item name="Item Four"/>
<item name="Item Five"/>
<item name="Item Six"/>
</block>
<block title="Block Four">
<item name="Item One"/>
<item name="Item Two"/>
<item name="Item Three"/>
<item name="Item Four"/>
<item name="Item Five"/>
<item name="Item Six"/>
<item name="Item Seven"/>
<item name="Item Eight"/>
<item name="Item Nine"/>
<item name="Item Ten"/>
<item name="Item Eleven"/>
<item name="Item Twelve"/>
</block>
<block title="Block Five">
<item name="Item One"/>
<item name="Item Two"/>
<item name="Item Three"/>
<item name="Item Four"/>
</block>
<block title="Block Six">
<item name="Item One"/>
<item name="Item Two"/>
<item name="Item Three"/>
<item name="Item Four"/>
<item name="Item Five"/>
<item name="Item Six"/>
</block>
</exampleXML>

To trigger the load we’ll need to dispatch an event.  This is a very simple event so it’ll be a very simple class.  I’ve called it LoadXMLEvent and it’s saved in the event folder we created in part Two.  Right click on the folder, select new class.  When the class wizard launches we need to extend the CairngormEvent class.  Select the browse button next to the Superclass text input and then start to type ‘CairngormEvent’ into the panel that pops up.  It’ll quickly find CairngormEvent, click OK and then OK again into the wizard panel.  This will generate the class with the correct imports and will also create the constructor for you.

Like I said this is a very simple class, it doesn’t need to even parse any data, all we want to do is announce we need the XML.

package com.worthyashes.simpleCairngorm.events
{
import com.adobe.cairngorm.control.CairngormEvent;

import flash.events.Event;

public class LoadXMLEvent extends CairngormEvent
{
public static const LOAD_XML_EVENT:String = "loadXMLEvent";

public function LoadXMLEvent(bubbles:Boolean=false, cancelable:Boolean=false)
{
super(LOAD_XML_EVENT, bubbles, cancelable);
}

override public function clone():Event
{
return new LoadXMLEvent(this.bubbles,this.cancelable);
}

}
}

Lets go through the code.  The first variable is a public static constant variable (it’s in capitals as a visual indication that it is a constant, this is not necessary though it is a convention worth following.)

All this really does is hold the string to indicate what event this class is.  CairngormEvents exetend the standard Event class so it requires a string indicator.  Rather than parseing the name of the event in when the event is created by the class using it we are it in the class so we have more control, and access to it through the static variable.  This means that we don’t have to try and remember what we called this event, if we need to access this name all we need to do is use LoadXMLEvent.LOAD_XML_EVENT, and we make sure that we are talking about the correct event.

Now for the constructor.  As we are not parseing any data we don’t really have to put anything in the constructor, but as it’s best practice (and the code was written for us) we’ll leave the variables for bubbling and canceleable in.

Note that in the super() function, that calls the Superclasses constructor we are parsing the LOAD_XML_EVENT variable in to type the class.

Finally we override the clone function.  This function is used for bubbling and by overriding this function we make sure the correct event type is returned.

That’s it – our first CairngormEvent, woo hoo!

Next we’ll create the Controller that’ll actually do something.

On the commands folder right click, select new , class and then in the wizard rather than selecting a superclass we are going to select an interface.  The ICommand interface types this class as an ICommand and also defines the functions required by it.

Select the add button next to the Interface text area, start typing in ICommand and when it finds the correct interface select it and hit OK.  Select OK on the wizard panel and your controller will be created with all of the required imports and also the required functions to satisfy the interface.

Now onto the class

package com.worthyashes.simpleCairngorm.commands
{
import com.adobe.cairngorm.commands.ICommand;
import com.adobe.cairngorm.control.CairngormEvent;
import com.worthyashes.simpleCairngorm.events.LoadXMLEvent;

public class LoadXMLCommand implements ICommand
{
public function LoadXMLCommand()
{
}

public function execute(event:CairngormEvent):void
{
var e:LoadXMLEvent = event as LoadXMLEvent;

trace("Load XML Event triggered the command!!");
}

}
}

All we’ve done here is populate the execute function with a trace so we know it’s working.  I also set a variable, in this case e as the Type of event that has triggered this command and cast the event passed into the function to the correct type.  In other classes this can be useful as this then gives you native access to the Event classes properties.  In this case the LoadXMLEvent has no properties, it only exists to tell the application it is time to get some XML, but I still have it there.  It’s not necessary, but after you’ve been putting together a large application you have a pile of classes, having a reference to the event class in the command class makes it easier to find.

So we’ve created an Event and we’ve created a Command – but aren’t we doing an MVC implementation?  Where’s the controller?  That comes now and the controller exists to tie the Events and Commands together.

Right click on the control folder and select new class.  This class extends FrontController and I’ve called mine SimpleFrontController.
The FrontController class listens to the CairngormEventDispatcher class and executes Commands based on the events called.

Lets add our code to start it working.

package com.worthyashes.simpleCairngorm.control
{
import com.adobe.cairngorm.control.FrontController;
import com.worthyashes.simpleCairngorm.commands.*;
import com.worthyashes.simpleCairngorm.events.*;

public class SimpleFrontController extends FrontController
{
public function SimpleFrontController()
{
super();
initialise();
}

private function initialise():void
{
addCommand(LoadXMLEvent.LOAD_XML_EVENT,LoadXMLCommand);
}

}
}

We’ve created our own initialise function and in this function we tie the commands and the events together.  Remeber the static string we created in the LoadXMLEvent class that was then passed to the super function as the type?  This is an example of why we do this – we don’t need to remember the type, all we need to do is reference the Event class itself.  This is really handy if we need to change the type – rather than picking through the app changing strings we change it in the Event class itself and that’s it.

Now we’ve created the controller we need to instantiate it.  This can be done with MXML in the application.  We’ll also trigger the event.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application layout="vertical"
xmlns:control="com.worthyashes.simpleCairngorm.control.*"
creationComplete="creationCompleteHandler();">

<mx:Script>
<![CDATA[
private function creationCompleteHandler():void
{
var loadXMLEvent:LoadXMLEvent = new LoadXMLEvent();
loadXMLEvent.dispatch();
}
]]>
</mx:Script>

<control:SimpleFrontController id="frontController"/>

<mx:Panel title="XML Display" width="600" height="500">
<mx:ViewStack width="100%" height="100%">
<mx:Box>
<mx:Tree/>
</mx:Box>
<mx:Box>
<mx:TextArea/>
</mx:Box>
</mx:ViewStack>
<mx:ControlBar>
<mx:Button id="btn_tree" label="Display as Tree"/>
<mx:Button id="btn_datagrid" label="Display as TextArea"/>
</mx:ControlBar>
</mx:Panel>

</mx:Application>

What have we added?  First of all we’ve added an xmlns attibute to the main application tag.  This allows us to shortcut accessing the controller by using our own name ‘control’ that will reference the com.worthyashes.simpleCairngorm.control package.  We’ve also added a creation complete handler function for the creationComplete event.  This function creates and dispatches an loadXMLEvent.  Finally we’ve added the FrontController using MXML.  Run it and you will get the trace from the Command class as it executes – don’t forget to debug the application rather than running it.  Next we are going to look at the Delegate that retrieves the data and introduce a new class, the ServiceLocator class.

Category:Cairngorm, Flex, Frameworks, Tutorials | Comments (1) | Autor: admin

Cairngorm Getting Started Part Three : Singletons

Wednesday, 2. July 2008 22:07

We’ve covered an overview of the MVC pattern and how it relates to Cairngorm and we’ve set up the environment and we’ve set up the environment so we can finally start to play with some code.  Nearly.

There is one last concept to go over before we move on, Singletons,  I’m sure that most of you are happy with this concept, but for those who don’t here we go.

A singleton is a class that there can only be one of.  Ever.  To borrow a joke from someone else – like Highlander there can be only one (though this analogy doesn’t quite add up as initially there were loads of them, then they had to fight each other to whittle the numbers down to one.  However the sequals made a mockerly of this idea as ‘aliens’ got involved in a typical WTF can we do now idea to make more money out of this clearly dead horse – and ruined a fantastic film.  So to relate this to a design pattern is actually quite misleading.) (Don’t get me started on the Matrix sequals – he had clearly won at the end of the first one, why didn’t you stop there?)

Right, sorry I do tend to digress a bit (Star Wars prequals!  WTF were they all about?  On a side note when I was an actor in the London Dungeon, long story but safe to say the acting career when fantastically well :( , I actually made the little boy who played Anakin Skywalker cry.  So I made Darth Vader cry – sort of.  Beat that!)

I did it again, concentrate – back to singletons.  Like I said a singleton is a class that there can be only one of.  Why is this helpful?  Well if there is only one then everytime you access the class you have exactly the same data stored within t.  They can be thought of as silos of data, or memory.  They can also be bound to view components and this is where the concept of changing the model to change the view works.  This is why they are used as a major part of the Cairngorm framework.  (Lots of people don’t like singletons, and I’m still not entirely sure why)

Here is an example of a Cairngorm singleton : -

package com.worthyashes.simpleCairngorm.model
{
        import com.adobe.cairngorm.model.IModelLocator;
        [Bindable]
        public class MemoryModelLocator implements IModelLocator
        {
         //Singleton code
         private static var _instance:MemoryModelLocator;

         public function MemoryModelLocator(enforcer:SingletonEnforcer)
         {
         if (enforcer == null)
             {
              throw new Error("Like at the end of Highlander, before the crap sequal, there can be only one");
             }
         }

          public static function getInstance():MemoryModelLocator
          {
           if (_instance == null)
            {
                _instance = new MemoryModelLocator(new SingletonEnforcer());
              }
            return _instance;
            }
            //End of singleton code

           //Pop your vars into the model from here on
      }
}
class SingletonEnforcer{}

Lets go through the code

[Bindable]

public class MemoryModelLocator implements IModelLocator

The [Bindable] keyword makes this class available for flex bindings so it is possible to directly bind the ModelLoactor and it’s subsequent variables to the view components as discussed above.

A Cairngorm Singleton is also known as a ModelLoactor and implements the IModelLocator interface. (For a discussion of interfaces you’re going to have to do a bit of a google.  I understand them, understand how and why to use them, but for the life of me I can’t actually put into words why – I’ll have a go at a later post)

Now for the slightly mind bending bit, once you’ve got the hang of this it will all become clear.

private static var _instance:MemoryModelLocator;

This variable _instance, the underscore is there to indicate it is a private variable (the private keyword does that really, the underscore is more a visual reminder in the code), holds a reference to the MemoryModelLocator class.  Which is the class that it is in.  So it holds a reference to itself, in itself.  Which you’d imagine would have another _instance variable, but the keyword static indicates that this variable is always the same in every single instance of this class.  So every time you access the Singleton after it has initially been instantiated you are getting the same class back.  I’ve just re-read that, I think it makes sense – if not then send me a mail and I’ll re-work that paragraph.

Now onto the constructor.  In order for a singleton to work we need to only ever create one at any time.  This means we DON’T want to be able to call the constructor directly, as this would instantiate a new class.  By convention we call a static function called getInstance() (It doesn’t have to be called this, but as it’s a convention I recommend you stick to it) that returns an instance of the class.

Singletons in AS2 were easier to do.  This was because it was allowed to create a class and set the constructor to be private.  So you’d write something like : -

private function MemoryModelLocator()
{
}

However you can’t do this in AS3.  So we have a hack.  The Cairngorm team have acknowledged it as a hack, so I’ll say it too, hack, hack, hack.  To understand how this hack works we need to look at the new package structure of AS3.  In this case : -

package com.worthyashes.simpleCairngorm.model
{
//The class goes in here
}

Now if I put another class in this package (folder) I would be able to instantiate the MemoryModelLocator class without importing it and use the functions within it.  I could create an instance of the class without any bother at all, and we want to stop this.  So we create a class outside the package declaration.

//End of class
}
class SingletonEnforcer{}

This class is outside the curly brackets that close off the package, and is not available to ANY class except for the MemoryModelLocator class.

So if we pop an instance of this Singleton enforcer class into the constructor of the MemoryModelLocator class then we can force the MemoryModelLocator class to only ever be instantiated by itself through the getInstance() function.

So the constructior is : -

public function MemoryModelLocator(enforcer:SingletonEnforcer)
{
if (enforcer == null)
{
throw new Error("Like at the end of Highlander, before the crap sequal, there can be only one");
}
}

and the getInstance() function looks like this.

public static function getInstance():MemoryModelLocator
{
if (_instance == null)
{
_instance = new MemoryModelLocator(new SingletonEnforcer());
}
return _instance;
}

To go through this and explain it, remember that the _instance variable is static and therefore will be the same every time this class is accessed.  What we do with the getInstance() call is to first of all check if the _instance variable exists.  If not then we create it by calling the constructor with an instance of the SingletonEnforcer class.  This can be accessed by the getInstance() function as it is in the MemoryModelLocator class.  Then we return the _instance variable.  So if we make the call to the getInstance() function in the MemoryModelLocator we will ALWAYS get the same Singleton.  As it is a static function (which it has to be so we can call it and return a static variable) we use it slightly differently, like this : -

var model:MemoryModelLocator = MemoryModelLocator.getInstance();

Right – hopefully that all made sense.  It’s a bit confusing, but hopefully once you see the ModelLocator in action it’ll all be made clear!

Category:Cairngorm, Flex, Frameworks, Tutorials | Comments (2) | Autor: admin

Custom Flex Preloaders Part Five : A few more examples

Monday, 23. June 2008 11:27

In Part Four we tidied up the code a bit with another class I’ve called CustomPreloader to extend the DownloadProgressBar class and hold the required functions for CustomPreloaders.  Now if we extend the CustomPreloader class all we need to do is override the listener functions to control our preloader.  So lets have a look at another example.

In this case we are going to use the timeline on the MovieClip to display the download time.  All I’ve done is create a Flash File and a preloader MovieClip within it.  Then in the preloader MovieClip i made it have 100 frames and on each frame I put the text “Frame 1″, “Frame 2″ etc.  You can get the example from here -> Timeline Preloader FLA

Now the code.

package com.worthyashes.preloaders
{
	import flash.display.MovieClip;
	import flash.events.ProgressEvent;

	public class TimelineCustomPreloader extends CustomPreloader
	{
		private var preloadMovieClip:MovieClip

		[Embed(source="assets/swf/timeline.swf",symbol="preloader")]
		private var PreloadAssets:Class;

		public function TimelineCustomPreloader()
		{
			super();
			preloadMovieClip = new PreloadAssets();
			addChild(preloadMovieClip);
			preloadMovieClip.gotoAndStop(1);
		}

		private function centrePreloader():void
		{
			x = (stageWidth/2) - (preloadMovieClip.width/2);
			y = (stageHeight/2) - (preloadMovieClip.height/2);
		}

		override protected function preloadStarted():void
		{
			centrePreloader();
		}

		override protected function downloadProgress(event:ProgressEvent):void
		{
			var percent:int = Math.floor(event.bytesLoaded/event.bytesTotal*100);
			preloadMovieClip.gotoAndStop(percent);
		}

	}
}

And we change the code on the Application tag in the MXML to be

<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml”
layout=”horizontal”
preloader=”com.worthyashes.preloaders.DynamicPreloader”>

So we are pointing to the correct class.  Lets quickly go through the code, as it is quite straightforward.

public function TimelineCustomPreloader()
{
super();
preloadMovieClip = new PreloadAssets();
addChild(preloadMovieClip);
preloadMovieClip.gotoAndStop(1);
}

The only change we have here is we need to stop the preloader playing as soon as it is instantiated.

override protected function downloadProgress(event:ProgressEvent):void
{
var percent:int = Math.floor(event.bytesLoaded/event.bytesTotal*100);
preloadMovieClip.gotoAndStop(percent);
}

As we go through the download as we work out the percentage downloaded we round off the figure and then tell the clip to display (and stop at) that frame.

Click here to have a look.

Right – well that should give you a good idea how you can use a Falsh MovieClip in a swef as a preloader for flex and how to control it.  What about somethign a bit more interesting?  What if you wanted to create a preloader but not use any Flash assets at all, and do it totally dynamically?  OK – lets have a go.

Lets look at the DynamicPreloader.as

package com.worthyashes.preloaders
{
	import flash.events.ProgressEvent;

	public class DynamicPreloader extends CustomPreloader
	{
		private var preloadSprite:DynamicPreloadDisplay;

		public function DynamicPreloader()
		{
			super();
			preloadSprite = new DynamicPreloadDisplay();
			addChild(preloadSprite);
			trace("New dynamic preloader");
		}

		private function centreSprite():void
		{
			x = (stageWidth/2) - (preloadSprite.width/2);
			y = (stageHeight/2) - (preloadSprite.height/2);
		}

		override protected function preloadStarted():void
		{
			centreSprite();
		}

		override protected function downloadProgress(event:ProgressEvent):void
		{
			preloadSprite.displayDownload(event.bytesLoaded/event.bytesTotal*100);
		}

	}
}

Lets go through the code – it won’t take long ;) .

First look at the variables

private var preloadSprite:DynamicPreloadDisaply;

This is the preloader that we will dynamically create.  We instantiate it in the DynamicPreloader constructor. (NOTE: I left the trace in so if you run this code through the debugger it will trace to the console even though flex hasn’t started properly yet)

Finally we need to send the percent downloaded to the DynamicPreloadDisplay class, so we trigger a function I’ve called displayDownload

override protected function downloadProgress(event:ProgressEvent):void
{
preloadSprite.displayDownload(event.bytesLoaded/event.bytesTotal*100);
}

Lets now look at the DynamicPreloadDisplay.as

package com.worthyashes.preloaders
{
	import flash.display.Sprite;
	import flash.filters.BevelFilter;
	import flash.filters.DropShadowFilter;
	import flash.filters.GlowFilter;
	import flash.text.TextField;

	public class DynamicPreloadDisplay extends Sprite
	{
		private var percentText:TextField;
		private var line:Sprite;
		private var totalLineWidth:int = 260;

		public function DynamicPreloadDisplay()
		{
			drawBackground();
			addText();
			addLine();
			createFilters();
		}

		private function drawBackground():void
		{
			graphics.beginFill(0x666666,1);
			graphics.drawRoundRect(0,0,300,100,10,10);
			graphics.endFill();
		}

		private function createFilters():void
		{
			var bevel:BevelFilter = new BevelFilter();
			this.filters = [bevel];
		}

		private function addText():void
		{
			percentText = new TextField();
			percentText.width = 300;
			percentText.x = 20;
			percentText.y = 20;

			var glowFilter:GlowFilter = new GlowFilter();

			percentText.filters = [glowFilter];

			addChild(percentText);
		}

		private function addLine():void
		{
			line = new Sprite();
			line.x = 20;
			line.y = 40;

			addChild(line);
		}

		public function displayDownload(percent:int):void
		{
			line.graphics.clear();
			line.graphics.lineStyle(2,0x00ff00,1);
			line.graphics.beginFill(0xffffff,1);
			var lineWidth:int = totalLineWidth*percent/100;
			line.graphics.drawRect(0,0,lineWidth,15);
			line.graphics.endFill();

			var dropShadowFilter:DropShadowFilter = new DropShadowFilter();
			line.filters = [dropShadowFilter];

			percentText.text = percent.toString() + "% Downloaded";
		}

	}
}

Again lets go through the code.  The DynamicPreloadDisplay extends the Sprite class.  This gives us access to the drawing api and a sprite to display the preloader in.

Constructor : -

public function DynamicPreloadDisplay()
{
drawBackground();
addText();
addLine();
createFilters();
}

When I’m coding I like to pull things out into individual functions that do one thing (well that’s what i try to do) this means that if I need to fix something I’m normally only looking at one specific problem at a time.

Draw Background function

private function drawBackground():void
{
graphics.beginFill(0x666666,1);
graphics.drawRoundRect(0,0,300,100,10,10);
graphics.endFill();
}

This merely draws the background.

Add Text

I want to have a text field to display the percentage downloaded so I create one on the fly.  Note that we create this after the background.  If we did it the other way round the background would be on top of the textfield.

private function addText():void
{
percentText = new TextField();
percentText.width = 300;
percentText.x = 20;
percentText.y = 20;
//Add a filter for a laugh
var glowFilter:GlowFilter = new GlowFilter();

percentText.filters = [glowFilter];

addChild(percentText);
}

Now I want to create a line to display how much has been downloaded visualy

private function addLine():void
{
line = new Sprite();
line.x = 20;
line.y = 40;

addChild(line);

}

The line is another sprite held by the DynamicPreloadDisplay sprite.

Finally – and this is just to demonstrate that this is possible – I’ve added a filter to the background.

private function createFilters():void

{

var bevel:BevelFilter = new BevelFilter();

this.filters = [bevel];

}

The last function to look at is the displayDownload function

public function displayDownload(percent:int):void

{

line.graphics.clear();

line.graphics.lineStyle(2,0x00ff00,1);

line.graphics.beginFill(0xffffff,1);

var lineWidth:int = totalLineWidth*percent/100;

line.graphics.drawRect(0,0,lineWidth,15);

line.graphics.endFill();

var dropShadowFilter:DropShadowFilter = new DropShadowFilter();

line.filters = [dropShadowFilter];

percentText.text = percent.toString() + "% Downloaded";

}

We clear the graphics from the line sprite.  Then we define the line style and fill.  If you want to understand this a bit better then please look at the Flash Drawing API.  Again I’ve applied filters just for the sake of it.

Finally we set the percentText to the percent downloaded.

Click here to see it working.

Well – I apologise for the shocking design but I hope this has given you a good overview of how to implement and create custom preloaders for Flex.  Have fun!

Category:Flash, Flex, Flex Builder, Tutorials | Comments (2) | Autor: admin

Custom Flex Preloaders Part Four : Tidying up the Code

Sunday, 22. June 2008 16:32

Right so in Part Three we actually got to write a bit of code and see a working custom flex preloader (even if it doesn’t really look very pretty).

Looking at the code I can tidy this up a bit.  We are always going to need to override the set preloader function to add the listeners.  I’m a bit lazy so if I create a class in-between then I can save a bit of typing.  My new CustomPreloader class looks like this : -

package com.worthyashes.preloaders
{
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.ProgressEvent;

	import mx.events.FlexEvent;
	import mx.preloaders.DownloadProgressBar;

	public class CustomPreloader extends DownloadProgressBar
	{
		public function CustomPreloader()
		{
			super();
		}
		//This is the most important
		override public function set preloader(preloader:Sprite):void
		{
			preloader.addEventListener(ProgressEvent.PROGRESS,downloadProgress);
			preloader.addEventListener(Event.COMPLETE,downloadComplete);
			preloader.addEventListener(FlexEvent.INIT_PROGRESS,flexInitProgress);
			preloader.addEventListener(FlexEvent.INIT_COMPLETE,flexInitComplete);
			preloadStarted();
		}

		protected function preloadStarted():void{}

		protected function downloadProgress(event:ProgressEvent):void{}

		protected function downloadComplete(event:Event):void{}

		protected function flexInitProgress(event:FlexEvent):void{}

		protected function flexInitComplete(event:FlexEvent):void
		{
			dispatchEvent(new Event(Event.COMPLETE));
		}
	}
}

To use this class then we can extend it and then override the listener functions as required.  There is also a default function in the flexInitComplete listener to trigger the COMPLETE Event.  Unless it is required to change this function (easily done by overriding the function) then this class will deal with letting the Application know when to start.

So if we refactor the BasicCustomPreloader.as class we get : -

package com.worthyashes.preloaders
{
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.ProgressEvent;

	import mx.events.FlexEvent;

	public class BasicCustomPreloader extends CustomPreloader
	{
		private var preloadMovieClip:MovieClip;

		[Embed(source="assets/swf/basic.swf",symbol="preloader")]
		private var PreloaderAssets:Class;

		public function BasicCustomPreloader()
		{
			super();
			preloadMovieClip = new PreloaderAssets();
			addChild(preloadMovieClip);
		}

		private function centreClip():void
		{
			x = (stageWidth/2) - (preloadMovieClip.width/2);
			y = (stageHeight/2) - (preloadMovieClip.height/2);
		}

		override protected function preloadStarted():void
		{
			centreClip();
		}

		override protected function downloadProgress(event:ProgressEvent):void
		{
			var percentage:int = Math.round(event.bytesLoaded/event.bytesTotal*100)
			preloadMovieClip.percent_txt.text = percentage.toString() + "%";
		}

		override protected function downloadComplete(event:Event):void
		{
			preloadMovieClip.percent_txt.text = "100%"
		}

		override protected function flexInitProgress(event:FlexEvent):void
		{
			preloadMovieClip.percent_txt.text = "Initialising";
		}
	}
}

This is hardly earth shattering, bit it does tidy things up a bit and make the implementation of a CustomPreloader a little easier.

In the final part of this tutorial I’ll create two more preloaders, one that will use the timeline of the swf and another that will dynamically draw a preloader without using any assets at all.

Category:Flash, Flex, Flex Builder, Tutorials | Comment (0) | Autor: admin

Custom Flex Preloaders : Part Three Finally we’re playing with Flex

Sunday, 22. June 2008 15:07

OK – so check out Part Two for see the flash assets we’ve produced and download them from here if you need them – > Basic Flash Assets.

Now we want to create a new flex project.  Open flex and create a new project, call it whatever you feel like and click on finish.

Create an assets folder, and in the assets folder create a swf folder (where we’ll pop the preloader swf) and I’ve created an originals folder to put some images that we will use to bloat the flex file so we can have a decent file size to test the preloaders are working.

To hold the code I’ve created a com/worthyashes/preloaders folder.  This is a standard way of creating a namespace for your code so it won’t conflict with any other code that you may be using in the project.  I also create an archive folder – this is just something I do to hold bits and is not necessary for this to work.

Custom Preloader Folder Structure

Save the swf to the assets/swf folder and we are ready to go.

First off we need to bloat the file so we’ve got something to work with.

BasicCustomPreloader.mxml : -

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
preloader="com.worthyashes.preloaders.BasicCustomPreloader"
layout="vertical">
<mx:Script>
<![CDATA[
/*
Here are some images to bloat up the size of the swf
*/
import mx.events.FlexEvent;

[Bindable]
[Embed(source="assets/originals/bush.jpg")]
private var img1:Class;
[Embed(source="assets/originals/charlieHavingBreakfast.jpg")]
private var img2:Class;
[Embed(source="assets/originals/field1.jpg")]
private var img3:Class;
[Embed(source="assets/originals/field2.jpg")]
private var img4:Class;
[Embed(source="assets/originals/frostyHedge.jpg")]
private var img5:Class;
[Embed(source="assets/originals/frozenBranches.jpg")]
private var img6:Class;
[Embed(source="assets/originals/gardenSteps1.jpg")]
private var img7:Class;
[Embed(source="assets/originals/gardenSteps2.jpg")]
private var img8:Class;
]]>
</mx:Script>
<!--We'll display an image so we can prove it initialised properly-->
<mx:Image source="{img1}" width="100%" height="100%" horizontalAlign="center"/>
</mx:Application>

Using the Embed keyword we are telling the compiler to add these files to the swf, not load them at runtime.  Normally you wouldn’t want to do this but it’s perfect for us as we want to have a large swf.  This has pushed the swf size up to just over 10Meg.  Perfect.  The last thing we do is display one of the images so we have a visual cue that the application has loaded.

The line in the Application tag

preloader=”com.worthyashes.preloaders.BasicCustomPreloader”

Tells the application to ignore the standard preloader and load our Custom Preloader class instead.

Now for the preloader code.  I’ll reproduce it here and then we’ll go through it.

BasicCustomPreloader.as

package com.worthyashes.preloaders
{
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.ProgressEvent;

	import mx.events.FlexEvent;
	import mx.preloaders.DownloadProgressBar;

	public class BasicCustomPreloader extends DownloadProgressBar
	{
        private var preloadMovieClip:MovieClip;

		[Embed(source="assets/swf/basic.swf",symbol="preloader")]
		private var PreloaderAssets:Class;

		public function BasicCustomPreloader()
		{
			super();
            preloadMovieClip = new PreloaderAssets();
			addChild(preloadMovieClip);
		}
		//This is the most important
		override public function set preloader(preloader:Sprite):void
		{
			preloader.addEventListener(ProgressEvent.PROGRESS,downloadProgress);
			preloader.addEventListener(Event.COMPLETE,downloadComplete);
			preloader.addEventListener(FlexEvent.INIT_PROGRESS,flexInitProgress);
			preloader.addEventListener(FlexEvent.INIT_COMPLETE,flexInitComplete);
			preloadStarted();
		}

		private function preloadStarted():void
        {
             centreClip();
        }

        private function centreClip():void
		{
			x = (stageWidth/2) - (preloadMovieClip.width/2);
			y = (stageHeight/2) - (preloadMovieClip.height/2);
		}

		private function downloadProgress(event:ProgressEvent):void
        {
            var percentage:int = Math.round(event.bytesLoaded/event.bytesTotal*100)
			preloadMovieClip.percent_txt.text = percentage.toString() + "%";
        }

		private function downloadComplete(event:Event):void
        {
            preloadMovieClip.percent_txt.text = "100%";
        }

		private function flexInitProgress(event:FlexEvent):void
        {
            preloadMovieClip.percent_txt.text = "Initialising";
        }

		private function flexInitComplete(event:FlexEvent):void
		{
			dispatchEvent(new Event(Event.COMPLETE));
		}
	}
}

We’d better go through the code.

First of all, as we discussed in Part One, we are extending the DownloadProgressBar class.  This class has all of the functionality for handling the loading and initialising of the application, so we don’t have to worry about that.

Next we have a variable to hold our MovieClip that we will use as the preloader.

private var preloadMovieClip:MovieClip;

And we will embed the swf.

[Embed(source="assets/swf/basic.swf",symbol="preloader")]
private var PreloaderAssets:Class;

The swf needs to be embedded as a generic Class, but we have a second attribute in the Embed metadata which has a reference to the symbol we are going to use.  This is given the same name as the Linkage name we gave the symbol in the flash movie.  So we now have access to the preloader movieclip.

In the constructor we can tie these two variables together.

public function BasicCustomPreloader()
{
super();
preloadMovieClip = new PreloaderAssets();
addChild(preloadMovieClip);
}

This bit of code sets up the preloadMovieClip variable as a new instance of the preloader movieclip from the embeded swf file.  Now we can use dot notation to access anything within this clip.

Next we override the set preloader function from the DownloadProgressBar Class.  We set up four event listeners to handle the download progress and the initialisation of the application.

override public function set preloader(preloader:Sprite):void
{
preloader.addEventListener(ProgressEvent.PROGRESS,downloadProgress);
preloader.addEventListener(Event.COMPLETE,downloadComplete);
preloader.addEventListener(FlexEvent.INIT_PROGRESS,flexInitProgress);
preloader.addEventListener(FlexEvent.INIT_COMPLETE,flexInitComplete);
preloadStarted();
}

These are mapped to further functions which will actually do the work for the preloader.  The preloadStarted function is called to do any initial work required for the preloader, in our case making sure the preloader is displayed in the centre of the screen. (I won’t go through that code, it’s very straight-forward)

Lets look at the listeners

private function downloadProgress(event:ProgressEvent):void
{
var percentage:int = Math.round(event.bytesLoaded/event.bytesTotal*100)
preloadMovieClip.percent_txt.text = percentage.toString() + “%”;
}

The downloadProgress function works out the percentage loaded and then displays the result in the percent_txt dynamic text field that lives in the preload movieclip in the swf.  As you can see we can get to this text field using the preloadMovieClip variable we set up earlier and dot notation.
private function downloadComplete(event:Event):void
{
preloadMovieClip.percent_txt.text = “100%”;
}

When the download is complete we can simply set it to 100%.  However this isn’t the end of the preload process as we now need to wait for the application to build itself and initialise.
private function flexInitProgress(event:FlexEvent):void
{
preloadMovieClip.percent_txt.text = “Initialising”;
}

Once the download is complete we need to display some sort of indicator that the application is starting.  In this case I made it quite simple and just changed the text in the percent_txt text  field.
private function flexInitComplete(event:FlexEvent):void
{
dispatchEvent(new Event(Event.COMPLETE));
}

Once the application is fully downloaded and initialised we need to dispatch a COMPLETE event.  As we’ve overridden the existing function in the DownloadProgressBar it will not automatically dispatch this event and we need to do it ourselves.

You can see the working preloader here.

Next lets tidy up the code and have a bit of fun.

Category:Flash, Flex, Flex Builder, Tutorials | Comment (0) | Autor: admin

Custom Flex Preload Part Two : Producing the SWF

Sunday, 22. June 2008 12:26

Please see Part One for the introduction to this post

We are going to embed a swf into a class that extends the DownloadProgressBar to take the place of the standard flex preloader.  Rather than just dumping a swf into the preloader we want to have some form of access to the assets in the swf so we can display the percent loaded, maybe show some sort of visual cue as to how much has downloaded.

So fire up flash and lets get stuck in.

Create a new flash document (FLA), and select ActionScript 2.

New Flash File

We need to create a MovieClip to expose the asset to Flex and we don’t want to associate it with a class, which we would have to do if we chose ActionScript 3.

As I’ve pointed out many times before I am NOT a designer, so this preloader is going to look a bit ropey, but it will serve to illustrate the point.

What we need is a movieclip with a linkage name in the library for us to be able to access it from Flex.  So draw a box and then select it and press F8 to turn it into a movielcip.

Create Symbol Dialog Box

I’ve popped the name of preloader and selected “Export for ActionScript” and “Export in the first Frame”.  I’ve left the linkage name as “preloader,” this is the name we will use in the Flex code to identify this MovieClip.

Click OK.  Double Click the movie clip (Cntrl Click on a Mac – I think, I don’t use one) to edit it.  To make things easy I’ve created a couple of layers, one for the background (the box) one for static text and one for dynamic text (the text that will display the amount  of the application that is loaded).

Preloader Dynamic Text

As you can see I gave the dynamic text a name of “percent_txt.”  Save the file and export it.

You can download the fla from here – > Basic Flash Assets

Next - lets look at the flex code.

EDIT – I said this needed to be in AS2 from the Flash IDE.  After more time working with Flex I’ve actually realised that you can export in AS3 from the IDE and use class names, ignore the warnings about there being no class file and use the class name you gave the asset exactly as I said the instance name should be used above.

Category:Flash, Flex, Flex Builder, Tutorials | Comments (2) | Autor: admin

Custom Flex Preloaders : Part One – Credit where credit is due

Friday, 20. June 2008 17:19

So – I’ve got bored of the standard flex preloader.  (Actually the company I’m working at has)  I’ve got away with it so far as the applications I’ve been working on have either been back-end systems or prototypes so the great unwashed (in which I include myself, expecially today as Charlie was up most of the night and I didn’t have a chance for a shower this morning after oversleeping) never saw the grey box.Standard Flex Preloader

Don’t get me wrong, as with most flex components the standard design is very nice, just a bit, well, er, basically it looks like a flex app.

As normal I need to thank a few guys for some fantastic posts that put me on the right track : -

Jesse Warden

Ted On Flex

I am Josh

I’m not trying to steal these guys ideas and post them as my own, what I am doing is to write up what I understand here in a way that I can swallow.

Back to custom preloaders.

With all the other framework components it is really easy to apply CSS, skins or images to style them up.  The problem with the preloader is that it is, well it’s preloading the framework.  We have no access to any of the flex framework except for a class called the DownloadProgressBar.  We have this class and the standard flash classes that are available to us in the flash player.

We definately do want to use the DownloadProgressBar, for the reasons explained by Jesse Warden

“Flex’ built in preloader is pretty sweet. It auto-adjusts for your application’s color to stand out, it handles all aspects of preloading. This includes remote shared libraries, fonts, and even deferred classes used in modules. Finally, it deals with the initialization of your Flex application which can possibly take longer than a few milliseconds. ”

There’s no point in us re-writing functions that do the above if they are already in the DownloadProgressBar class, so we only need to worry about displaying something instead of the standard preloader and get some useful information into it.

Lets look at a very simple example, we will load a swf as a replacement for the standard preloader.

Next we’ll look at what we need to do with the Flash FLA to make it’s assets available for Flex.

Category:Flash, Flex, Flex Builder, Tutorials | Comment (0) | Autor: admin

Cairngorm Getting Started Part Two : Setting up the Environment

Thursday, 19. June 2008 22:26

For an overview of Cairngorm check out part one.

OK – before we can start we need to set up the environment.  First things first go and get Cairngorm from here.  For now just download the binary, but further down the line you may want to download the source to have a look at the guts of the code.  Unzip the folder to somewhere that you can easily find.  I have a central folder called codeLibrary for all central code, but to be honest you can keep it on the desktop if you want.

Now fire up Flex Builder and create a new project.

Creating a new flex project

Don’t click on finish click on next, the next screen asks where you want to compile the application to (default is fine, normally bin-debug), click next again.  Now we need to map in the Cairngorm library in, this is the .swc file you got in the download.

Click on the library tab, then the Add SWC button.

Browse to the folder where you unzipped the file and select the Cairngorm.swc.

Click OK

Cairngorm folder sturcture

then finish.

Now we have access to the Cairngorm library.

NOTE : If tyou do get overexcited and click on finish and create the project before adding the Cairngorm.swf simply right click on the project, select preferences then Flex Build Pah.  This will then show you a similar dialog to the one I described above and you can map in the SWC there.

Final thing to do is to set up the folders for the Cairngorm structure.  This is not compulsory, but you’ll find it a lot easier if you have a folder structure like this.

Right click and select new – > folder.  I won’t go through it step by step, but here’s the recommended structue.
Cairngorm Folder Structure

EDIT : I realised that’s not too clear.  The folder structure is : -

com

____>worthyashes

————->simpleCairngorm

—————————>business

—————————>commands

—————————>control

—————————>events

—————————>model

—————————>responder

—————————>view

—————————>vo

The com/worthyashes bit is just a standard namespace so if someone uses my classes they shouldn’t conflict with other classes (worthyashes is my normal username).

simpleCairngorm – this folder is really to hold all the code that specifically relates to this Cairngorm app.  This means that if you have a number of different bits of your app all using Cairngorm in theory you can pull an individual bit out and use it on other project, for example a user management system.

The sub folders of the simpleCairngorm folder are the actual suggested folder structure for Cairngorm.

Sorry it wasn’t clear from the piccy.

END OF EDIT.

OK – thats done.  Next – finally time to get our hands dirty with some code! (Well nearly.…..)

Category:Cairngorm, Flex, Flex Builder, Frameworks, Tutorials | Comment (0) | Autor: admin