Some UcompOSStyleProxy Basics

If you are a regular reader of this blog, you know that a lot of blogs have been dedicated to talking about the UcompOS Proxy components.  However, one component that hasn’t received a lot of attention so far is the UcompOSStyleProxy.

The UcompOSStyleProxy provides a means to manage the style properties of the UcompOS Main Container.  For instance, you can use the UcompOSStyleProxy to override the default background image on the UcompOS Main Container or set fade in\out duration effects on UcompOSWindowProxy instances.

To demonstrate the two behaviors above, let’s take a look at a simple UcompOSStyleProxy code example.  First, in my UcompOS instance, I have created a simple HTML application called styler.html that is loaded as a background application by my dockManifest.xml file.  The code in my styler.html application is fairly simple and easy to follow as evidenced by the following sample code:

<HTML>
<HEAD>
<SCRIPT TYPE=”text/javascript” SRC=”/UcompOSSDK.js”></SCRIPT>
<SCRIPT TYPE=”text/javascript”>

//instantiate the UCompOSSDK
function start()
{

//instantiate a UcompOSStyleProxy instance that we can apply styles to
var styler = new UcompOSStyleProxy();

//set the default background image to Picture1.jpg at the correct file path on the server
styler.setBackgroundImage(“/applications/Picture1.jpg”);

//now, set the UcompOSWindowProxy instances to fade in\out 3 seconds
styler.setWindowFadeInDuration(3000);
styler.setWindowFadeOutDuration(3000);

}

</SCRIPT>
</HEAD>
</HTML>

Hopefully, this example is simple enough to follow along with fairly easily; the mechanics involved are designed to be as straightforward as possible. However, one could easily envision scenarios where a user’s preferences are saved in a database and loaded at run-time by turning styler.html into a scripted application using PHP, PERL, or the language of your choice.  Or, perhaps you may look at setting and instantiating style properties at startup using your dockManifest. The choice is up to you!

Note also that it is also possible, for example, to change the color of text on the menu bar by using some code like (using our example above):

styler.setStyle(“.MenuBar”,”color”,0x0000FF);

You will want to keep in mind, though, that it is likely that the UcompOSStyleProxy class will continue to evolve in such a way that setting styles in this manner may not work in the future. Therefore, this practice is not recommended at this time. However, you will want to stay tuned to the updates that are made to this class as the UcompOS SDK continues to mature over the coming months.

Garbage Collection in the UcompOS RPF

OscarTheGrouch In large and sophisticated Flash-based applications, such as the Rich Portal Applications you develop with the UcompOS Rich Productivity Framework, Garbage Collection becomes an increasingly important consideration.

Garbage Collection is a computer science concept that deals with memory management and re-allocating memory occupied by objects that are no longer needed or in use by the computer program.

Garbage Collection in a large-scale event-driven Flash architecture is a crucial consideration and unfortunately, can also be a tedious proposition to properly implement.

One of the more important considerations in aiding with Garbage Collection in Flash-based application is proper management of event listeners.

In a best-practice implementation, any call to addEventListener() would be followed up with a call to removeEventListener() once the event listener was no longer needed. Event listeners perpetuate the objects they are associated with so even once a particular object is destroyed, that doesn’t necessarily mean any event listeners associated with it will be destroyed too.

Failure to remove event listeners once they are no longer needed in a large-scale implementation can cause memory leaks and performance can break down over time.

In all your Flash applications, you should employ this strategy when and where possible.

In a typical large-scale UcompOS RPF implementation, Flash-based applications and sub-applications are continuously being loaded and unloaded into the UcompOS Portal.

The concept of Proxy Components in the UcompOS RPF involves event listeners being attached to a Proxy Component in one entity that represents an object in another UcompOS entity and then listening for dispatched events.

Therefore, the concept of garbage collection takes on especially critical importance in the UcompOS RPF because if UcompOS applications are being loaded and unloaded constantly and the event listeners that are attached to them are not being properly removed, performance would become an issue in a large-scale implementation.

The UcompOS Portal has been designed such that when SWF content that has been loaded into the UcompOS Portal is unloaded, a garbage collection routine is implemented to try to optimize system performance. (The three ways SWF content is loaded into the UcompOS Portal is in UcompOS Window instances, UcompOS Artifact instances, or into the UcompOS run-time.)

As of the UcompOS RPF Public Alpha release 0.4.6, some additional enhancements to the garbage collection process have been implemented that I will discuss here.

Understanding the UcompOS RPF garbage collection architecture can help you build more scalable Rich Portal Applications.

The recent enhancements come in the realm of Proxy Components.

By strict convention, all Proxy Components must extend the SDK class AbstractProxyComponent. As of UcompOS RPF 0.4.6, AbstractProxyComponent now extends a new SDK class called SDKEventDispatcher which extends EventDispatcher.

(Also, as a side-note, the AbstractProxyComponent class now implements IEventDispatcher in addition to IProxyComponent so you can refer to your Proxy Components as IEventDispatcher or IProxyComponent instances interchangably.)

SDKEventDispatcher simply overrides addEventListener() and offers a protected property _listeners of type Array.

I chose to create this separate class versus simply overriding addEventListener() in AbstractProxyComponent so that in the event the new clean-up process employed can be useful outside the scope of a Proxy Component, one could simply extend SDKEventDispatcher versus EventDispatcher.

Here is the over-ridden addEventListener():

override public function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void
{
	_listeners.push({type:type,listener:listener});
	super.addEventListener(type,listener,useCapture,priority,true);
}

Notice that I am always assigning a true value to the useWeakReference parameter in the super call to addEventListener(). This is because in the context of attaching event listeners to Proxy Components, you always would want them to be weak references to aid in garbage collection.

In AbstractProxyComponent, there is a new protected method, cleanup() which is as follows:

protected function cleanup(event:SDKEvent=null):void
{
	while(_listeners.length)
	{
		var object:Object = _listeners.pop();
		removeEventListener(object.type,object.listener);
	}
	_sdkModel.removeProxyComponent(this.uuid);
	var commandObject:CommandObject = new CommandObject("SDK.cleanup",{uuid:this.uuid});
	var dataPackage:DataPackage = new DataPackage(Utilities.createUID(),_sdkModel.connectionId,this.destination,commandObject);
	_sdkClient.send(dataPackage);
}

What the cleanup() method does is it automatically removes any event listeners that have been attached to the Proxy Component.

It also sends a message to the end-point of the Proxy Component targeting its SDK.cleanup public API method that is built into the UcompOS SDK and therefore exposed by any UcompOS entity. This aids in UcompOS RPF garbage collection-related activities.

Calls to cleanup() do not occur automatically.

When you would call cleanup() in a Proxy Component would be an implementation specific consideration.

