Site Contents
Home
My Blog
ColdFusion
JRun
Flex
Wireless & Networking
Hardware & Gadgets
HDTV
Software Picks
Pictures
Contact Me
Search


My Articles & Papers
Flex Performance
Server/Client
mm.com Under the Hood
Multiple Instances of CFMX
Multiple Instance Config
NLB with ColdFusion
Clustering CFMX for J2EE
Multi-Tier Hardware LB w CFMX
Cisco CSS & Coldfusion MX
JRun 4 Jini based Clustering
WiFi Growth

2ID Tacweb

Other Hobbys
Body-For-Life Challenge

Personal Projects
Family Pool
Deck Gate

username:
password:
 

 
Macromedia Flex

Macromedia Flex Presentation Server

Flex Developers Center
Developing Flex Applications (Livedocs)
Flex ActionScript Language (Livedocs)
Downloadable Documentation

Blogs:
Christophe Coenraetes
Eric Anderson
Kevin Hoyt
Matt Chotin
Ben Forta
Steven Webster
Tom Link 
Peter Ent
Waldo Smeets

flexcoders.org - mailing list
Viewing by Category: Flex / Main
September 8, 2008

Utah State Senator and Ogden City Police Chief blogs about Spatialkey and the power of bringing together relevant data sets from multiple places. Here is a small sampling of Chief Griener's posting.

"Not just any map - it's a combination map of satellite images, street map, and my geographically assigned patrol beat map in layers. The company (Universal Mind) has made it so user friendly that I can literally research and plot over 400,000 calls for service in the last 5 years in about 30 seconds. The system is web based so quickly analyzing What-Ifs can be accomplished anytime, anywhere, on any computer with an air card. You can begin to see how this would be valuable to me and my law enforcement team."

SpatialKey Law Enforcement continues to evolve and improve to provide cutting edge technology to the Law Enforcement community. It is exciting to be a part of great team with so much potential. Keep an eye on the SpatialKey blog for other important news around SpatialKey in general.

SpatialKey_ComputerWorld.jpg

The most recent issue of ComputerWorld magazine features a cover story called "Can Web 2.0 Save B.I.?" that features a case study on SpatialKey. In the article they interview Chief Jon Greiner of the Ogden Police Department in Utah. Ogden is the first installation of the enterprise version of SpatialKey Law Enforcement Dashboard (see the press release), and Universal Mind has been working closely with the Ogden PD to use the SpatialKey platform to develop what we think is a game-changing crime mapping product.

Yes that is our application on the cover. Check out the online version of the article on ComputerWorlds' website

September 1, 2008

After leaving Adobe in November of 2007 I joined Universal Mind as the director of Technology. UM had been working on a product that was called LaunchPad. At that time LaunchPad was a proof of concept built for the San Francisco PD with basic heatmap capabilities and no server side architecture. Our goal was to pull together a team with GIS experience, data visualization and build a kick ass product based on LaunchPad. As a consulting organization it is a unique endeavor to go off and build a product that is not targeted toward any specific customer. With a small team and some part time resources we set out to build what is now known as SpatialKey. Over the last nine months I have had the pleasure of managing an amazing group of resources on the SpatialKey project. Initially we started with a very small team of Doug McCune and Ben Stucki. Anyone in the Flex community recognizes Doug and Ben as amazing Flex developers and it did not take me long to realize the same thing. I am amazed at the things they can do with Actionscript. In late December we hired Reggie Wilbanks. Reggie had worked in traditional GIS for a long time and brought us a lot of experience and quickly became a skilled AS3 and Flex developer. Andy Powell has also been a key resource while working with us part time in addition to customer facing projects. Zach Johnson joined our team in June straight out of University of Wisconsin with a masters in Cartography. Zach has great passion and skill for online mapping and data visualization and is a great writer as well. Behind the scenes Mike Connor has served as our product manager, Mike has been a great help to me in getting this product developed and shaping the Law Enforcement version. Tom Link has been the overall leader behind the project as Universal Mind's CTO. Thanks to Tom for bringing me to Universal Mind and giving me the great oppportunity to lead such an amazing team.

I am excited to finally introduce SpatialKey as a a next generation Information Visualization, Analysis and Reporting System. It is designed to help organizations quickly assess location based information critical to their organizational goals, decision making processes and reporting requirements. The technology preview allows you to use our visualization templates to look at sample datasets that we have collected over the last few months. A future release based on Adobe AIR will all users to import their own data and bring into the visualization templates to look at the data in multiple ways.

Why is it different?


Example view of SpatialKey

We've been seeing the same approach to web-based mapping for years now. It is pretty much all the same with just markers on a map. Little pin markers work fine if you're showing a few data points. If you are looking for the closest Star Bucks to your home you can pull up google, do a search and you see all of the Star Bucks within X miles of your home. Markers work great for that, but what if you wanted to see all of the StarBucks in the United States or play back the growth of Star Bucks as they grew from just a single coffee shop in Seattle to the thousands of locations around the country? Or only see the StarBucks built in the US during the 1990s? SpatialKey allows you to view thousands of points without the need of any server technology.

SpatialKey uses some of the most advanced visualization renderings for geospatial data that have ever been seen on the web. The focus here is on aggregate renderings: heatmaps, thematic grids, graduated circles. For large quantities of data you want to see density or sum total value. Piling a bunch of markers on top of each other ends up confusing users without a clear picture or story for the data. SpatialKey focuses on rendering aggregate data in meaningful ways. We can show a heatmap of the entire country or the entire world. and let you visualize any number of data fields. The technology preview is just using CSV files and loads them in at runtime, nothing is pre-rendered and you can intereact with the applications to filter the data and see updates within seconds. What you won't see (yet at least) is the same capability with a server implementation allowing you to do the same thing but with Millions of points. We are already doing this with our Law Enforcement version but could bring the same capability to other industries.

What can you do now?

