Simple DataGrid with ArrayCollection Update Example

I was helping out on the Flex community forum and one of the posts needed a little more of example than I could give using the forum post tools. So, I decided to create a quick example of a DataGrid using an ArrayCollection for the dataprovider. The ArrayCollection is created dynamically using a randomization selection from two static arrays. Then there is an option for updating the list showing which of the items have “Red” as the color value. I also put a couple of other items in the example, including an ItemRenderer for the DataGrid and a button holder for the Panel.

The first part of this example is to show an Object being used in an ArrayCollection. The idea behind using an Object is so that when the data is inserted, it is done as a specific type, which eliminates the need for casting String values into other types for manipulation. In this example, the myObjectItem has 2 String, 1 Number and 1 Boolean objects. The class defines these objects and also has a function for creating the object from passed in values.

package controls
{
	public class myObjectItem
	{
		public static function create(itemValue1:Number, itemValue2:String = '', itemValue3:String = '', itemValue4:Boolean = false):myObjectItem {
			var tmpMyObject:myObjectItem = new myObjectItem();
			tmpMyObject.myItemValue1 = itemValue1;
			tmpMyObject.myItemValue2 = itemValue2;
			tmpMyObject.myItemValue3 = itemValue3;
			tmpMyObject.myItemValue4 = itemValue4;
			
			return tmpMyObject;
		}
		
		public function myObjectItem()
		{
		}
		
		[Bindable]
		public var myItemValue1:Number;
		[Bindable]
		public var myItemValue2:String;
		[Bindable]
		public var myItemValue3:String;
		[Bindable]
		public var myItemValue4:Boolean;
	}
}

Creating the object is straight forward. Call the create function and add each value, in this case, by setting the Number to the loop value, the Strings to random vales from two arrays and the Boolean to false. The object is created and then added to the ArrayCollection. There are other ways of creating the ArrayCollection with data passed in from XML or data connections, but for this example, I am creating the data randomly.

// populate Arrary Collection with random values
var lengthOfMyArray:int = 26;
	for(var i:int = 0; i < lengthOfMyArray; i++) {
		myArrayCollection.addItem(myObjectItem.create(i, randomStringItem(colors), randomStringItem(fruits)));
	}

The second part of the example is to update a value in the ArrayCollection. The post on the Flex forum was doing a calculation and then setting a value to “true”. In my example, I check the String value for “Red”. If it is found, then I set the Boolean value to true as parts of a new object with old data from the original object and then using setItemAt to place the new object back in the ArrayCollection at the position of the old object.

protected function findRed_clickHandler(event:MouseEvent):void {
				// looks for the "red" in ItemValue2 and changes ItemValue4 
				for(var t:int = 0; t <  myArrayCollection.length; t++) {
					var tmpObject:Object = new Object();
					tmpObject = myArrayCollection.getItemAt(t);
					
					if(tmpObject["myItemValue2"] == "Red") {
						tmpObject.myItemValue4 = true;
					} else {
						tmpObject.myItemValue4 = false;
					}
					
					myArrayCollection.setItemAt(tmpObject, t);
				}
				// Refresh Data
				myArrayCollection.refresh();				
			}

This is a very straight forward example and I might add more items to it later.

View Source

Spark LineGrid Component

Since I had a day off, I decided to work on converting my old Flex Examples to the new Flex 4.  As stated in a previous post, the new Flex 4 breaks Degrafa and Degrafa seems to be defunct now.  Most of the drawing functions are handled with spark and sprite functions, but little things like arcs and line repeaters are not.  So where before it was easy enough to create a repeating line in Degrafa, now I have to do a loop to create the lines needed.  Well, in this case, instead of drawing lines, I’m drawing rectangles.  While it might seem simple at first just to draw a bunch of rectangles together to create a grid, there is a little trickiness to it.  You can have to account for the size of the total grid, based on the number of columns, rows and the grid box size.  And you also have to use both the column and row count value to draw the correct number of rows and columns and at the right size.  It is all just a matter of thinking about it for a few moments and then having an “ah ha!” moment.  Another little quirk with the components is that when you add a visual element, it puts it in the center of the group component.  On the Egg Timer, I just left it there for now because it worked for what I needed.  I might change it later.  But for the LineGrid, it made for it not to line up correctly.  So, before I start drawing the rectangles, I had to determine the actual 0,0 location first.  It also took a couple tries to make sure I was using the right zero.