For instance, with these new capabilities, I have updated some of the UcompOS Portal Proxy Components that are built into the UcompOS SDK.

Consider the updated constructor of the UcompOSWindowProxy class:

public function UcompOSWindowProxy()
{
	super();
 
	// set the destination property to the UcompOS Portal
	super._destination = _sdkModel.root;
	<strong>addEventListener(CLOSE,cleanup);</strong>
}

The call to addEventListener(CLOSE,cleanup) is the new addition to the constructor.

What it does is it causes the inherited cleanup() method to always be called when the UcompOS Window instance on the UcompOS Portal that is represented by the UcompOSWindowProxy instance is closed.

Therefore, any event listeners you have attached to the UcompOSWindowProxy instance are automatically removed whenever the window is closed.

In 100% of the possible use cases for the UcompOSWindowProxy, this is the desired behavior.

The net result of this is you don’t have to worry about making your own calls to removeEventListener() for your particular UcompOSWindowProxy instances.

The same sort of behavior has been engineered into some of the other Proxy Components built into the UcompOS SDK including UcompOSAlertProxy, UcompOSDialogueProxy, UcompOSArtifactProxy, and UcompOSBrowserWindowProxy.

Consider this strategy when you are building your own Proxy Components and remember to always use removeEventListener() in all your other Flash applications whether you are deploying them in the UcompOS Portal or not.

Instantiating UcompOS Global (Continuum) Variables at Startup

In my post about UcompOS Shared Objects, I described how the UcompOS Portal furnishes a Shared Object Implementation that can be written to and read by any UcompOS entity in the UcompOS Continuum.

In a large-scale UcompOS Rich Portal Application, you very likely may find a need to share complex data across multiple UcompOS entities.

One effective approach to this challenge is to use the UcompOSGlobalManagerProxy class’s setSharedObject(), getSharedObject(), and getSharedObjects() methods.

These methods get/set shared objects on the UcompOS Portal at run-time.

But what if you want to populate the UcompOS Portal’s shared Object at start-up even before any UcompOS applications are launched?

As of the version 0.4.1 Milestone release of UcompOS RPF, there is a way to do this.

The key is a new <globalVariables/> element that can be added as a child element to the root <applications/> element in a dock manifest and as a child element to the root <application/> element in a UcompOS application manifest.

Below is a simple example of this in action in the dock manifest of my Educator 2 software application being built entirely on top of the UcompOS RPF:

<?xml version="1.0" encoding="utf-8"?>
<applications>
	<globalVariables>
		<globalVariable>
			<key>_DOMAIN_</key>
			<value>applications.ucompass.com</value>
		</globalVariable>
		<globalVariable>
			<key>_PROTOCOL_</key>
			<value>http</value>
		</globalVariable>
		<globalVariable>
			<key>_GATEWAY_</key>
			<value>http://pilotfish2.ucompass.com/apps/gateway</value>
		</globalVariable>
	</globalVariables>
	<application background="true" default="true">
		_PROTOCOL_://_DOMAIN_/Educator2PortalFoundation/manifest.xml
	</application>
</applications>

Each global variable is wrapped in a <globalVariable/> element with child <key/> and <value/> elements.

All global variables in the dock manifest will automatically be added to the UcompOS Portal’s Shared Object implementation and will immediately be available to all UcompOS entities.

String Substitutions in Manifest Files

In the above example, notice I am instantiating global variable named _PROTOCOL and _DOMAIN_. And then notice that those strings appear in my <application/> element.

A string substitution will automatically take place here such that the <application/> value will be http://applications.ucompass.com/Educator2PortalFoundation/manifest.xml after the substitution.

As mentioned earlier, the <globalVariables> element is supported in both application manifests and dock manifests so you can also establish global variables in this fashion when launching a UcompOS application.

Typing Shared Objects

The <value/> element supports an optional type attribute such that you can articulate the data type of a Shared Object.

The best way to show how this is accomplished is with examples:

Array

<globalVariable>
	<key>groceryList</key>
	<value type="Array">
		<item>Bananas</item>
		<item>Cereal</item>
		<item>Diapers</item>
	</value>
</globalVariable>

Object

<globalVariable>
	<key>contacts</key>
	<value type="Object">
		<item>
			<key>Joe</key>
			<value>555-1212</value>
		</item>
		<item>
			<key>Bob</key>
			<value>555-2121</value>
		</item>
	</value>
</globalVariable>

The type attribute can also be of type uint, int, Boolean, Number and String. The default data type is String. Also, the <item/> element supports the type attribute for Arrays and Objects.

Also, nesting of complex data structures is supported, so you can implement an Array of Arrays, or an Array of Objects, etc.

Introducing 3 New UcompOS Portal Proxy Components

The UcompOS SDK in the latest milestone release of the UcompOS Rich Productivity Framework, Public Alpha 0.3.1, contains 3 new UcompOS Portal Proxy Components that open up a host of new capabilities.

In this article, I’ll briefly introduce each of these 3 new components and show some examples of how they can be used and I plan to build some new tutorial content in the near future to cover these 3 new components.

UcompOSKeyboardProxy

Within the scope of an individual UcompOS application or sub-application, you can certainly implement your own logic to handle keyboard events.

However, suppose you want to capture keyboard events that occur in the scope of the UcompOS Portal and pass them to other UcompOS entities such as those that may be running as AIR applications on the desktop, in separate UcompOSBrowserWindowProxy instances, or in sandboxed SWF implementations.

You can now use the new UcompOSKeyboardProxy class to do this.

The class is a Singleton with a single property named listen.

When you set the listen property to true, any keyboard events that occur in the scope of the UcompOS Portal will be dispatched by the UcompOSKeyboardProxy Singleton.

Let’s look at a simple code-based example of this:

package
{
 
	import flash.display.Sprite;
	import com.ucompass.ucompos.sdk.SDKClient;
	import com.ucompass.ucompos.sdk.proxycomponents.UcompOSKeyboardProxy;
	import com.ucompass.ucompos.sdk.events.SDKEvent;
 
	public class KeyboardExample extends Sprite
	{
 
		public function KeyboardExample()
		{
			SDKClient.getInstance(this);
			UcompOSKeyboardProxy.getInstance().listen = true;
			UcompOSKeyboardProxy.getInstance().addEventListener(UcompOSKeyboardProxy.KEY_DOWN,eventHandler);
			UcompOSKeyboardProxy.getInstance().addEventListener(UcompOSKeyboardProxy.KEY_UP,eventHandler);
		}
 
		private function eventHandler(event:SDKEvent):void
		{
			trace("Type of event: "+event.type);
			trace("Character code: "+event.data.charCode);
			trace("Alt key pressed: "+event.data.altKey);
			trace("Shift key pressed: "+event.data.shiftKey);
			trace("Control key pressed: "+event.data.ctrlKey);
			trace("Key code: "+event.data.keyCode);
		}
 
	}
 
 
}