Go check out our gallery pairing up our four visualization templates that launched with the Technology preview. We will be putting up videos in the near future to showcase the features and provide a walkthrough for each template. If you have a particular dataset that you think would be compelling to see use the contact us form to send us your information and we will be in touch to collect the data. Also sign up for the beta to be notified when the desktop application becomes available so that you can import and view your own data.

January 11, 2007
After installing Flex 2.0.1 I was frustrated to find that I was no longer getting output to my flashlog.txt files. After some searching around I found that it was moved to C:\Documents and Settings\username\Application Data\Macromedia\Flash Player\Logs. I found that this was due to security restrictions in Vista.

January 7, 2007

I was creating a simple application to enter IP addresses into a database and I found there was no simple way to validate the IP addresses. With Flex it is fairly simple to create a custom validator. The code below uses a regular expression to validate each octet of the IP to make sure it is in the range of 0-255. For an example of usage you can use any of the examples within the Flex documentation when using Validators.

package validators
{
 import mx.validators.Validator;
    import mx.validators.ValidationResult;
 
 public class IPValidator extends Validator {
        // Define Array for the return value of doValidation().
        private var results:Array;
        // Constructor.
        public function IPValidator() {
            // Call base class constructor. 
            super();
        }
    
        // Define the doValidation() method.
        override protected function doValidation(value:Object):Array {
            // Clear results Array.
            results = [];
            // Call base class doValidation().
            results = super.doValidation(value);        
            // Return if there are errors.
            if (results.length > 0)
                return results;
                
            if (String(value).length == 0)
             return results;
        
           var pattern:RegExp = /\b(25[0-5]|2[0-4][0-9]|[01]?[0-9]
[0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4]
[0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/;
     var r:Array = pattern.exec(String(value));
   if (r == null)
   {
    results.push(new ValidationResult(true, null, "NaN", 
                    "You must enter an IP Address"));
                return results;
   }
             return results;
        }
    }
}

November 17, 2005

I found this pretty cool and a great demonstration of the new power with FlashPlayer 8.5. FlashVNC is a Flash Player based client that connects to a TightVNC server. Check it out on Darrons blog.

July 29, 2005
In working with Flex and Flash I have used the crossdomain.xml several times. For someone new to Flex or Flash it is somewhat difficult to explain why it is needed. I end up drawing pictures and probably confuse the developer even more.  Martijn De Visser has an excellent explanation and slideshow on his blog. Check it out... The first time I looked at the slides I thought it was just a simple image, check out the NEXT button on the bottom right.

May 25, 2005

If you run a Flex or Flash application on Linux in Firefox or Mozilla you may see the application only render partially and the rest of the screen shows up gray or black.  This is a known issue with the Flash Player.  You can find some information on the mozilla website.

http://bugzilla.mozilla.org/show_bug.cgi?id=234328

Fortuneately there is a simple workaround. The workaround is to set the width to something other than 100%, which is the default for Flex applications.

May 19, 2005

Christophe demonstrates a very cool approach for integrating HTML pages/sites into an app that is 100% Flex and it makes the application look like the Flash Player is loading/rendering the HTML in the page.

You can check out his blog posting here: http://coenraets.com/viewarticle.jsp?articleId=95 

The example he posted is here: http://coenraets.com/apps/iframe/index.htm 

April 29, 2005

Over the last few months I have blogged very little due to time constraints, travel and vacation. I have been working on the Flex team for about a year and a half now and still continue to do ColdFusion development anytime a chance arises. I have seen a lot of questions recently about ColdFusion and Flex integration and my goal for blogging over the next few months is answering a lot of the common questions.

  1. Deployment options - seperate instances, single instance (deployed as a singe web app, deployed as a seperate web app)
  2. External Webserver configuration options (IIS & Apache)
  3. Data integration (HTTPService - XML, Webservices, RemoteObject (examples and gotchas)
  4. Authentication and Authorization

I am looking for other questions that I can answer as well and can put together code samples. I might even turn this into a dev center article if I can pull enough content together. Please post your comments or thoughts.

March 17, 2005

I have heard this question many times and I don't think it is documented. If you want to change the color of an entire row within a Datagrid in Flex use the following code

dg.setPropertiesAt(2, {backgroundColor:0xFF0000});

Where dg is your datagrid and the first parameter is the row of number you want to change

January 26, 2005

The validators that are provided in Flex cannot be localized or have the error strings easily changed because they cannot have an id, which means they cannot be accessed from script and you cant bind objects that dont have an id. One solution is to subclass the various validators and override their error string properties so they access variables in the application. Then all you have to do is load in strings into those variables and youre all set.

In the example, if you type xyz and hit tab, you will see the validator kick in with the custom message from the app, that calls the invalidCharError() and in the AS file you will see that it returns the string defined in the MXML file. You can also type in a custom error in the second TextInput and change the error on the fly allowing you to localize the errors easily from an XML file or other source. Also try typing in 123 and hitting tab on the first input and you will see another customized error message. Just locate the different methods in the MXML AS API and override each of the methods you need custom errors for.Note that the validation logic itself doesnt change at all you are just overriding the error messages.

Thanks to Alex for providing a starting point for this example. You can download the code here and it is also shown below

MXML file:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml" >
<mx:Script>
 var invalidCharError:String = 
 "Default Error for Invalid Phone Number!!";
 var wrongLengthError:String = 
 "Hey dummy the phone number needs to be at least 10 digits long!!";
</mx:Script>
   
   <mx:Model id="myModel">
     <employee>
   <phoneNumber>{phone.text}</phoneNumber>
  </employee>
   </mx:Model>
   
   <MyPhoneNumberValidator xmlns="*" 
      field="myModel.employee.phoneNumber" />
 
 <mx:Label text="Phone Number"/>
 <mx:TextInput id="phone" />
 <mx:Label text="Custom Error Message"/>
 <mx:TextInput id="newError"/>
 
 <mx:Button click="invalidCharError = newError.text" 
 label="Change Error Message" />
</mx:Application>

Subclassed Validator (MyPhoneNumberValidator.as):

//
// Simple age validator.  
//   Verifies: AS components
//
class MyPhoneNumberValidator extends mx.validators.PhoneNumberValidator
{
 // The default is "Invalid characters in your phone number."
 public function get invalidCharError():String
 {
  return mx.core.Application.application.invalidCharError;
 }
 
 // The default is "Your telephone number must be at least 10 digits in length."
 public function get wrongLengthError():String
 {
  return mx.core.Application.application.wrongLengthError;
 }
 
}

December 10, 2004

I have heard requests from developers using ColdFusion and Flex that they would like more information about integrating the two. One of my coworkers Tom Link started a blog and his first few entries cover ColdFusiona and Flex integration. His first three posts cover the following topics

December 9, 2004

Here is another recent question I recieved through email so I thought I would share the answer.

Question: Is it possible to build a flex app that will show changing data in a database without refreshing the browser? Kinda like a stock ticker. I need to build a demo app that will be a summary page of all our product facilities across the country. This page should show products available for sale and the numbers should change without the saleperson ever touching the computer. Is this possible with flex?

Answer: Yes, this is possible. There are two parts to this question, building a ticker in flex and the second keeping data up to date in flex.

  1. I was asked recently how you would go about building a stock ticker in Flex. Eric Anderson and Peter Ent two of my coworkers ventured off and built a simple example that can be found on Eric's blog. This example illustrates how to take a component and scroll it across the screen. I would like to extend this idea in the future and allow the ability to dynamically add complex data to the ticker. Developers that are familiar with Flex should be able to extend upon Eric's example
  2. The second part of this question is keeping the data up to date in the client without some type of user intervention. There are two options that can be used to keep the data in synch. You could use setInterval() to call a data service on a periodic basis or you could use a "server push" communcation model.
    1. Using setInterval(): I have a posting on using setInterval() to call a function on a periodic basis. Using this code you could add the call to a dataservice within the function that is being called to keep a client side model up to date and bind the model to the ticker. setInterval() would work well in the use case from the question above, since the data is not real time you could check the server for changes on a periodic basis and if there were changes have it go ahead and synch up the client model.
    2. Using "server push": Christophe Coenraets has a good example of using XMLSocket to send and receive XML messages to and from the server. You could also use Flash Communication server to accomplish the same thing but it is not currently well documented. Look for examples in the future on this topic. Server push is more appropriate where you need real time information and it is time critical, a good example is stock quotes. Also remember, when you use "server push" a socket is left open from the server to the client at all times.

If time allows in the future I will build out a working example.

I was recently asked the following question around precompiling. It is a little known fact that if you precompile a Flex application flex does not load the SWF from disk. In order to take full advantage of the cached SWF you need to create your own JSP/CFML/HTML wrapper for the SWF. I address that issue in my Flex Server performance paper. If you are using MXML/AS components in your application then you will need to compile them as well. The following quesiton addresses the question with precompiling components.

Question: I have used the mxmlc compiler to pre-compile our flex applications into .swf files. I have changed the jsp pages that used to use the flex jsp tags to include the mxml application to now include the .swf file directly.

During pre-compile all of the mxml components and action script classes get compiled into .swo files and placed in the flex/generated// directories. When this is packaged and deployed the jsp page will get the .swf flex application but all of the components and classes that are used will get recompiled and placed in new directories in the flex/generated/ directory. The previously compiled versions are not being used. There seems to be little benefit in first use startup time since the supporting classes and mxml components need to be compiled again.

The question is how do we pre-compile our applications and distribute the application, components and action script classes so that we avoid the compile time hit the first time we access our application.

Answer: You should use both mxmlc and compc to compile your files. Prior to compiling your MXML app and files you should compile your components into a SWC using compc. In most cases you will need to use a manifest file, this is addressed in the docs. Then copy the SWC to your classpath (flex_app_root/WEB-INF/flex/user_classes), you could then remove the MXML files (components only) after doing this. http://livedocs.macromedia.com/flex/15/flex_docs_en/wwhelp/wwhimpl/common/html/wwhelp.htm?context=Flex_Documentation&file=00001182.htm

Next, recompile you MXML files so that they use the SWC file instead of the .mxml components This should cause flex to use the SWC files for the components and not recreate SWOs for the components.

October 14, 2004

Google launched the Beta of its long anticipated Desktop Search tool for Windows today. The application acts as your own personal Google Server and indexes the contents your system by file name, or in the case of select file formats, by the contents of the file. It runs on Windows XP and Windows 2000 (with Service Pack 3).

The free download indexes the full text of email created in Outlook or Outlook Express, Word documents, Excel spreadsheets, PowerPoint presentations, AOL Instant Messages, and caches the pages you view in Internet Explorer so you can revisit the page later "even if its live content has changed or you're offline."

The install is really simple and after you install it starts indexing. If you are working on your system then it will take a while to index. As soon as it realizes the machine is idle it starts churning away. After it indexes the data you are presented with a browser based interface much like the google we all know. Yes is it lightening fast, typing in JRun on my machine turned up 24,107 entries for files and 27,823 for web history, all that in .5 seconds. It looks through basically anything on your machine and indexes it. For free you can't beat this. it is on my short list of the best windows utilities I have ever used.

You can download it here.

October 11, 2004

Flex is a great application to build a Kiosk application but when viewing the application through a web browser you can still see the navigation buttons and menus in the browser. Internet Explorer offers the capability to open in Kiosk mode. Kiosk mode forces the webpage or application to occupy the entire viewable area of the screen. 

To open IE in Kiosk mode you use the following command:

iexplore -k http://127.0.0.1/flex/myApp.mxml

You can then use Alt-F4 to close the window.

Thanks to Mike Collins for offering this tip.

If you want to execute code in Flex on a interval you can use the setInterval() function in Flex. For example if you wanted to call a data service every five minute to update the data displayed on the screen you can use setInterval(). An example of using setInterval is shown below. This example was taken from Peter Ent on the Flex forums.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml" xmlns="*" 
             creationComplete="startApp()">
   <mx:Script>
      <![CDATA[               
   function startApp() 
   {                    
   setInterval(this,"do_output",5000);               
   }               
   function do_output() {                   
     var mydate:Date = new Date();                    
     output.text += mydate+" -- testing"+newline;               
    }          
    ]]>
   </mx:Script>
   <mx:Panel title="Interval Test" width="400" height="400">
      <mx:Text width="300" height="400" id="output" />
   </mx:Panel>
</mx:Application>

August 31, 2004

I have ran into this a few times and it can be confusing and frustrating if you do not know why this is happening. If you have a combobox bound to a dataProvider and programatically set the selected index using comboBoxName.selectedIndex=x bindings will not fire. In order to get bindings to update you need to fire a change event. Bindings only occur when user interaction occurs. The following code will cause bindings to occur

//changing the selectedIndex then fire a change event
comboBoxName.selectedIndex=2;
comboBoxName.dispatchEvent({ type: "change" });

I ran into something that at first confused me but once I figured out what I was missing it made sense. If you try to invoke a URL with URL parameters you will get an error. For example when trying to load them XML from my blog RSS feed with the following code:

<mx:HTTPService url="http://www.bpurcell.org/blog/rss.cfm?mode=short&mode2=cat&catid=14"
id=
"myHTTPData" method="GET" resultFormat="xml">

The above code will cause the following error in Flex, "HTTPService Fault: Parameters are not allowed in the url, use the request object".

The correct approach is to use the mx:request object within the HTTPService call. The following code illustrates an approach that works correctly

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml" 
            initialize="myHTTPData.send();trace('calling service');">
<mx:Script>
<![CDATA[
  var myURL:String="http://www.bpurcell.org/blog/rss.cfm";
 var mode:String="short";
 var mode2:String="cat";
 var catid="14";
]]>
</mx:Script>
<!-- If you set resultFormat to Object it turns the returning data into an object -->
<mx:HTTPService url="{myURL}" id="myHTTPData" method="GET" resultFormat="object">
  <mx:request>
  <mode>{mode}</mode>
  <mode2>{mode2}</mode2>
  <catid>{catid}</catid>
 </mx:request> 
</mx:HTTPService>
<mx:TextArea text="{myHTTPData.result.RDF.channel.title}" width="250" />
<mx:TextArea text="{myHTTPData.result.RDF.item[0].description}" 
width="250" height="200" />
<mx:TextArea text="{myHTTPData.result}" width="250" height="500" /> </mx:Application>

July 13, 2004

In some cases you will need to send XML to your web service or HTTP Service. It is not as simple as just putting the model or the object within the call to the server. You will need some amount of actionscript to convert the object back into XML. In this example I am using a helper class that converts the actionscript object to XML before passing it. Michael Prichard was kind enough to offer his code to accomplish this task. Below I use the XMLTools.as file to convert the mx:Model into a XML doc before sending it to the server. This example just echos back the result and displays it. The same idea could apply to a mx:WebService call.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml" 
backgroundColor="#FFFFFF">
<mx:Script> <![CDATA[ var myXMLString:String; function checkClass(myObject:Object) { var myChange:XMLTools = new XMLTools(); myXMLString=myChange.toXML(myObject); trace(myXMLString) myTestJSP.send() } ]]> </mx:Script> <mx:HTTPService url="echo.jsp" id="myTestJSP" showBusyCursor="true" method="POST"
result="myTextArea.text=event.result;trace(event.result);" resultFormat="text">
<mx:request><xmlString>{myXMLString}</xmlString></mx:request> </mx:HTTPService> <mx:Model id="thePersonModel"> <name>Brandon</name> <age>30</age> <address> <street>foobar</street> <number>19</number> </address> </mx:Model> <mx:Button click="checkClass(thePersonModel);"
label="Convert Model to XML and Send to JSP"/>
<mx:Label text="The JSP will echo back the XML that was sent"/> <mx:TextArea width="300" height="200" id="myTextArea"/> </mx:Application>

Feel free to modify the XMLTools.as file to work within your environment and share any code changes with Michael, his email is within the actionscript file. You can download the code sample here.

July 12, 2004

In Flex the calls with mx:WebService and mx:HttpService are made through the Flex proxy. If your server is behind a Proxy server and does not have direct acess to the internet you will run into problems accessing external web services or HTTP Url's. Flex 1.0 Updater 1 introduced the ability to send requests from the Flex proxy through an external proxy server out to the internet. The process is documented in the Flex 1.0 Updater 1.0 release notes under bug #87581. The new feature supports basic authentication and NT authentication on proxy servers.  I am not behind a proxy server so in order to test this I used one of the proxy servers from the public proxy servers website. I tested this with the blogreader from the samples application.  In order to get it working I had to modify one line in the blogreader and add a public proxy server to the flex-config.xml.

In flex-config.xml I added the following: (If your proxy server requires authentication you will need to add that information see the release notes for details)
<http-service-proxy>
....
<external-proxy>
<location>66.114.194.100:80</location>
</external-proxy>
....
</http-service-proxy>

I modified line 52 in blogreader.mxml, since we don't want the call to the topics.xml file to go through the remote proxy server since it is located in the same directory as the mxml file.
<mx:HTTPService id="topicRequest" url="topics.xml" resultFormat="xml"
result=
"selectFirstBlog()" useProxy="false"/>

I left the rest of the code in blogreader.mxml the same. Whenever you click on a blog topic the flash player sends the request to the Flex proxy, the Flex proxy then sends the call to the remote proxy server and then the remote proxy server sends the request to the URL that is requested. This is not an approach that you would normally use unless you are forced to put the Flex server behind a firewall/proxy server to access the internet.

You could possibly bypass all of the proxies by setting useProxy="false" in line 56 of the blogreader.mxml but in that case all of the remote URL's would need a crossdomain.xml file to get around the flash security sandbox feature.

June 30, 2004
A common question that developers ask is "How do I upload files from a Flex Application". The Flash Player does not support this feature due to the security restrictions.A technote on the macromedia.com website provides a slick solution that can be used through JSP or ColdFusion to upload files

June 15, 2004

I often get the question, "How do I store persistant data on the clients machine with Flex?"  You cannot arbitrarily write to the clients disk like you can with a desktop application due to the sandbox that the Flash Player operates in.  What you can do is leverage a feature of Flash called Shared Objects to write data to the clients machine much like you can write cookies to a users computer. You can store simple data types in a SharedObject. These types are Number, String, Boolean, XML, Date, Array, and Object. You cannot store built-in ActionScript types such as Function or MovieClip in a SharedObject though. Flash will serialize them to disk automatically using the shared Object API. There is a default maximum amount of 100KB per domain for the Flash Player but this value can be increased. If you go over the limit of 100KB the user will be prompted to allow more data to be stored locally. 

The SharedObject class functions like a browser cookie. You use the class to store data on the user's local hard drive and call that data during the same session or in a later session. Applications can only access their own SharedObject data, and only if they are running on the same domain. The data is not sent to the server and is not accessible by other Flex applications running on other domains.

The Flex documentation provides two different examples that can get you started using Shared Objects.

June 12, 2004

ColdFusion, JRun and Flex TechNotes are now available as RSS feeds at the following URLs:

June 3, 2004
Dirk Eisman has posted a cool Flex utility that serves as a good client side debugging tool. Check it out on his website.

June 1, 2004

There are three factors that affect overall startup time: compilation time, download time, and application initialization time. Since compilation time only affects the first request and downloaded content is cached after the first request the application initialization time affects the users experience most of all. There are a few simple steps you can take to analyze the initialization time and target the areas that are affecting performance most.

With a few lines of code you can see the amount of time it takes to initialize your application.

  1. First you will need to add a Label component in some unobtrusive area of your application. In this example we will call it "initLbl"
    <mx:Label id="timerLbl"/>
  2. Add the following attribute to your Application tag: creationComplete="doLater(this, 'updateLabel')"
    <mx:Application ... creationComplete="doLater(this, 'updateLabel')">
  3. Add the following function to your Application script:
    function updateLabel
    <mx:Script>
    <![CDATA[
    {
    timerLbl.text = getTimer();
    } ]]>
    </mx:Script>

  4. Run your Flex application. The label should display the number of milliseconds that elapse during application startup. Run twice more to get an average.
  5. Now you can start to gradually remove pieces of your application, until you've whittled it down to nothing. Each time that you remove a piece, run the app (three times) and record the startup time. Due to dependencies in your code you may not be able to remove the pieces entirely. You can wrap your code snippets with the following code to prevent it from initializing when the application starts.
    <mx:Canvas creationPolicy="none">...tag(s) to be removed...</mx:Canvas>

After identifying code that is causing the problem you can use the recommendations in the performance developer center article to reduce the intitialization time of your application. You can also use the Flex Profiler to do more in depth analysis but the above approach provides developers a simple way to profile their application. Thanks to David George from Flex Engineering for providing the steps.

May 26, 2004

I have recieved several questions asking how do I bind XML data to a datagrid? The following code binds a simple XML string that is retrieved through the HTTPService using ColdFusion. ColdFusion could be replaced in this case with a JSP or Servlet. Be aware, there is a known issue with the Flex webservice proxy when you try to invoke XML through a webservice. The XML will be encoded incorrectly and will not decode in the Flex application. The workaround is to use HTTPService and create a .cfm or .jsp page that serves as a gateway.

-----xmlService.cfm-----
<CFSILENT>
<CFSAVECONTENT VARIABLE="employees">
 <employees>
  <employee>
   <id>100</id>
   <name>Brandon Purcell</name>
   <title>Principal Engineer</title>
   <phone>617-555-6971</phone>
  </employee>
  <employee>
   <id>101</id>
   <name>Bill Phillips</name>
   <title>VP Engineering</title>
   <phone>617-555-5555</phone>
  </employee>
 </employees>
</CFSAVECONTENT>
</CFSILENT>
<cfheader  name="content-type" value="text/xml">
<cfsetting enablecfoutputonly="yes" showdebugoutput="no"> 
<CFOUTPUT>#employees#</CFOUTPUT> 
-----end xmlService.cfm-----
------datagridXML.mxml------
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml" 
  backgroundColor="#FFFFFF" 
  verticalGap="0" 
  initialize="myHTTPDetail.send()">
  
<mx:HTTPService id="myHTTPDetail" showBusyCursor="true" method="GET" 
 url="xmlService.cfm">
</mx:HTTPService>
<mx:DataGrid 
 id="orderGrid" 
 dataProvider="{mx.utils.ArrayUtil.toArray(myHTTPDetail.result.employees.employee)}"
 width="375">
 <mx:columns>
 <mx:Array> 
  <mx:DataGridColumn columnName="id" headerText="Id" width="40"/>
  <mx:DataGridColumn columnName="name" headerText="Name" width="115"/>
  <mx:DataGridColumn columnName="title" headerText="Description" width="130"/>
  <mx:DataGridColumn columnName="phone" headerText="Price"/>
 </mx:Array>
 </mx:columns> 
</mx:DataGrid>
</mx:Application>
------end datagridXML.mxml------

May 17, 2004

Two new articles on the Macromedia Flex Developer Center were released today that are must reads for Flex developers. The articles are split between the server and the client and cover a broad range of topics that will keep you busy for a while. The two articles are also merged together as a whitepaper for easier printing. If you have any comments about the paper click on the feedback forms.  All comments will be passed to Deepa and I so we can continue to update the contents of the paper for future reference.

You can view the two papers here:
http://www.macromedia.com/devnet/flex/articles/client_perf.html
http://www.macromedia.com/devnet/flex/articles/server_perf.html

The first updater for Flex 1.0 is now available. Flex 1.0 Updater 1 includes performance and reliability improvements, enhanced API reference documentation, and more. You can download the Flex updater here.

Release Notes, Installation Instructions, Enhanced API Docs

May 11, 2004
Macromedia is celebrating our customer community by hosting Community Week, May 17-21, an opportunity to learn, network and interact with Macromedia product managers and our customer community. There will be free online presentations and a worldwide meeting on Wednesday. Go to www.macromedia.com/community for more information. Macromedia Community Week

April 28, 2004

The datagrid in Flex works very well with flat XML. For example if you have the following XML it is very simple to bind it to a DataGrid.

<mx:Model id="thePersonModel">
 <name>Brandon</name>
 <age>30</age>
 <address>19 foobar</address>
</mx:Model>
<mx:DataGrid id="myDataGrid" dataProvider="{mx.utils.ArrayUtil.toArray(thePersonModel)}"/>

But what if you have a more complex XML packet that you need to bind to a DataGrid?

<mx:Model id="thePersonModel">
 <name>Brandon</name>
 <age>30</age>
 <address>
  <street>foobar</street>
  <number>19</number>
 </address>
</mx:Model>

<mx:DataGrid id="myDataGrid" dataProvider="{mx.utils.ArrayUtil.toArray(thePersonModel)}"/>

In the above code the name and age will bind appropriately but the addess column will show [object Object] instead of the value of street and number. There is an easy workaround to display the values of complex XML using the labelFunction from the <mx:DataGridColumn> tag. When we call the labelFunction tag the dataprovider gets passed to the function and we can grab any value from the dataprovider. The following code shows how this works

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml" 
width="600" height="450">
<mx:Script> <![CDATA[ function myLabelFunc(item):String { if (item.address.number==undefined) {return null;} else {return item.address.number + " " + item.address.street;} } ]]> </mx:Script> <mx:Model id="thePersonModel"> <name>Brandon</name> <age>30</age> <address> <street>foobar</street> <number>19</number> </address> </mx:Model>
<mx:DataGrid id="myDataGrid2"
dataProvider="{mx.utils.ArrayUtil.toArray(thePersonModel)}">
<mx:columns> <mx:Array> <mx:DataGridColumn columnName="name" headerText="Name"/> <mx:DataGridColumn columnName="age" headerText="Age"/> <mx:DataGridColumn headerText="Address" labelFunction="myLabelFunc"/> </mx:Array> </mx:columns> </mx:DataGrid> </mx:Application>

While this is a very simple example where we have XML data hard coded to a Model there may be times where you get data from web services that you have no control over the format of the data. labelFunction can provide an easy workaround to get the appropriate data into your DataGrid.

The labelFunction is also avilable on <mx:List> an example of using it can be found in the livedocs.

April 23, 2004

If you have used the ColdFusion Flash Remoting Gateway with Flex you may have noticed that the data returned is in a different structure then when you use webservices. For example, if you return a data from a CFC in ColdFusion you have two ways to get this data back to Flex. I will explain these two approaches below and the gotchas I ran into. This can save you a lot of frustration. For the example I am refering to a CFC that returns a query.

  1. Invoke the CFC as a webservice with <mx:WebService url="http://server/directory/file.cfc?wsdl" ......>. With this approach an array of objects is returned and you can bind the result to any of the visual components in Flex easily. To access data directly with this approach you use

    result[0].COLUMNAME

    In this case 0 is the array index and COLUMNAME is the column from the query. Notice that all variables returned from a CF webservice are uppercased automatically.
  2. You can also invoke the webservice using the Flash Remoting gateway in ColdFusion using the <mx:RemoteObject> tag. I ran into some gotchas with this approach and they can cause you a lot of headaches if you don't understand how it works. I won't hightlight the syntax here because I posted an entry on that a few weeks back here. Instead I want to highlight the differences that cause me problems

    The first issue I ran into was trying to access data in the result that is passed back through AMF. While it is an array of objects the array is not stored in the top level object. Instead it is buried in an object called _items. To access the data that is returned you need to use the following syntax.

    result._items[0].COLUMNAME

    Although we are using the same CFC the data is returned in a slightly different format. This can be problematic if you try to access the data directly. One trick I found is to use XMLObjectOutput to dump the contents of the result to better understand the structure. Don't be confused by the XMLObjectOutput name though. It dumps any object in Actionscript.

    The second issue I ran into deals with binding the result data to a datagrid and this is the one that caused me a lot of frustration. If you take the result directly from the <mx:RemoteObject> response you can bind it directly to the datagrid and the data appears properly. When I went to sort the numeric data it sorted it as a string. Although that same data sorted fine when I used a webservice to bring the data into the grid. I used typeof() to check the data types of the data and they turned out to be number objects so that was correct. After thinking about this a bit I remembered that the structure in the webservice is a bit different than the AMF data. I thought it may be possible that the result._items[0] structure of the data was throwing it off. I ended up using the following code to create a client side array then bound the array to the grid.

    <mx:Script>
    <![CDATA[
    public var calorieArray:Array;

    function processResult(result):Void
    {
    calorieArray=result._items;
    }
    ]]>
    </mx:Script>

    <mx:RemoteObject id="calorieCFC" encoding="AMF" protocol="http"
    endpoint="@ContextRoot()/flashservices/gateway" source="calorieapp.calorie">

    <mx:method name="searchCalorieData" result="processResult(event.result)" fault="processFault(event.fault)"/>
    </mx:RemoteObject>

    <mx:DataGrid id="userGrid" width="625" dataProvider="{calorieArray}"/>


    By creating an Array that is set to result._items the numeric data sorts correctly. If you bind the result from <mx:RemoteObject> as shown in the code below then the numeric data does not sort correctly!! I couldn't figure this out for the life of me for several hours. It will bind and display correctly but when you sort it sorts everything as a string. You would think that it wouldn't bind at all? It turned out to be the structure of the data, with AMF there is additional metadata that is passed and the actual array of objects is buried in _items. By bringing this array to the top level of the object and binding it to the datagrid it sorts correctly.

    <mx:DataGrid id="userGrid2" width="625" dataProvider="{calorieCFC.searchCalorieData.result}"/>

April 14, 2004

Actionscript has a useful function called getTimer() that can be used to retrieve the number of milliseconds that the Flash movie has been playing. You can use this function to time calls that are made to dataservices as well. In the example below I am calling a webservice from XMethods that is returning the temp based on a given zipcode. When the Get Weather button is clicked the getWeather() function is called and a variable called startTime is used to store the time when the webservice was invoked. When the result is returned the weatherHandler() function is called, when this function is call the label theTimer has its value set with the value getTimer()-startTime and the result is show in the weatherResult label.

WebService Timing Example

If you would like to try this just copy the code below into an MXML doc and invoke it through Flex.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml" backgroundColor="#FFFFFF">
<mx:Script>
  <![CDATA[
  public var startTime:Number;
 
  function getWeather():Void
  {
   startTime=getTimer();
   weatherService.getTemp.send();
  }
  function weatherHandler(theResult):Void
  {
   theTimer.text=getTimer()-startTime;
   weatherResult.text=theResult;
  }
  ]]>
</mx:Script>
<mx:WebService id="weatherService"
   wsdl="http://www.xmethods.net/sd/2001/TemperatureService.wsdl"
    showBusyCursor="true">

  <mx:operation name="getTemp" result="weatherHandler(event.result)">
   <mx:request>
   <zipcode>{zip.text}</zipcode>
   </mx:request>
  </mx:operation>
</mx:WebService>

<mx:Panel title="Webservice Timing Example">
<mx:HBox>
<mx:Label text="ZipCode"/>
   <mx:TextInput id="zip"/>
   <mx:Button click="getWeather()" label="Get Weather"/>
  </mx:HBox>
<mx:HBox>
   <mx:Label text="Weather Result: "/>
   <mx:Label id="weatherResult"/>
  </mx:HBox>
  <mx:HBox>
   <mx:Label text="mx:WebService request time in milliseconds: "/>
   <mx:Label id="theTimer"/>
  </mx:HBox>
</mx:Panel>
</mx:Application>

April 13, 2004

In the {flex-install}/extras/netConnectionDebugger you will find the netConnectionDebugger.html and netConnectionDebugger.swf that can help you sniff out and debug AMF issues with Flex. When <mx:RemoteObject> is used in Flex the default protocol is AMF, Flex ships with its own AMF gateway but you also have the option of connecting to other Flash remoting gateways. Lke the one that ships with CF. See this blog entry for details http://www.bpurcell.org/blog/index.cfm?mode=entry&entry=1013. I have seen several issues on the forums and in mailing lists where developers tried this approach and were unable to make it work. With adequate debugging information it is hard to tell what is going on behind the scenes. It is pretty simple to get the netConnectionDebugger working and I will outline the steps below.

  1. In the /flex/WEB-INF/flex/flex-config.xml locate the <debug>...</debug> section and find the entry
    <remote-objects-debug>true</remote-objects-debug> and set the value to true
  2. Restart your server so the changes take affect
  3. Open a browser with the URL to the netConnectionDebugger.html file (in my case I open the URL below)
    C:\Program Files\Macromedia\Flex\extras\netConnectionDebugger\NetConnectionDebugger.html
  4. Now we are ready to start debugging. Open the URL of the mxml document that uses AMF and you will start seeing the request/response get logged from the client and server. In my example below I am using the Firefox browser although you can use IE. I have two tabs open one with the MXML doc I am debugging and the second with the NetConnectionDebugger.

AMF NetConnectionDebugger

note: You DO NOT need the flash debug player for this to work since the netConnectionDebugger works similar to a sniffer 

Troubleshooting: If the output doesn't appear, first verify that you modified the flex-config.xml as shown in step 1 above. Then try refreshing the MXML doc a few times to make sure it gets recompiled. You may need to just modify the file and save it again to force the compile.

April 7, 2004
Macromedia Max 2004 was announced today and it is being held November 1-4 in New Orleans, Louisiana.  You can find more information on http://www.macromedia.com/macromedia/events/max/

April 2, 2004

I was writing an application in Flex using ColdFusion as the backend. I first started using Webservices for my implementation and was wondering if I could easily switch it to Flash Remoting without modifying any of my other code. After all with CF, a CFC can be exposed either by web services or by Flash Remoting without any changes on the CF end.

My initial code looked like the following in Flex that called the CFC as a webservice

<mx:WebService id="usersCFC" 
wsdl="http://127.0.0.1/myappdir/components/mycfc.cfc?wsdl"
showBusyCursor="true">
 <mx:operation name="getAllUsers"
result="userModel.userResultHandler(event.result)"
fault="userModel.userFaultHandler(event.fault)"/>
</mx:WebService>

Notice I am just pointing the wsdl in the WebService tag directly at CF. Now if I want to use the ColdFusion Flash Remoting gateway instead, I don't have to change any of my other code in my MXML document. I just need to change the data tag. I just comment out the mx:WebService tag and replaced it with the following

<mx:RemoteObject id="usersCFC" 
endpoint="http://127.0.0.1/flashservices/gateway"
source="myappdir.components.mycfc"
   showBusyCursor="true">
 <mx:method name="getAllUsers"
result="userModel.userResultHandler(event.result)
fault="userModel.userFaultHandler(event.fault)"/>
</mx:RemoteObject>

Notice that I am not using the AMF implementation that ships with Flex. Instead I am using the CF flash gateway by modifying the endpoint attribute in the mx:RemoteObject tag.

The only issue that I ran into when doing this was with CF's handling of webservices. All variables returned from a CF webservice are uppercase even if they are not in the cfc file. With Flash remoting they are returned exactly as they are written. MXML is case sensitive so you may run into an issue here. Otherwise I found that this worked very well.  Pretty cool!!!

**Late addition to this entry: I recieved an email noting that if you use Remoting with the endpoint attribute you will not use the proxy that is built into Flex. If the Flash Remoting server is on a different domain from the originating domain the Flex SWF was loaded from then a crossdomain.xml file needs to be used. You can find details on the crossdomain.xml file in the Flash livedocs. Basically you will run into a problem if Flex is on one machine and ColdFusion is on another. It is also worth taking a look at this Flash Devnet article for a second explanation of crossdomain.xml.

March 29, 2004

XMLObjectOutput is a really cool tool for debugging when you are writing Flex Apps. It is somewhat similar to CFDump and displays the structure of any Object in Flex.

The XMLObjectOutput class is used to convert XML Objects to simple Object types. This is useful for easy access to values and attributes of the XML Object by using property names versus using firstChild, nextNode, etc. to access the data. This Class also traces Arrays and Objects in a clear representation of the structure. XMLObjectOutput can be found in the install for Flex in the \Flex\extras\XMLObjectOutput\ directory. You will find two files (XMLObjectOutput.as and XMLObjectOutput.html). XMLObjectOutput.html provides documentation on the usage and methods of the XMLObjectOutput actionscipt class. In order to use this class for debugging you need to have the Flash Debug Player installed. Instructions for installing the debug player can be found here. The XMLObjectOuput.as file needs to be placed in the same directory as your *.mxml and *.as files or in the {web-app}\flex\WEB-INF\flex\user_classes\ directory.

XMLObjectOutput can be used for development similar to CFDump. The class can be used either in an mxml document or an .as file. The output gets written to the {windows user home directory}\flashlog.txt. In my example using Windows XP it gets written to C:\Documents and Settings\bpurcell\flashlog.txt. Each time the Flash player is loaded the flashlog.txt file is cleared and output gets appended while it is running.

For this example I will use the XMLObjectOutput to debug the Flex BlogReader in the samples application that ships with Flex. Open the /blogreader/blogreader.mxml file and locate the following section of code

function feedResponse(response) {
            if (response.rss==null)
                feed=new RDFFeed(response);
            else
                feed=new RSSFeed(response);
        }

First copy the XMLObjectOuput.as class to \samples\WEB-INF\flex\user_classes\. Next, add the following code right above the if statement

   //debugging
   var myDebugger:XMLObjectOutput = new XMLObjectOutput() ;
   myDebugger.traceObject(response, 'Dump of Feed Data');

Open the blogreader.mxml in a browser running the debug player. You will see something like the following in flashlog.txt. You can use a tool like wintail to follow the flashlog.txt file.

Dump of Feed Data  [object Object]
 |-- RDF [object]
       |-- xmlns [object]
       |-- xmlns:admin [object]
       |-- xmlns:sy [object]
       |-- xmlns:dc [object]
       |-- xmlns:rdf [object]
       |-- item [array]
             |-- [0] [object]
                   |-- rdf:about [object]
                   |-- date [object]
                   |-- creator [object]
                   |-- subject: null
                   |-- description [object]
                   |-- link [object]
                   |-- title [object]
                   ..............

Notice that this outputs the structure of the object returned in the response. Using this tool we can easily identify the notation needed to reference something within the object. Also the XMLObjectOutput does not recursively call itself to dump the object tree you will need to use dot notation to dump objects further down the tree.

For example we can see from the dump that we could use response.RDF.item[0] to dump the first item in the array. Now modify the code to look like the code below.

   //debugging
   var myDebugger:XMLObjectOutput = new XMLObjectOutput() ;
   myDebugger.traceObject(response.RDF.item[0], 'Dump of Feed Data');

Refresh the browser, and review the flashlog.txt. Notice that only the first item in the array was dumped.

Dump of Feed Data  [object Object]
 |-- rdf:about [object]
 |-- date [object]
 |-- creator [object]
 |-- subject: null
 |-- description [object]
 |-- link [object]
 |-- title [object]

To output the title of the first object in the array use the following notation "response.RDF.item[0].title".

See how easy it is to use XMLObjectOutput to display the structure of objects and debug your applications?

As you may already know Flex 1.0 is now available. There are tons of resources available on Flex and I will help you find them.  I have spent most of the last few months working a lot with Flex and have really grown to love it.  The excitement I felt when I started working with CF back in 1997 I am feeling all over again with Flex. The Applications you can build are truly amazing and the great thing is I don't have to be an accomplished designer to build it.

You will first want to start with http://www.macromedia.com/software/flex/ to understand what Flex is and if it fits your needs.

Next, you will want to read the articles from the Flex Developers Center. You will find everything from Building your first Flex application to Architecting Flex Applications. To keep up with all of the latest information I suggest you check out the following blogs:

Christophe Coenraetes
Matt Chotin
Ben Forta

You can find help at the Flex Support site as well. The Flex support team has been working hard as well publishing technotes to help solve common issues developers will run into.

You will be seeing a lot more Flex on my blog in the future. If you want to subscibe to my Flex RSS feed you can use the following URL's

Short Feed: http://www.bpurcell.org/blog/rss.cfm?mode=short&mode2=cat&catid=14
Full Feed: http://www.bpurcell.org/blog/rss.cfm?mode=full&mode2=cat&catid=14

 

 

Page Render Time:234