Featured Post

BNIRIA Adobe Group Launched!

BNIRIA Is On! Today I received notice of approval to start up the Bloomington/Normal Illinois Rich Internet Applications Adobe user group! If you are a Central Illinois Web designer or developer, then we are inviting you to join, discuss, and network with us. Are You a Recruiter or Business We also...

Read More

Follow @dougrdotnet on Twitter

Playing With Google Maps Flex API

Posted by dougr | Posted in ActionScript, Flex | Posted on 07-01-2010

Tags: , , ,

1

I’m working on some Google Maps Flex API exercises to familiarize myself with working with the API library.

The first things to do are to sign up for a Google Maps API Key, and download the Google Maps Flex Library SWC (use the one with “Flex” in the filename).  I am following the Google Maps API For Flash Docs really closely here as this is the first time I’ve worked with the API.  In the example, to follow, my objective is to create a map where I can add an address, have it geocoded with the Google geocode service, and then display that address as a point on the map with a marker.  I want to have zoom, drag, and also to be able to click on the marker to get the point information in a marker information window.

After following through the docs, I found that it is really easy to get a basic map to render with very little code.  To do this, you can simply declare a new map object inside your main application file using the following mxml:

<maps:Map id="map" mapevent_mapready="onMapReady(event)"
 width="100%"
 height="100%"
 key="[enter API key here]"
/>

Along with the onMapReady method which handles map properties:

//called by the mapevent_mapready event in maps, instantiated in <maps:Maps...
private function onMapReady(e:MapEvent):void{
 //enable mouse wheel zoom and add the standard google zoom contorl to map
 map.enableScrollWheelZoom();
 map.enableContinuousZoom();
 map.addControl(new ZoomControl());
}

That is enough to put a global map on your screen, now we need to give the map some information.  I want to be able to provide an address and have the Google service geocode it for me.  In order to do this, I am going to need the API ClientGeocoder class.  The following method creates a new ClientGeocoder, sets up geocode event listeners, and passes the address from a TextInput into a method from the ClientGeocoder class, called geocode(String), that accepts a String argument, which will be the address.

//this method takes care of the address geocoding, handling result events
private function geocode(event:Event):void {
 geocoder = new ClientGeocoder();
 //geocoder event listeners for success or failure
 geocoder.addEventListener( GeocodingEvent.GEOCODING_SUCCESS,geoSuccess);
 geocoder.addEventListener(GeocodingEvent.GEOCODING_FAILURE,geoFail);
 //geocode the address, passing in the address from textfield
 geocoder.geocode(addy.text);
}

If the geocoder returns success, the following listener method is called.  I assign the placemarks property value from the result to a variable and if it has length, I set the map center, the initial map zoom level, the map type, the marker point for the placemark, and add the marker to the map.  I also setup a listener for a click event on the marker that will call a method that creates an address information window.

//listener method if the result event returns success
private function geoSuccess(event:GeocodingEvent):void {
 //assign the placemarks value from the response
 placemarks = event.response.placemarks;
 //check and see if response returned any placemarks
 if (placemarks.length > 0) {
  //set the center of the map to the placemark point, set initial map zoom and type
  map.setCenter(placemarks[0].point,15,MapType.NORMAL_MAP_TYPE);
  //create a new marker for the placemark
  marker = new Marker(placemarks[0].point);
  //listen for a click event on the marker
  marker.addEventListener(MapMouseEvent.CLICK, addMarker);
  //add the marker on map
  map.addOverlay(marker);
 }
}

Here is the addMarker method called from the geoSuccess method.

//listener method for marker click event
private function addMarker(event:MapMouseEvent):void {
//open the placemark information window
marker.openInfoWindow(new InfoWindowOptions({content: placemarks[0].address}));
}

If the result event returns failure, then I simply launch an Alert, notifying the user that geocoding failed.

Here is the resulting application thus far:

Get Adobe Flash player





I’m going to be continuing to play with the API.  As I learn more and add to this app, I plan on successive follow-up posts which discuss additional functionality.

HTH!

#100blogs challenge Day5 http://bit.ly/4MtAfx

Dynamically Resizing Shapes With ActionScript

Posted by dougr | Posted in ActionScript, Flex | Posted on 04-01-2010

Tags: , , , , ,

2