As you can see, the properties in the event dispatched by the UcompOSKeyboardProxy Singleton are very similar to those of the Flash KeyboardEvent class.

UcompOSAlertProxy

The Flex Alert class is a modal dialogue.  It prevents the user from doing anything until they click a button control on the Alert dialogue.

The UcompOSAlertProxy class lets you throw a Flex Alert onto the UcompOS Portal.

When the user clicks a button on the Alert class, instances of UcompOSAlertProxy dispatch an SDKEvent instance.

The UcompOSAlertProxy class has two methods: confirm() and simpleAlert().

confirm() throws a confirmation style dialogue onto the UcompOS Portal.

Below is the signature of the confirm() method:

public function confirm(title:String,message:String,okLabel:String=null,cancelLabel:String=null,defaultButton:String=OK):void

As you can see, you can customize the alert title, the message of the Alert body, and the labels used on the “OK” and “Cancel” buttons.  You can also indicate which button should be the default button.

Let’s look at a code-based example:

package
{
 
	import flash.display.Sprite;
	import com.ucompass.ucompos.sdk.SDKClient;
	import com.ucompass.ucompos.sdk.proxycomponents.UcompOSAlertProxy;
	import com.ucompass.ucompos.sdk.events.SDKEvent;
 
	public class AlertExample extends Sprite
	{
 
		public function AlertExample()
		{
			SDKClient.getInstance(this);
			var a:UcompOSAlertProxy = new UcompOSAlertProxy();
			a.addEventListener(UcompOSAlertProxy.ALERT_SUBMIT,eventHandler);
			a.confirm("Confirm","Are you sure you want to delete this file?","Yes!","Hell No!",UcompOSAlertProxy.CANCEL);
		}
 
		private function eventHandler(event:SDKEvent):void
		{
			switch(event.data.detail)
			{
				case UcompOSAlertProxy.OK:
					trace("The file will be deleted");
					break;
				case UcompOSAlertProxy.CANCEL:
					trace("The file will NOT be deleted");
					break;
			}
		}	
 
	}
 
}

Notice in the example above, the SDKEvent‘s data Object will have a detail property that will be a value of UcompOSAlertProxy.OK or UcompOSAlertProxy.SUBMIT.  This is parallel to the implementation of the Alert in Flex.

The simpleAlert() method simply throws an Alert with a single button of type UcompOSAlertProxy.OK.

UcompOSDialogueProxy

In some instances, you’ll want to set up a modal user interaction dialogue when you want to capture some sort of input from the user.

To address this need, I created the UcompOSDialogueProxy class.

The UcompOSDialogueProxy is used to throw up a few different types of modal user interaction dialogues.

For instance, suppose you have a File Management application and you want to give the user the ability to choose a “Save As” option.

You don’t want the user to be able to do anything else until they either input a file name and press submit, or, cancel the operation.

This would be a perfect place to use the new UcompOSDialogueProxy class.

There are initially 4 different types of dialogues I have set up: TextInput for single line text input; TextArea for multiple line text input; RadioButtons for survey-type interaction; and SWFLoader which enables you to throw your own content into the dialogue and this content can be a UcompOS entity.

Below is the signature of the add() method of UcompOSDialogueProxy:

public function add(controlType:String=TEXT_INPUT,title:String="UcompOS Dialogue",label:String="",width:uint=400,height:uint=0,showCloseButton:Boolean=false,cancelLabel:String=CANCEL,submitLabel:String=SUBMIT,cancelEnabled:Boolean=true,submitEnabled:Boolean=true,initData:Object=null):void

Notice the default height is 0.  What happens is when the width or height is 0, the size of the Dialogue automatically conforms to the content that is placed inside of it.  Otherwise, the width/height is explicitly set.

The initData Object parameter has special meaning.

It is passed to the RadioButtons and SWFLoader types of Dialogues and examples of how initData is constructed in those two scenarios is depicted in the examples below.

Let’s look at a code-based example that shows how to use each of the 4 different types of dialogues:

TextInput Dialogue Example

package
{
 
	import flash.display.Sprite;
	import com.ucompass.ucompos.sdk.SDKClient;
	import com.ucompass.ucompos.sdk.proxycomponents.UcompOSDialogueProxy;
	import com.ucompass.ucompos.sdk.events.SDKEvent;
 
	public class TextInputDialogue extends Sprite
	{
 
		public function TextInputDialogue()
		{
			SDKClient.getInstance(this);
			var d:UcompOSDialogueProxy = new UcompOSDialogueProxy();
			d.add(UcompOSDialogueProxy.TEXT_INPUT,"Sample Dialogue","What is your name?");
			d.addEventListener(UcompOSDialogueProxy.DIALOGUE_SUBMIT,eventHandler);
		}
 
		private function eventHandler(event:SDKEvent):void
		{
			var d:UcompOSDialogueProxy = event.target as UcompOSDialogueProxy;
			trace("Your name is "+event.data.data);
			d.close();
		}
 
	}
 
}

Notice in the above example, in the eventHandler() method, the UcompOSDialogueProxy‘s close() method is called.  The dialogue does not disappear by itself upon a submission.  You have to explicitly remove it with the close() method such that you have much better control over when the dialogue is closed based on the specifics of the user’s input.

TextArea Dialogue Example

package
{
 
	import flash.display.Sprite;
	import com.ucompass.ucompos.sdk.SDKClient;
	import com.ucompass.ucompos.sdk.proxycomponents.UcompOSDialogueProxy;
	import com.ucompass.ucompos.sdk.events.SDKEvent;
 
	public class TextAreaDialogue extends Sprite
	{
 
		public function TextAreaDialogue()
		{
			SDKClient.getInstance(this);
			var d:UcompOSDialogueProxy = new UcompOSDialogueProxy();
			d.add(UcompOSDialogueProxy.TEXT_AREA,"Sample Dialogue","Please tell us why you like the UcompOS in 1,000 words or less:");
			d.addEventListener(UcompOSDialogueProxy.DIALOGUE_SUBMIT,eventHandler);
		}
 
		private function eventHandler(event:SDKEvent):void
		{
			var d:UcompOSDialogueProxy = event.target as UcompOSDialogueProxy;
			trace(event.data.data);
			d.close();
		}
 
	}
 
}

The TextArea example is almost identical to the TextInput example.

RadioButtons Dialogue Example