// Find the actual 0,0 start
var actualZeroX:int = -1 * ((columnCount * boxSize) * .5);
var actualZeroY:int = -1 * ((rowCount * boxSize) * .5);

One good thing about the new components, is that when you use the declarations, it is the same as creating a set function, which means less code.  I simply added declarations for the column and row counts, then put those values where I need them.  When I use the LineGrid component I add the values I need just like any other attribute.


<components:LineGrid id="lineGrid1" rowCount="5" columnCount="5" boxSize="50" lineThickness="4" lineColor="0x009900" />

Here is the example showing a grid with equal columns and rows and then two other grids with column or rows determined by the size of the application.

[kml_flashembed publishmethod="dynamic" fversion="10.0.0" movie="http://demo.deanlogic.com/Flex/GridLineRepeater/SparkGridLines.swf" width="800" height="300" targetclass="flashmovie"]

Get Adobe Flash player

Horizontal Slider and List synch

As I stated in a previous post, I am working on a little project for work that dealt with including arrays inside of arrays.  Part of this also had me putting lists inside of lists.  The layout of one of the display has an Accordion navigation control with a HorizontalList, that also contained an accordion with it’s own HorizontalList.  I am using the horizontal list to scroll through main items with sub-items below.  On top of this, I am creating the HorizontalList, the HSlider and the Accordion controls all dynamically.

The first part of setting up the slider and list, is to make sure the HorizontalList has only 1 columnCount (number of columns displayed), else you see all of your items.  The second part is to set the start and end of the slider.  At first I used 0 as the start, but since I am showing the initial record, 1 should be the minimum value.  I set the maximum value to the length of the data set for the list.   I had found some code that used a counter to determine the position of the slider and the list.


private function prevClick(evt:Event):void{
var tmpHozList:HorizontalList = new HorizontalList();
tmpHozList = evt.target.data[0][0];
var tmpSlider:HSlider = new HSlider;
tmpSlider = evt.target.data[0][1];
//move Horizontal List
var pos:int = tmpHozList.horizontalScrollPosition - 1;
var min:int = 0;
var curvalue:int = Math.max(min, pos);
tmpHozList.horizontalScrollPosition = curvalue;

//move Slider
tmpSlider.value = curvalue;
}

private function nextClick(evt:Event):void{
var tmpHozList:HorizontalList = new HorizontalList();
tmpHozList = evt.target.data[0][0];
var tmpSlider:HSlider = new HSlider;
tmpSlider = evt.target.data[0][1];

//move Horizontal List
var pos:int = tmpHozList.horizontalScrollPosition + 1;
var min:int = 0;
var curvalue:int = Math.max(min, pos);
tmpHozList.horizontalScrollPosition = curvalue;

//move Slider
tmpSlider.value = curvalue;
}

The counter would get the current position and then add or subtract (depending on the button pushed) from the count and then determine max (Math.max) value between the count and the minimum and return that value to step the slider.  Well, this wasn’t working correctly.  I was trying to figure out if Math.min and some other method of determining the min and max values of the slider, when it hit me to just increment and decrement the value.  I use increment all the time in loops, so why wouldn’t it work to move the slider and the list position.


private function prevClick(evt:Event):void{
var tmpHozList:HorizontalList = new HorizontalList();
tmpHozList = evt.target.data[0][0];
var tmpSlider:HSlider = new HSlider;
tmpSlider = evt.target.data[0][1];
if(tmpHozList.horizontalScrollPosition > 0){
//move Horizontal List
tmpHozList.horizontalScrollPosition--;
//move Slider
tmpSlider.value--;
}
}