There are allot of applications where dynamic resizing of shapes is necessary, and useful. Dynamic data is one of the corner stones of Rich Internet Application (RIA) development. When combined with User Experience (UX) design elements, we can deliver meaningful information back to our users, creating a rich user experience, a greater degree of interest, along with interactivity. Involving our users in our applications and providing information dynamically elevates our applications dramatically from that of static content.
Dynamic resizing of shapes is just one way that we can utilize data and provide visual cues and feedback to our users, delivering meaningful information from data. In my following example, I am going to illustrate one way that dynamic resizing of shapes may be used. There are a myriad of different ways to use this technique, applied to various display objects, limited only by imagination.

Creating a UI Level Indicator

In this example, I am going to write a level indicator meter which responds dynamically to amplitude data from an audio file.  The applied use for this example would be, for instance, left and right meters for audio level indication.

Classes and Methods Used In This Example

The ActionScript Sprite Class

Sprite is a basic display object class which can display graphics.  Sprite can be a parent, meaning that Sprite can contain children.

with()

The ActionScript with method calls an object once and then allows successive properties to be accessed and modified within the with() statement.  This is a really nice convenience method, saving the need for calling the class over and over for each property.

The ActionScript Graphics Class

Graphics is a display class that provides us a means to create shapes, helper methods include: drawRect(), drawRoundRect(), drawCircle(), and drawEllipse(), I’ll be using the drawRect() method.  There are several public methods available in this class, of which I am going to use 4 in this example.

  • lineStyle(thickness:Number= NaN, color:uint = 0, alpha:Number = 1.0, pixelHinting:Boolean = false, scaleMode:String = “normal”, caps:String = null, joints:String = null, miterLimit:Number = 3)
  • beginFill(color:uint, alpha:Number = 1.0)
  • drawRect(x:Number, y:Number, width:Number, height:Number)
  • endFill()

lineStyle() is just as it reads, this method provides access to properties of the shape’s line styling, such as thickness, color, etc… as shown in the method’s properties above.

beginFill() provides access to the shape’s fill properties, such as color and alpha.

drawRect() does just that, it draws a rectangle, the available properties allow for x and y assignments, along with width and height of the rectangle.  Just gotta love self-documenting code :-)

endFill() actually adds the fill properties to the shape, as defined in the beginFill() method.

The ActionScript SoundChannel Class

The SoundChannel class is the sound controller class.  In ActionScript, every sound is assigned to a channel, there can be multiple channels, just like having a left and right channel for stereo or having n-number of channels that may be mixed together.  In this example, I am going to be using 2 of the class’ public properties.

  • leftPeak
  • rightPeak

The leftPeak and rightPeak properties are read only and are used to assign the volume amplitude to the associated channels.

The ActionScript UIComponent Class

The UIComponent Class is the base class for all visual components in ActionScript.  I am going to create an instance of this class that will contain the level indicator display objects.  I will be adding this instance to the stage with all its children.

A Simple Dynamic Resizing Shape Example

In this example, the first thing I do is declare the private vars I’m going to need in the creation of left and right rectangle display objects which will, later, resize based upon dynamic data.  I also declare the SoundChannel class var and a UIComponent class var.  I then create an init method which sets up the left and right display objects and adds them to the base class levelUI UIComponent class instance.

In the onEnterFrame method, I update the left and right shape’s widths on each onEnterFrame event.  The data used to update these values is obtained from the left and right peak values accessed from the SoundChannel object.

private var channel:SoundChannel;
private var left:Sprite;
private var right:Sprite;
private var levelUI:UIComponent;

//setup left and right sprites and apply graphics style properties and positions
//on application initialization
private function init():void{
 //create the left sprite
 left = new Sprite();
 //define the left shape and properties
 with(left.graphics){
   lineStyle(0,0x00AF33,1);
   beginFill(0x00AF33,1);
   drawRect(0,0,1,5);
   endFill();
 }
 //position the left sprite
 left.y = 60;
 left.x = 20;

 //create the right sprite
 right = new Sprite();
 //define the right shape and properties
 with(right.graphics){
   lineStyle(0,0x00AF33,1);
   beginFill(0x00AF33,1);
   drawRect(0,0,1,5);
   endFill();
 }
 //position the right sprite
 right.y = 75;
 right.x = 20;

 //add left and right sprites as children to the levelUI display object
 levelUI.addChild(left);
 levelUI.addChild(right);
 //add levelUI to the display
 this.addChild(levelUI);
 }

//I want the shape's sizes to update at the beginning of entry into each frame
//A movie at 24 frames per second will call this method, using the onEnterFrame
//event, 24 times per second.
private function onEnterFrame(event:Event):void{
 //check and see if a sound channel object already exists
 if(channel != null){
   left.width = 50 * channel.leftPeak; //set the left shape's width
   right.width = 50 * channel.rightPeak; //set the right shape's width
 }
}