package
{
 
	import flash.display.Sprite;
	import com.ucompass.ucompos.sdk.SDKClient;
	import com.ucompass.ucompos.sdk.proxycomponents.UcompOSDialogueProxy;
	import com.ucompass.ucompos.sdk.events.SDKEvent;
 
	public class RadioButtonsDialogue extends Sprite
	{
 
		public function RadioButtonsDialogue()
		{
			SDKClient.getInstance(this);
			var d:UcompOSDialogueProxy = new UcompOSDialogueProxy();
			var choices:Array = ["ActionScript 3","JavaScript","PERL","C++"];
			d.add(UcompOSDialogueProxy.RADIO_BUTTONS,"Sample Dialogue","What is your favorite programming language?",0,0,false,UcompOSDialogueProxy.CANCEL,UcompOSDialogueProxy.SUBMIT,true,true,{choices:choices});
			d.addEventListener(UcompOSDialogueProxy.DIALOGUE_SUBMIT,eventHandler);
		}
 
		private function eventHandler(event:SDKEvent):void
		{
			var d:UcompOSDialogueProxy = event.target as UcompOSDialogueProxy;
			trace("Your favorite programming language is: "+event.data.data);
			d.close();
		}
 
	}
 
}

Notice in the example above, we are building an Array of choices to give to the user where a Radio Button will be associated with each choice.  The Array is passed as a property named choices in the initData parameter passed to the UcompOSDialogueProxy‘s add() method.

SWFLoader Dialogue Example

package
{
 
	import flash.display.Sprite;
	import com.ucompass.ucompos.sdk.SDKClient;
	import com.ucompass.ucompos.sdk.proxycomponents.UcompOSDialogueProxy;
	import com.ucompass.ucompos.sdk.events.SDKEvent;
 
	public class SWFLoaderDialogue extends Sprite
	{
 
		public function SWFLoaderDialogue()
		{
			SDKClient.getInstance(this);
			var d:UcompOSDialogueProxy = new UcompOSDialogueProxy();
			var source:String = "http://applications.ucompass.com/MyCustomDialogue.swf":
			d.add(UcompOSDialogueProxy.SWF_LOADER,"Sample Dialogue","",0,0,false,UcompOSDialogueProxy.CANCEL,UcompOSDialogueProxy.SUBMIT,true,true,{source:source});
			d.addEventListener(UcompOSDialogueProxy.DIALOGUE_SUBMIT,eventHandler);
		}
 
		private function eventHandler(event:SDKEvent):void
		{
			var d:UcompOSDialogueProxy = event.target as UcompOSDialogueProxy;
			trace("The Connection Id of your SWF content is: "+event.data.data);
			d.close();
		}
 
	}
 
}

In this case, we are passing the URL of a SWF to the dialogue.  When the user presses the Submit button for the dialogue, the connection id of the SWF content is returned in the SDKEvent dispatched by the UcompOSDialogueProxy instance.

From here, UcompOS SDK transactions could be used to communicate directly with the SWF content and retrieve special information from it.

In-Depth Coverage of the UcompOS Menu Bar

The menu bar feature on the UcompOS Portal can be customized in a number of different ways.  This article will discuss the basics of the UcompOS menu bar, and also provide a look at some of the features that have been recently added to the menu bar including support for keyboard shortcuts.

Attaching a Menu Bar to a UcompOS Application

The common paradigm of using the menu bar is to have a custom menu bar implementation appear while a particular UcompOS application is in focus.

There are two ways to go about doing this.

The first is to attach an XML model for the menu bar to the particular UcompOS application’s manifest file.

Below is an example of a simple menu bar model that would be placed in the UcompOS application manifest file as a child of the root application element.

	<menu>
		<menuitem label="File">
			<menuitem label="Open"/>
			<menuitem label="Close"/>
			<menuitem label="Quit"/>
		</menuitem>
		<menuitem label="Edit">
			<menuitem label="Copy"/>
			<menuitem label="Paste"/>
		</menuitem>
	</menu>

You can also add a custom menu bar implementation to a UcompOS application at run-time.

This is accomplished using the UcompOSMenuBarProxy class that is built into the UcompOS SDK.

UcompOSMenuBarProxy is a Singleton, meaning it is instantiated via a static method.

It offers a setMenuBar() method that accepts a parameter model of type XML (String in the JavaScript SDK).

Below is a simple example of the UcompOSMenuBarProxy‘s setMenuBar() method at work:

var menuBarModel:XML = new XML("<menu><menuitem label='File'><menuitem label='Open' data='open'/><menuitem label='Close' data='close'/></menuitem></menu>");
UcompOSMenuBarProxy.getInstance().setMenuBar(menuBarModel);

If you have done any coding in Flex and added your own XML dataProvider to a Flex MenuBar implementation, the above example should look familiar.  The XML data model we are using is based on the model that is used inside of Flex.

The Base UcompOS Menu Item

By default, UcompOS Portal implementations will have a base menu bar item that is perpetually viewable throughout the user’s session.  This is analogous to the Mac OS X Operating System’s menu bar implementation that has a base menu bar item on the left of the menu bar represented by Apple’s trademark logo.

BaseMenuBar

The base menu bar option is shown above.

Overriding the Base Menu Item

You can replace the built-in UcompOS menu bar item with your own custom implementation in one of two ways.

One such way is by adding a baseMenu element to one of your UcompOS application’s manifest files.

Below is an example of this:

<baseMenu>
	<menuitem label="Company X">
		<menuitem label="About Our Company" data="about"/>
	</menuitem>
</baseMenu>

This would replace the base UcompOS menu bar item with an option labeled “Company X” that has an “About Our Company” sub option.

Below is an example of the custom base menu bar for the Educator 2 software I am building on top of the UcompOS RPF:

Educator2MenuBar

The other way would be to use the UcompOSMenuBarProxy class and to override the base menu item at run-time.

The second parameter of the UcompOSMenuBarProxy‘s setMenuBar() method is an optional Boolean property named baseMenu that defaults to false.

When you pass in a true value for this parameter, the menu bar model you pass to setMenuBar() will become the base menu item.

There can only be one base menu item at a time throughout your entire UcompOS implementation.  If UcompOS Application A sets the base menu item, then UcompOS Application B sets the base menu item later, it will override the base menu item set by UcompOS Application A.

It is planned at some point that the UcompOS Dock Manifest will indicate which UcompOS Applications have the privilege of setting the base menu item which could be an important consideration in large collaborative development environments.

Sharing a Menu Bar Across Multiple UcompOS Applications

In some implementations, you may want one menu bar implementation to be used across multiple applications.

To do this, you would declare one of your applications as the default application.  This is accomplished in one of two ways: in the Dock Manifest by passing a default=”true” attribute to an <application/> element, or at run time with the UcompOSGlobalManagerProxy‘s isDefaultApplication property.