private function nextClick(evt:Event):void{
var tmpHozList:HorizontalList = new HorizontalList();
tmpHozList = evt.target.data[0][0];
var tmpSlider:HSlider = new HSlider;
tmpSlider = evt.target.data[0][1];

//move Horizontal List
tmpHozList.horizontalScrollPosition++;
//move Slider
tmpSlider.value++;
}

Well, it did work, except for one small issue.  For some reason, increase the count didn’t cause any issues.  Possibly the max amount it can increment on the HorizontalList works great, but the minimum value does not.  Regardless, decrementing the values would lead to the  list position going below 0 and causing an error. Which means, that for the previous button, I had to put a check in to make sure the current value wasn’t less than the minimum value, which was 1.  Anything over 0 was fine.  Simple and less code.  Now I just have to go through and update the other slider list combos.

Zend AMF and Flash Builder

While I was pondering creating the Flex/Flash test application for the Demo site, I ran across Flex Test Drive.  I remember reading it before and couldn’t remember why I didn’t go through with the example….then I tried connecting to the php web service.  The Flex Test Drive gives you three options for a server:  Java, PHP and ColdFusion.  I don’t have a ColdFusion or Java option on my hosted website, so PHP was the way to go.  I also didn’t want to bother installing a web server locally, because I want to post my examples on my site.  Because of this, installation is probably not as straight forward as I hoped it would be.

The first part of Flex Test Drive creates the starting application, which you choose the server backend.  Since I wanted to use my website as the server, I put in http://demo.deanlogic.com for the Root URL.  The example points to a local web server, so this is where I started to diverge from the game plan.  The next part was to create a database using MySQL server and then add some basic components to the application.  All of that went fine, after a few short hick-ups in the sql statement to populate the tables.  The next step is connecting to the database using the PHP remote connection and that’s where I got into trouble.

The PHP remote connection uses Zend AMF, which is part of the Zend Framework. Apparently in Flash Builder 4.5, the integration is even closer.  However, part of the setup of the PHP Zend AMF connection adds the Zend Framework to the application directory.  Once that is added, you have to updated the amf_config.ini file to point to the framework and library directories.  This is were it got a little confusing for me.  Since the initial directories are locally on my PC, I didn’t know which directories to use; UNIX or Windows.


[zend]
;set the absolute location path of webroot directory, example:
;Windows: C:\apache\www
;MAC/UNIX: /user/apache/www
webroot = /home/users/web/deanlogiccom

;set the absolute location path of zend installation directory, example:
;Windows: C:\apache\PHPFrameworks\ZendFramework\library
;MAC/UNIX: /user/apache/PHPFrameworks/ZendFramework/library
zend_path = ZendAMF/Zend/ZendFramework/library

[zendamf]
amf.production = false
amf.directories[]=services

My first attempt was to use the UNIX directories, but it would end up with not being able to find the include files.  I even downloaded the ZendFramework from the Zend site and loaded it up to my site.  Nothing seem to work.  I even tried altering the gateway.php file to point directly to the directories without using the check code included.  Going directly to the gateway.php on my website would show the same error I was getting when connecting.  So, I figured I could modify the init file until that error went away.  After several attempts at different directory options, I finally saw “Zend Amf Endpoint” on the gateway page.  Woo hoo!!

Unfortunately the PHP remote connection still wasn’t working, which is when I noticed that it said something about the release folder and the gateway file.  When I initially deployed the Flex application, it was under the bin-debug folder, while the ZendFramework was a few levels higher.

By moving all of the deploy files to the same level as the ZendFramework folder, I finally got the PHP Zend remote connection to work.  When the connection works, it uses the EmployeeService to get information from the database to be used in the rest of the Test Drive demonstration.

Hopefully later I get the directory setup so it is a little cleaner.  It seems that everything I add just drops into the main folder.  The Dreamweaver Widgets did this as did the CSS from the style sheet.  I prefer things to be much more organized.  But, for now, I’m glad the data connection is working so I can move on with the Test Drive.

 

ArrayCollection in an ArrayCollection