There is a bit more to do here in order to write a functional prototype that updates dynamically.  Namely, we need a sound object that holds the actual sound file.  This is beyond the scope of this article, however, additional information may be found in the livedocs.

HTH!

#100blogs challenge Day2 http://bit.ly/4MtAfx

Using NativeApplication To Get App Version

Posted by dougr | Posted in AIR, ActionScript, Cairngorm, Flex | Posted on 24-07-2009

Tags: , , , ,

0

This is a nice little gem I wanted to share. I needed to display the current version of my application in the startup screen, when the user launches the app. I’ve already been updating this as I push releases to my update server where my updater xml file is located. At first I was going to just do a request for that xml document but then thought I’ve already got the version locally in the app.xml file, why not get it from there and not have to have the request.

I’m using Cairngorm so I wrote a command class to do this for me.

package com.dougrdotnet.commands
{
	import com.adobe.cairngorm.commands.ICommand;
	import com.adobe.cairngorm.control.CairngormEvent;
	import com.dougrdotnet.model.StatusModelLocator;

	import flash.desktop.NativeApplication;

	public class GetAppXMLVersionCommand implements ICommand
	{
		private var statusModel:StatusModelLocator = StatusModelLocator.getInstance();
		public function execute(event:CairngormEvent):void
		{
		   var descriptor:XML = NativeApplication.nativeApplication.applicationDescriptor;
		   var ns:Namespace = descriptor.namespace();
		   var version:String = descriptor.ns::version;
		   statusModel.version = version;
		}

	}
}

What i’ve done is use the NativeApplication class’ applicationDescriptor property to get the XML from app.xml. I set a variable to hold the namespace value from the descriptor xml. Then I go in and get the version node using descriptor.ns::version. Then, in this case, I am assigning the version string to a Model variable so that I can use it wherever that model singleton exists. Certainly, this method could simply return version to supply the value to the caller.

Reader Question – Manipulating a String

Posted by dougr | Posted in ActionScript, Flex | Posted on 14-06-2009

Tags: , ,

0

A reader asked me a question about taking a date stored as a string and manipulating it so as to remove sub-strings. This is really simple in ActionScript, using the replace method. The replace() method is used to find a match in a particular string and then replace it with some other string inside the parameters of the method, such as string.replace(pattern, repl);