When a default application is set on the UcompOS Portal, then any UcompOS Applications that have the following menu bar models:

	<menu default="true"/>

will use the Menu Bar implementation that is assigned to the application that has been declared as the default application.

As a note of caution, only one application can be declared as the default at a time on the UcompOS Portal.  If you try to declare an application as the default while another application has already been defined as the default, a run-time error will occur.  This is by design, and you must set the isDefaultApplication property of the UcompOSGlobalManagerProxy to false before you can set it to true for another application.

As is the case with setting base menu items, I am considering setting it up at the Dock Manifest level such that it is articulated ahead of time which applications can declare themselves as the default.

Menu Bar Icons

The model for the UcompOS menu bar supports the icon attribute for menuitem elements.  The value of the icon attribute should be the full URL to an image of type GIF, JPG, or PNG.

You can use any sized icon but it is recommended you use an icon sized at 18×18.

Below is an example of a menu bar implementation with icons:

MenuBarIcons

Menu Bar Separators

In the image above, notice there is a separator between the “Delete” and “Close” options.

This is accomplished with the following menuitem element:

	<menuitem type="separator"/>

Window-Specific Menu Bars

In some UcompOS applications, you may spawn many different UcompOS windows and load a variety of different sub-applications into each window instance.

Each window instance may need their own unique menu bar implementation.

The UcompOSWindowProxy class offers a setMenuBar() method that allows you to attach a custom menu bar implementation to individual UcompOS Window instances.

The menu bar will come into view whenever the window it is attached to comes into focus.  When the window closes, the menu bar will return to the existing menu bar implementation attached to the UcompOS application in focus.

Menu Bar Events

Obviously, if you go through the trouble of implementing a custom menu bar, you want to know when the user has selected an option on the menu bar.

When an item is selected on the menu bar, an event of type UcompOSMenuBarProxy.ITEM_CLICK is dispatched to any listening UcompOSMenuBarProxy instances.

A strict protocol that must be recognized is that only menuitem elements that have a data property will dispatch a UcompOSMenuBarProxy.ITEM_CLICK event.

Let’s look at a very simple code-based example:

package
{
 
	import com.ucompass.ucompos.sdk.proxycomponents.UcompOSMenuBarProxy;
	import com.ucompass.ucompos.sdk.events.SDKEvent;
	import com.ucompass.ucompos.sdk.SDKClient;
 
	public class MenuBarExample extends Sprite
	{
 
		public function MenuBarExample()
		{
			var menuBarModel:XML = new XML("<menu><menuitem label='File'><menuitem label='Select Me' data='testData'/></menuitem></menu>");
			SDKClient.getInstance(this);
			UcompOSMenuBarProxy.getInstance().setMenuBar(menuBarModel);
			UcompOSMenuBarProxy.getInstance().addEventListener(UcompOSMenuBarProxy.ITEM_CLICK,eventHandler);
		}
 
		private function eventHandler(event:SDKEvent):void
		{
			trace("The user said "+event.data.label);
			trace("The associaed data is "+event.data.data);
		}
 
	}
 
 
}

UcompOSMenuBarProxy.ITEM_CLICK events are only dispatched to UcompOS entities in the scope of the UcompOS application in focus when the menu item was selected.  So if UcompOS Application B has implemented a custom menu bar, and UcompOS Application A is in focus, no menu events will be dispatched to UcompOS Application B.

Keyboard Shortcut Commands

In applications where you load a lot of functionality onto the menu bar, keyboard shortcut commands can be a very convenient feature for your users, and, perhaps as importantly, they can help your applications address important accessibility standards crucial for many public-use applications.

To add a keyboard shortcut command to a menu item, you use the shortcutKey attribute to the menuitem element in a menu bar model.

For instance:

	<menu>
		<menuitem label="File">
			<menuitem label="Print" data="print" shortcutKey="ALT-P"/>
		</menuitem>
	</menu>

In the above example, when the user presses the ALT key and the P key simultaneously, the action that will take place will be exactly the same as if the user would have chosen the Print option with the mouse.

Below is an example of a similar implementation from Educator 2:

PrintOption

Uploading Files to a UcompOSArtifactProxy Instance

In a major UcompOS Portal Application I am building, I place UcompOS Artifact instances that represent file volumes on the UcompOS Portal. Over this past weekend, I found myself with the need to enable the user to right-click on the file volume artifacts (revealing their context menus) and choose an “Upload Files” option with the goal of providing the user a way to upload files directly to the root directory of the particular file volume.

My initial approach to this was to attach a Context Menu to the artifact instances with an “Upload Files” option.  I then created an event listener to listen for the UcompOSArtifactProxy.MENU_ITEM_SELECT event dispatched by the UcompOSArtifactProxy instance.

Once this event is dispatched, I reasoned I could then create a FileReferenceList instance and then call its browse() method and go from there.

However, when I attempted this, I was reminded of an important detail when an error was thrown once I called the FileReference.browse() method.

Just like the launching of AIR applications as well as the entry into Full Screen Mode, the opening of the file browse dialogue by the Flash Player must succeed a user-triggered mouse event.

In the context of the UcompOS Continuum, the entity where the mouse event occurs is the UcompOS Portal.  This is a completely separate entity from the code that is calling the FileReference.browse() method.

In my implementation, I have a Flash application that is running as a background application that sets up the aforementioned UcompOS Artifact instances that represent file volumes.

So when the user right clicks on the artifact and selects the Context Menu item, they are actually operating on the UcompOS Portal itself.

An SDKEvent is then dispatched to the background application and then what follows is the call to FileReferenceList.browse().

However, as far as the Flash Player is concerned, in that scenario, the call to FileReferenceList.browse() does NOT proceed a user-triggered mouse event because the mouse event occurs in a totally different scope.

So I have engineered a new process into the UcompOS Portal to enable the goals I described above.

I think the use case I am speaking to here is one that has good merit to be repeated by many developers – i.e. a widget that you can upload files to.  I can envision many scenarios where this could be useful such as file conversion utilities for one.

The model I have developed involves creating an uploadFiles property on the UcompOSArtifactProxy‘s data Object property.

The value of this uploadFiles property must be the same String value as the label placed on a Context Menu item that is attached to the artifact.

What will happen in this case, when the user selects the context menu option on the artifact on the UcompOS Portal, the file browse dialogue will open, and the user will be able to select multiple files.

After the user selects the files, what happens next is very important.

The UcompOS Portal will dispatch to the UcompOSArtifactProxy instance an SDKEvent for each attached file.

The SDKEvent‘s data property will have two properties: fileName:String and fileData:ByteArray, i.e. the name of the file and the contents of the file as a ByteArray.

From here you can do whatever you need to do with this information including upload the file to a remote server, do some sort of conversion, or anything else your specific use case requires.