At work I am trying to display a bunch of information retrieved from a web services.  The data has a header table (top item) and then supporting item tables (sub items).  My current data only brings back one top item, but I have set it up to display multiple top items using a HorizontalList.  I created a custom component based on a Form, which allows me to easily display header and values.  In the future, I can probably use the form for inputs, but for now it is just displaying.  I am also using an Accordion container to display each of the header items that are wrapped in an overall item.  In each Accordion item, I dynamically create a box, to hold the form, which is dynamically created by passing it in as a new ClassFactory.  The Form acts as an item render in the HorizontalList.  Well, the problem I ran into is, that you can only pass in one DataProvider into the HorizontalList.  This was causing an issue with an item that would have an over all header information and then a DataGrid full up sub items.   After starting to fuss around with other options, it occurred to me to pass in the sub items as an ArrayCollection type.

For example, if I had a class called MyObject


package {

public class MyObject {

[Bindable]
 public var ID:Number:

[Bindable]
 public var Name:String:

[Bindable]
 public var itemList:ArrayCollection
}
}

And earlier I populated an ArrayCollection called itemListArrayCollection with data, then I wanted to add this to an ArrayCollection called myMainArrayCollection, it would look something like this.


var newObject:MyObject = new MyObject();

newObject.ID = 1;

newObject.Name = 'Test';

newObject.itemList = itemListArrayCollection;

myMainArrayCollection.addItem(newObject);

Then, in the Form I created to display the items, I would set the FormItems to show ID and Name


<mx:FormItem>

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

</mx:FormItem>

<mx:FormItem>

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

</mx:FormItem>

And the DataGrid within the form would get it’s DataProvider through the initial data value.  I can also point to the columns (DataFields) in the itemListArrayCollection in order to set up the DataGridColumns.


<mx:DataGrid dataprovider="{data.itemList}">

<mx:columns>

<mx:DataGridColumn DataField="listField1" />

<mx:DataGridColumn DataField="listField2" />

<mx:DataGridColumn DataField="listField2" />

</mx:columns>

</mx:DataGrid>

I’m sure I’m not the first person to pass an ArrayCollection inside of an ArrayCollection, but it was an “ah ha!” moment for me today.  I’m not sure if it is considered best practice to do this, but it works for what I need much simpler than trying to create a component to receive multiple multiples of DataProviders.  Once I get things straightened out with the current web services, I know I will have to go back and probably have an overall ArrayCollection with 3 – 5 ArrayCollections passed into it.

Adobe BrowserLab

I decided to take a glance at the widgets I put in earlier today and stumbled onto a nice little tool over at Adobe.  In Dreamweaver you have a few options for viewing your work to determine how it will look in the real world.  The first method is to use a split view, which gives you one frame of code and another frame of design.  The obvious benefit is that you can quickly find your code problems before sending it up to the site.  However, as you notice from the image below, it might not actually be what  you really see.

Adobe apparently has their previewer using some of the same code as Chrome, because the color changes I added to the Aqua Button widget show in the preview but not in my FireFox browser.  Dreamweaver helps you determine what the page will look like in the real world, without loading every version of every browser, with a Preview Menu.  On the menu are the browsers loaded on your PC and then a couple of other options.

There is a Preview in BrowserLab option that launches Adobe BrowserLab.  This, complimentary until April 12, 2012, tool allows you to view a web page in multiple browser simulators.  The browser choices even differentiate between OS version, because there are FireFox for OS X and Windows options.  The menu launches BrowserLab with your file version of your page or  you can load your site using the URL.   You can select multiple browsers for viewing the site, but BrowserLab will do a initial loading of all the select browsers before you can view.  Once everything is loaded, you can switch between the browsers selected and view 2 browser options at the same time, either in split view or onion layers. From the screen shot below, you can see that Chrome displays orange buttons, while FireFox does not.  This makes BrowserLab a very useful tool for quickly viewing your website across many browser version.  I hope that Adobe keeps it free for those who have Dreamweaver.  I also have used Adobe Story for some movie projects, which also has a “complimentary until April 12, 2012″.  I am guessing Super Duber Master Creative Collection Suite 6 will be launched then.  Maybe by then, I’ll have made some money off of one of my hobbies to pay for the expensive upgrade.