From Livedocs ( http://livedocs.adobe.com/flex/201/langref/String.html#replace() )

replace(pattern:*, repl:Object):String
Matches the specifed pattern against the string and returns a new string in which the first match of pattern is replaced with the content specified by repl.

The reader needed to take a date formatted as such – 15:07:47.001.850.000 and end up with a string formtted like the following – 50747001850.
As I said this is really simple using replace and just a little bit of RegEx:



private function init():void {

    var dateStr:String = "15:07:47.001.850.000";

    var d:String = stringReplace(dateStr);

    trace(d); // Output is 150747001850

}


    private function stringReplace(value:String):String {
    var v:String = value;
    v = v.replace(/:/g, "");
    v = v.replace(/\./g, "");
    var re:RegExp = new RegExp("000$");
    v = v.replace(re, "");

    return v;
}

In the init method, I’ve set the variable dateStr to the value of the string that needs to be manipulated. Next, I’ve set the variable d to the value of the result of the stringReplace() method which follows, passing in the original string. In the stringReplace() method, which accepts the string parameter named value, I assign value to the variable v. Next, using the replace() method, I search the string for any ‘:’ characters. The reason it will search the entire string is that I’ve used the global (g) flag in the expression. Then note that the second parameter of the replace method I’ve specified an empty string. This will replace any ‘:’ with “” (nothing). I’ve done the same in the second replace() method, only removing periods from the string and replacing with an empty string. The next line I create a new RegExp object so that I can use the following RegExp(“000$”) in order to remove the trailing 000. The $ in the expression applies the pattern match to the end of the string, so as to not remove any instances of 000 that might exist anywhere other than the end of string. This way if the original string is provided from a dynamic source there is no worry of removing zeros anywhere other than the end of string. I then run the replace() method a last time and apply the RegExp as the pattern and replace it with an empty string. When I return the modified string the result is the formatted string as needed for other parts of the application, shown in trace output.

Constant and Static Variables in AS 3.0

Posted by dougr | Posted in ActionScript, OOP | Posted on 03-04-2009

Tags: , ,

4

Today a question came up regarding the difference between constant fields and static fields and I thought it noteworthy to mention here as it is easy to casually use static when one’s intention is really to define a constant.  Prior to AS 3.0, const was not available.

In short, a field declared as static const is indeed read-only, however, if declared as static it may be writable from inside or outside of its containing class, depending upon its access modifier (see Basic Modifiers below), and there is not a requirement for an instance of that class to be created in order for it to be referenced. Fields declared as constants may not be modified, they are constant.

It is interesting to note that a static field declared in a class may have the same name as an instance variable – the rule is that while both vars of the same name may be used in the instance, the static variable must be preceded by the classname (i.e. MyClass.variableName), whereas the instance variable would simply be declared by name.

Basic Modifiers:
Internal: the default if no modifier is specified – allows internal and package level access
Private: provides the greatest degree of access restriction – allows only internal access
Public: provides the least degree of access restriction – its an all-access pass
Protected: provides package level access restriction – allows internal and subclass access

Prototyping Flex Using Business Delegate – Part III

Posted by dougr | Posted in ActionScript, Cairngorm, Flex | Posted on 28-02-2009

Tags: , , ,

1

The creation of an event which occurs in the View

In Part II I outlined how I wish to walk through the process of creating functional prototypes by incorporating the Business Delegate found within the Cairngorm Architecture. I am beginning from the View down since we are approaching development from a prototypical point of view. The object is to get a functional prototype developed as quickly as possible without the need for development of the data tier. As I’ve mentioned in Part II, we will be developing our data requirements and will know exactly what our back-end requirements will be when finished, but that is actually a bi-product of what we are doing. Additionally, we won’t be locked into any particular technology for the back end, we will have the added benefit of determining our data tier needs while developing our prototype.

In this section we will be concentrating on the view with a simple example using the Cairngorm Event model. Lets suppose that we have a view which contains a simple member intake form in a Panel container for which we wish to store data upon submit.


<mx:Script>
     <!--[CDATA[
          import mx.controls.Alert;
          import com.adobe.cairngorm.control.CairngormEvent;

          //Save the member's data
          private function saveMember():void{
               //check to see if form fields have data
               if(fname.text != "" || lname.text != ""){
                    //create a new Cairngorm Event
                    var event:CairngormEvent = new CairngormEvent("saveMember");
                    //create a generic object to hold form data to be passed on event
                    event.data = new Object();
                    event.data.fname = fname.text;
                    event.data.lname = lname.text;
                    event.dispatch();
                    //If the form was not filled in correctly, alert the user
               }else{
                    Alert.show("Please enter member first name and last name in form","Empty Form Fields";
               }
          }
     ]]-->
</mx:Script>

Its pretty straight forward, create a new event of type CairngormEvent and pass a string of “saveMember” as the event identifier. Additionally, I’ve created a generic object to hold the data from a form which contains a member’s first name and last name. I will be passing this data on to be stored in memory during testing and later will actually be passed onto a remote object to do something with it. Finally dispatching the event. I’ve got the event contained within a condition here to check to make sure that the form fields have been completed by the user, if not an alert pops up letting the user know. saveMember(), in this case, would perhaps be called on the click event of a button.
In the next installment I will discuss the Cairngorm Control class and how it ties together the event with the appropriate command to associate with the event.

<< Previous Next >>

My Wednesday 360Flex Schedule

Posted by dougr | Posted in 360Flex, AIR, ActionScript, Conference, Flex | Posted on 20-08-2008

2

I sat in on the 360Flex Keynote this morning.  I was absolutely moved by the code jam volunteer coders who put together the Second Harvest Food Bank application.  Also, 360Flex Conferences donated 10 percent of their profits to this non-profit to help provide food to those in need.

As for the remainder of my day, here on the last day of this most excellent conference.

I am attending:

  • 10:00 Tony Hillerson & Juan Sanchez’ See the Data, Be the Data
  • 1:00 Jun Heider’s Using the Flex Builder 3 Profiler
  • 2:30 RJ Owen & Brad Umbaugh’s Diving Deep with Component Lifecycle
  • 4:00 Ryan Stewart’s Synchronizaton with Air and LiveCycle DS

Wow, this week has gone fast.  I have had a chance to meet, face to face, a bunch of my twitter friends.  I have had the opportunity to meet several new friends as well, even two who live and work nearby me.  This conference was all about networking when outside of the sessions and I tell you, employment opportunities with Flex abound.  The session content has ranged the entire skill/knowledge set and has been fun, informative, and absolutely interesting.

If you have an opportunity to attend a 360Flex conference then be sure to attend, I have not been dissapointed what so ever.