Below, is a very simple code-based example of how you can create an Artifact and the user can change the artifact’s icon representation by uploading a new image to it.

The application is a UcompOS Flash application loaded into the UcompOS Portal as a background application.

package
{
	import flash.display.Sprite;
	import com.ucompass.ucompos.sdk.proxycomponents.UcompOSArtifactProxy;
	import com.ucompass.ucompos.sdk.SDKClient;
	import com.ucompass.ucompos.sdk.events.SDKEvent;
	import flash.events.Event;
 
	public class Main extends Sprite
	{
 
		private static const UPLOAD_LABEL:String = "Upload a new artifact image";
 
		public function Main()
		{
			// Instantiate the UcompOS SDK
			SDKClient.getInstance(this);
 
			// Create a UcompOS Artifact Proxy instance
			var artifact:UcompOSArtifactProxy = new UcompOSArtifactProxy();
 
			// Listen for uploaded files
			artifact.addEventListener(UcompOSArtifactProxy.UPLOAD_FILE,uploadHandler);
 
			// Initialize the artifact using a pre-defined image
			artifact.add("RIGHT CLICK ON ME!",null,"http://desktop.ucompass.com/UploadToArtifact/cloud-48x48.png",100,100,true,true,{uploadFiles:UPLOAD_LABEL});
 
			// Establish the context menu on the artifact with an Upload option
			artifact.setContextMenu(new XML(""));
		}
 
		private function uploadHandler(event:SDKEvent):void
		{
			var artifact:UcompOSArtifactProxy = event.target as UcompOSArtifactProxy;
 
			// Replace the artifact image with the content of the uploaded file
			artifact.setImage(event.data.fileData);
 
			// Show the name of the uploaded file as the label on the artifact
			artifact.setLabel(event.data.fileName);
		}
 
	}
 
}

Also, here is a link to a movie that shows the simple application in action.

Overriding the UcompOS Default MenuBar Item

The Menu Bar on the UcompOS Portal by default has a built-in menu item as displayed below:

DefaultMenuItem

You can override this default Menu Bar item in one of two ways.

First, in the application manifest for a particular application, you can specify the model for the Menu Bar that should be present when the application is in focus.

A sample Menu Bar model for a very simple File Management application may look something like this:

<menu>
	<menuitem label="File">
		<menuitem label="Open" data="open"/>
		<menuitem label="Close" data="close"/>
		<menuitem label="Quit" icon="http://apps.ucompass.com/exit.png" data="quit"/>
	</menuitem>
</menu>

As a relevant aside, the UcompOSWindowProxy has a setMenuBar(); method that accepts an XML object as input of the same form shown above. This lets you specify the model for the Menu Bar that should be in display while a particular window is in focus.

So you can have multiple windows spawned by the same UcompOS application all with different Menu Bar implementations. This is a very important capability.

What if you want to override the default UcompOS menu item and have 100% unique branding.

You can do this by building a baseMenu model into the application manifest.

For instance, my Educator 2 Menu Bar default Menu Bar item looks like this:

Educator2DefaultMenuItem

Here is the relevant code from my Application Manifest that articulates the base menu item:

<baseMenu>
	<menuitem label="" icon="http://applications.ucompass.com/Educator2PortalFoundation/images/Educator2_Menu_Bar_Icon.png">
		<menuitem label="About Educator 2" data="About Educator 2"/>
		<menuitem type="separator"/>
		<menuitem label="Logout" data="Logout" />
	</menuitem>
</baseMenu>

The setMenuBar(); method of the UcompOSMenuBarProxy class also has a second Boolean parameter named baseMenu. When you set a Menu Bar and pass true as the value for this parameter, that model will override the default UcompOS MenuBar implementation.

Overriding the default UcompOS MenuBar is just one of many ways to create a 100% unique and customized experience for users of your Rich Portal Application.

Self-Referencing Proxy Components

The AbstractProxyComponent class in the UcompOS SDK must, by strict convention, be the superclass for all Proxy Components. Understanding the mechanics of AbstractProxyComponent and its public properties and methods is a crucial step in building the most powerful Proxy Components that promote richer and more engaging experiences for users of your Rich Portal Application.

In this post, I will touch on one of the public properties of AbstractProxyComponent, self, and explain its purpose and provide a use-case scenario.

As you know, in the context of the UcompOS Continuum, the UcompOS Portal is simply one of X UcompOS entities, each of which have the UcompOS SDK implemented.

The UcompOS Portal sponsors a host of public API methods and the UcompOS SDK has been equipped with a batch of Proxy Components that serve as clients that can be used in your own UcompOS Applications to connect to these public API methods.

At the current time, the self property on AbstractProxyComponent may seem tightly coupled to the UcompOS Portal’s Proxy Components and specifically, to two of those Proxy Components: UcompOSWindowProxy and UcompOSArtifactProxy. However, as the UcompOS RPF continues to expand, the self property on a Proxy Component will take on increasingly significant meaning.

Right now however, the UcompOSWindowProxy and UcompOSArtifactProxy provide a very good model with which to illustrate the purpose of this self property.

As you know, when you create an instance of UcompOSWindowProxy and call its add(); method, you are launching a UcompOS Window on the UcompOS Portal and you are specifying the URL of the content that should be loaded into this window.

Behind the scenes, when the UcompOS SDK loads this content to the UcompOS Window, it passes the content some crucial information that that content will use to become a member of the UcompOS Continuum thereby being able to participate in SDK transmissions with other entities.

Here’s an interesting question:

What if you load some content into a UcompOS Window, and then you want to reference the UcompOS Window that the content is loaded into from the content itself?

The answer to this is you would create a UcompOSWindowProxy instance and then set its self property to true.

As an example of how I have used this capability, I have created a Rich Text Editor for my Educator 2 application I am building on top of the UcompOS RPF. This editor is a Flex 4 implementation.

In Educator 2, by strict convention, all SWF content I load into UcompOS Window and UcompOS Artifact instances is loaded in sandboxed configurations and I rely 100% on SDK transmissions for communication with other entities (the exception is drag and drop which I talked about in this posting).

The challenge then becomes, how do I resize the editor? To resize the editor, the user isn’t going to actually resize the editor itself, rather, the UcompOS Window instance the editor is loaded into. Since my content is sandboxed, I can’t access the parent container the content is loaded into using traditional scripting from within my Editor application.

The solution is to create a reference to a UcompOSWindowProxy and set its self property to true.

Let’s take a look at some code here that is similar to what you’d see in my editor application:

private function init(event:FlexEvent):void
{
 
	// Instantiate the UcompOS SDK
	SDKClient.getInstance(this,new ServicesDictionary());
 
	// Create a UcompOS Window Proxy instance
	var w:UcompOSWindowProxy = new UcompOSWindowProxy();
 
	// Create a self-reference - w in this case becomes a reference to
	// the UcompOS Window instance the content in scope is loaded into
	w.self = true;
 
	// listen for window resize events
	w.addEventListener(UcompOSWindowProxy.RESIZE_END,resizeHandler);
	w.addEventListener(UcompOSWindowProxy.MAXIMIZE,resizeHandler);
	w.addEventListener(UcompOSWindowProxy.RESTORE,resizeHandler);
 
}
 
// the SDKEvent instance dispatched to this handler following
// a window resize operation contains the new width/height of the
// UcompOS Window - the width and height of the content viewing
// portions of the UcompOS Window are housed in the event.data.width
// and event.data.height properties
private function resizeHandler(event:SDKEvent):void
{
 
	var w:UcompOSWindowProxy = event.target as UcompOSWindowProxy;
 
	// suppose my editor component is a variable named myEditor
	myEditor.width = event.data.width;
	myEditor.height = event.data.height;
 
}

These same mechanics can be leveraged in UcompOSArtifactProxy instances.

In fact, in one of my earliest UcompOS Video Tutorials entitled Building a UcompOS Weather Channel Widget, we saw this technique.

In that implementation, I created a self referencing UcompOSArtifactProxy instance so I could attach a Context Menu to the UcompOS Artifact and capture user selections on this Context Menu.

Here is a very simple example of a Flash CS4/CS5 UcompOS Application that leverages this principle:

package
{
 
	import flash.display.Sprite;
	import com.ucompass.ucompos.sdk.SDKClient;
	import com.ucompass.ucompos.sdk.proxycomponents.UcompOSArtifactProxy;
	import com.ucompass.ucompos.sdk.events.SDKEvent;
 
	public class Example extends Sprite
	{
 
		public function Example()
		{
 
			var sdkClient:SDKClient = SDKClient.getInstance(this);
 
			var artifact:UcompOSArtifactProxy = new UcompOSArtifactProxy();
			artifact.self = true;
			artifact.setContextMenu(new XML(""));
			artifact.addEventListener(UcompOSArtifactProxy.MENU_ITEM_SELECT,contextMenu_handler);
 
		}
 
		private function contextMenu_handler(event:SDKEvent):void
		{
			trace("User selected "+event.data.label);
		}
 
	}
 
}

Cross-Application Interactions in UcompOS Implementations

One of my primary goals in the design of the UcompOS Rich Productivity Framework was to create a flexible environment for the deployment of multiple Rich Internet Applications that needed to work either separately, or discretely to create a singular overall rich experience.

UcompOS Applications launched by the UcompOS Portal are sandboxed in such a way that they exist as isolated entities that can operate independently from the environment they’ve been loaded into.

As I touched upon in my posting on Building Drag and Drop Experiences in the UcompOS RPF, UcompOS applications should not attempt to access other UcompOS entities directly through direct ActionScript or JavaScript class/method interaction.

This is not to say that you cannot do this, but if you were going to, say, load two separate UcompOS entities into a n0n-sandboxed configuration, and have each entity access the other’s classes, you would obviously be tightly coupling the entities in such a way that if two different developers were working on each entity, one could very easily break the implementation unintentionally.

If you have a very compelling reason to do this, I have not prevented you from doing this.

In this posting, I will touch upon some of the numerous models for achieving cross-application interactivity in the UcompOS RPF.

Proxy Components and Services Dictionaries

The model for interactivity across the boundaries of UcompOS entities and applications is to use the framework that’s built into the UcompOS SDK, mainly Services Dictionaries and Proxy Components.  These are two extremely important concepts to understand, which is why I touch upon them so frequently.

In review, a Services Dictionary publishes a list of the “Public API” methods that an entity exposes to other entities.  A Proxy Component is a client apparatus in one entity that is built to connect to the Public API method sponsored by some other entity.

As I’ve also explained numerous times, and particularly in this posting, the UcompOS SDK has a number of Proxy Components built into it that are client apparatus’ to the Public API methods of the UcompOS Portal.  After all, the UcompOS Portal is simply one entity in the overall context of the UcompOS Continuum.

Numerous postings and tutorials I’ve posted give examples of building Services Dictionaries and Proxy Components so I won’t go into the details of this in this posting, but again, understanding their mechanics is crucial.

UcompOS SDK Events

Another crucial concept to understand in the UcompOS RPF is its Event-based implementation.

By strict convention, all Proxy Components extend a class in the UcompOS SDK named AbstractProxyComponent.

As the name implies, it is an abstract class and should never be instantiated directly, only extended.  (Unfortunately, ActionScript 3 doesn’t give us a true foolproof way to enforce abstractness.)

AbstractProxyComponent extends EventDispatcher so thus all Proxy Components inherit an addEventListener(); method.

So essentially, in one UcompOS entity, you can build a Proxy Component that talks to the Public API method in another entity.  And you can register an event listener to receive event notices from that Proxy Component.

That’s why I call these things “Proxy” Components.

You are creating a virtual representation in one entity of a physical implementation in another entity, so essentially, your Proxy Component is a “Proxy” to the true implementation that is actually located in an entirely different entity.

So when you do something like the following:

var w:UcompOSWindowProxy = new UcompOSWindowProxy();
w.add("http://blog.ucompass.com","UcompOS",800,600);
w.addEventListener(UcompOSWindowProxy.CLOSE,closeHandler);

w in the above scenario is an instance of the Proxy Component UcompOSWindowProxy that is built into the UcompOS SDK.

w is not REALLY the window that gets created on the UcompOS Portal, but it is a virtual representation of it.

But when you add an event listener on the CLOSE event of the window, it is as if you are attaching an event listener to the actual window itself.

I am hopeful that the concept of Proxy Components is making more and more sense to the dedicated readers of this blog.

The event handlers implemented with any Proxy Component are exclusively dispatched an instance of the SDKEvent class.

The SDKEvent class is worth studying.

If you look at the AS3 docs for the SDKEvent class, you’ll notice it has a collection of read-only properties.  One of which is data and another is proxyComponent.

By strict convention, any Public API method in a UcompOS entity returns an item of type Object.  This data is carried back to the Proxy Component that invoked the Public API Method in the form of an SDKEvent instance.

So for instance, building to our simple example above, I could do something like this:

w.addEventListener(UcompOSWindowProxy.WINDOW_INFO,windowInfoHandler);
w.getWindowInfo();
 
private function windowInfoHandler(event:SDKEvent):void
{
 
 // this will be the Object returned by the Public API method I contacted
 var data:Object = event.data;
 
 trace("Window size is "+data.width+" x "+data.height);
 
}