The other option on the Preview menu is Preview in Device Central .  Device Central is part of a few different Adobe applications.  It makes sense that Dreamweaver would give a device preview.  Everybody wants to know how their site will look like on mobile devices or a tablet or even a television. Yes, a television.   There is a device library that allows for downloading of different device profiles.  Even though Apple doesn’t like Adobe much, apparently Adobe is nice enough to provide iPad and iPhone profiles.  There are also BlackBerry phone and tablet profiles and bunch others.  And if Adobe didn’t create a profile you are looking for, apparently you can create one and share it in the library.  Once you have download the profile, you can add it to your test devices.

Finally, you can use the Multiscreen Preview to see how your site will look in different screen resolutions.  The default sizes are Phone (320 x 300), Tablet (768 x 300) and Desktop (1126 x 276).  Since these dimensions won’t fit all issue, you can modify the sizes, however, they might not fit neatly in the three pain window like the defaults.  You can also use this tool to setup multiple css files to be shown based on the size of the screen (small, medium, large).

With all of these tools, it will be easy for anyone to prepare their site for almost any possible viewer.

Adobe Edge and HTML5

Last night I downloaded Adobe Edge, which is Adobe’s tool for creating HTML5 basic animations.

Adobe® Edge is a new web motion and interaction design tool that allows designers to bring animated content to websites, using web standards like HTML5, JavaScript, and CSS3.

Edge will be updated regularly to add new functionality, stay ahead of evolving web standards, and incorporate user feedback to provide the best functionality and experience possible. This is an early look at Edge with more capabilities to come.

The current capabilities are very limited.  You can added Text and boxes to a canvas, plus you can import images.  There is a timeline, similar to what is seen in Adobe Premiere and I guess now Adobe Flash.  I haven’t looked into Adobe Flash very much, but I have been using Premiere for my movie projects. In the timeline, you add key points and then you can alter the color, scale, skew, position, opacity and rotation. It is fairly simple to use.  When you click on the object you have added and make a change using the properties panel, it automatically enters a layer for the effect.  I added the effect I created to the Demo site, but it only ran once.  The “Preview in Browser” works fine, but copying the JavaScript links and files, plus adding the div tag seems to not work entirely.  I probably broke it when I added my site logo to the animation. Anyway, I’m not that overly impressed.  I see articles that HTML5 will be the end of Flash.  Apparently these authors know nothing of Flex and that’s probably Adobe’s fault for melding the names together.  Yes, Flash is a timeline based animation tool, but it does a little more than that.  Flex is an application tool that outputs to Flash.  I’m not sure if Flex can be displayed using HTML5.  Just like Java, CGI and Perl haven’t gone away, I don’t see Flash going away, even if a certain fruit company has a problem with it.

Regardless of my first attempts with Edge Beta 2, I will be trying to add HTML5 elements tot he Demo site, because it is the latest buzz word and well, I’ll let Larry Ellison explain it.

Animating the logo

After getting a wonderful give of Adobe Master Collection from my wife, I am slowly learning how to use the many tools available.  Currently I am using Premiere to edit the footage of The RTP “Let’s Make a Movie” Meetup project called “I Remember Hanna“.  The movie is around 10 minutes long, but it took us 2 months to get if filmed due to location issues.  So far, I have learned how to add the video and clip it for the appropriate shots.  When it gets done and everything is complete, I’ll add a post about it.

One thing I would like to add to the film is a animated logo for Dean Logic.  This would be the animated logo I would use for any film I direct or produce, which so far is every movie that the “Let’s Make a Movie” group is doing so far.  Of course, if I do a movie outside of the group, I’ll use the logo for that as well.  Anyway I’m trying to learn how to use the 3D effects available in After Effects.   With this video, I am using the CC Partical World.  I need to figure out how to change the spheres to light bulbs.