Let’s talk a bit about the proxyComponent property of SDKEvent instances.

It is of type IProxyComponent.

The AbstractProxyComponent event implements the interface IProxyComponent from the SDK, so any Proxy Component can be cast as an item of type IProxyComponent.

Dispatching an Event to a Proxy Component from a Public API Method

So you have built your Public API method and you have set up a Proxy Component in another entity to connect to this Public API Method.

As I have explained, the Object your Public API Method MUST return will be returned to your Proxy Component packaged in an SDKEvent instance.

But what if you asynchronously want to dispatch an SDKEvent to a Proxy Component?

The key to this is the BroadcastEvent class in the SDK and its static dispatchEvent(); method.

As an example of when we might use this capability, suppose we have a UcompOS AIR application that sponsors a Public API Method that allows us to asynchronously return the list of files in a directory.

The implementation of this might look something like this:

private var _uuid:String;
 
public function getFilesInDirectory(data:Object):Object
{
 _uuid = data._dataPackage.uuid;
 var directory:File = new File(data.directory);
 directory.addEventListener(FileListEvent.DIRECTORY_LISTING,getFilesInDirectory_handler);
 directory.getDirectoryListingAsync();
 return SDKEvent.VOID;
}
 
private function getFilesInDirectory_handler(event:FileListEvent):void
{
 var files:Array = [];
 for(var i:uint = 0;i&lt;event.files.length;i++)
 {
 files.push((event.files[i] as File).name);
 }
 BroadcastEvent.dispatchEvent(_uuid,"fileListing",{files:files});    
}

As a brief aside, notice in the Public API method, I am returning SDKEvent.VOID.  This actually suppresses the return altogether of any data to the calling Proxy Component.  This is the best practice when your Public API method doesn’t return anything of value to the calling Proxy Component.

When the UcompOS SDK passes the input Object to a Public API method, it adds a property to the Object called _dataPackage which itself is an Object.

This Object has a property, uuid, which is the same value of the uuid property on the Proxy Component that originated the transaction with the Public API method.

The BroadcastEvent.dispatchEvent(); method expects this uuid value as the first input parameter.

A Proxy Component that invoked this Public API method could have an event listener listening for events of type “fileListing”.  In this scenario, the event handler would be dispatched an SDKEvent with the data dispatched to the BroadcastEvent.dispatchEvent(); method.

Dispatching Continuum Events

The UcompOSGlobalManagerProxy class in the UcompOS SDK has a method named dispatchContinuumEvent();.

It accepts two parameters – the type of event, and a data Object.

When you call this method, you are dispatching an event to every entity in the UcompOS Continuum and the event can be listened for on the UcompOSGlobalManagerProxy Singleton.

So for instance, you could say something like:

UcompOSGlobalManagerProxy.getInstance().dispatchContinuumEvent("myEvent",{name:Ed});

And in an entirely different entity, you could do something like this:

UcompOSGlobalManagerProxy.getInstance().addEventListener("myEvent",eventHandler);

and your event handler could look something like:

private function eventHandler(event:SDKEvent):void 
{
 
 trace("Your name is "+event.data.name);
 
}

The dispatchContinuumEvent(); method doesn’t need to target a specific entity as the BroadcastEvent.dispatchEvent(); method does – it simply dispatches an event to EVERY entity.

Launching one UcompOS Application from Another Entity

The UcompOSGlobalManagerProxy class has a launchApplication(); method which accepts as input an Application Manifest URL as a String.

This enables you to launch a UcompOS Application from another entity.  Similarly, there is a quitApplication(); method as well as a getConnectionId(); method which can be used to find the connectionId of an already running UcompOS Application.

UcompOS Shared Objects

As I posted here, the UcompOS RPF now has a Shared Object implementation where an entity can house Objects of specific names on an Object on the UcompOS Portal that is available to all other entities.

When any Shared Object is created or its properties are updated, a Continuum Event is dispatched.

This creates an environment where the Shared Object itself can become a useful medium for achieving inter-application and inter-entity communication.

Preloaders in UcompOS Implementations

In an enterprise-level UcompOS Rich Portal Application, many disaggregated applications may come together to create an overall rich experience.

Some of these applications may be relatively small HTML/JavaScript type applications that take virtually no time at all to load.  Other applications may be large and complex Flex applications that easily approach several megabytes in file size.

Providing the user with feedback and information about an application while it is loading is a critical part of creating a positive rich experience.

The UcompOS Portal has a built-in pre-loader dialogue that is a stylized progress bar implementation.

By default, the label on the pre-loader will read “Ucompass.com, Inc.”.

You can however override this by passing in a parameter named preloaderTitle to the UcompOS Portal implementation.

Click here for a simple example of this.

If you don’t want to append a query string to the UcompOS Portal URL, you can also set the value of the preloaderTitle global variable in your LocalLib.js JavaScript package that is in the ucompos/local/LocalLib.js file in the UcompOS Developers Package.  This resource is used to build custom authentication into your UcompOS Portal implementation.

Also, when you load Flash or Flex content into a UcompOS Window instance, you can customize the preloader that the user sees while the content is loading into the window.

By default, a generic progress bar dialogue appears (the same one used for the loading of the UcompOS Portal) with the title “Loading…” while the SWF content is loading into the UcompOS Window instance.

However, this text can be customized so that you could create messages that say things ranging from “Getting Sent E-Mails” to “Searching Flickr”.

Let’s take a look at the full signature of the add(); method of the UcompOSWindowProxy class:

public function add(source:String, title:String = Untitled Window, 
     width:uint = 400, height:uint = 300, x:uint = 0, 
     y:uint = 0, suppressParameters:Boolean = false, 
     sandbox:Boolean = true, preloaderTitle:String = null, 
     format:String = null):void

Notice the second to last parameter, preloaderTitle.

The value of this will be the value on the text field on the preloader that appears in the UcompOS Window while the SWF content is loading.

Below is a simple visual example of this:

PreloaderWindow

The preloader dialogue does not show up on HTML type applications loaded into a UcompOS Window.

Also, you can specify the pre-loader to be used on a “self-loading” applications.  A self-loading application is loaded immediately into a UcompOS Window versus simply being loaded invisibly into the UcompOS run-time.  This is accomplished by setting a selfLoading attribute in the root element of the application manifest for the UcompOS application and giving it a value of true.

To do this, simply set a preloaderTitle attribute in the root element of the application manifest.

If you are loading a Flex application into a UcompOS Window and that application furnishes its own preloader, then that preloader will be used versus the UcompOS Window’s default preloader.

At this time, I have not created a way to overload the default preloader used in the loading of the UcompOS Portal so you can only customize its text field for now using the technique illustrated above.