Categories
Articles

Flex Tilelist Listbase Fails on Resize

I often find myself investigating code issues from other programmers. Recently I had to deal with a rather complicated Flex 3 container problem. The problem occurred when resizing an application. The runtime error was


TypeError: Error #1009: Cannot access a property or method of a null object reference.
at mx.controls.listClasses::ListBase/addToFreeItemRenderers()[E:\dev\3.1.0\frameworks\projects\framework\src\mx\controls\listClasses\ListBase.as:4770]
at mx.controls.listClasses::ListBase/reduceRows()[E:\dev\3.1.0\frameworks\projects\framework\src\mx\controls\listClasses\ListBase.as:3863]
at mx.controls.listClasses::ListBase/updateDisplayList()[E:\dev\3.1.0\frameworks\projects\framework\src\mx\controls\listClasses\ListBase.as:3639]
at mx.controls.listClasses::TileBase/updateDisplayList()[E:\dev\3.1.0\frameworks\projects\framework\src\mx\controls\listClasses\TileBase.as:2357]
at mx.controls.listClasses::ListBase/validateDisplayList()[E:\dev\3.1.0\frameworks\projects\framework\src\mx\controls\listClasses\ListBase.as:3279]
at mx.managers::LayoutManager/validateDisplayList()[E:\dev\3.1.0\frameworks\projects\framework\src\mx\managers\LayoutManager.as:605]
at mx.managers::LayoutManager/doPhasedInstantiation()[E:\dev\3.1.0\frameworks\projects\framework\src\mx\managers\LayoutManager.as:678]
at Function/http://adobe.com/AS3/2006/builtin::apply()
at mx.core::UIComponent/callLaterDispatcher2()[E:\dev\3.1.0\frameworks\projects\framework\src\mx\core\UIComponent.as:8565]
at mx.core::UIComponent/callLaterDispatcher()[E:\dev\3.1.0\frameworks\projects\framework\src\mx\core\UIComponent.as:8508]

Trying to reproduce the problem was more problematic. First it is all Adobe Flex code in the call stack.

Second the error would not occur unless you went through a set of steps. First you needed to have enough items in the tile list where to cause vertical scrolling. Then you needed to load a different list of items into tile list that did not require a vertical scroll. After that you resized the application to smaller you get the above error.

The code referenced in the above call stack is Adobe Flex code and the signature of the offending method to the offending line is shown here:


protected function addToFreeItemRenderers(item:IListItemRenderer):void
{
   // trace("addToFreeItemRenderers ", item);

   DisplayObject(item).visible = false;

The error is caused by the item variable having a null value.

The solution we used was found at Tom Van den Eynde RIA Flex Blog entry Exception after TileList resize.

Adding a resize event to the TileList in the complex embedded containers and calling executeBindings() on the TileList object made the problem go away.

Categories
Articles

Php5 Simple Singleton Design Pattern

I wanted to reproduce a simple singleton design pattern in PHP 5. After reviewing many overly complex examples, I synthesized to this example.

It also makes use of the PHP5 magic function __get and __set also poorly addressed in web postings. Going for cleaner code I like to see $obj->prop rather than $obj->getProp() and $obj->setProp(value) in the code. But I am greedy and want to have read only and write only props. So I configured the various examples to achieve that goal. As well you can see in the __set and __get methods you may choose to work the props or call a private method that would handle the validation and proper handling of the set and return values. I demonstrated this here.

This is the singleton running with the idea of a single configuration object for an application. It only has one real property named isDebugging for the example.

<?php
class Config
	static private $_instance;
    private $isDebugging = false; // Read write
	private $version = "1.1"   ;  // Read only
	private $cannotReadProp = "x" ;
	public static function getInstance($args = array())
	{
		if(!self::$_instance)
		{
			self::$_instance = new Config();
		}
		self::$_instance->setIsDebugging(isset($args['isDebugging']) ? $args['isDebugging'] : self::$_instance->isDebugging);
		return self::$_instance;
	}
	private static function setIsDebugging($value)
	{
		self::$_instance->isDebugging = is_bool($value)? $value: self::$_instance->isDebugging;
	}
	public static function __set($prop, $value)

		if (isset(self::$_instance->$prop)
		{
			switch ($prop)
			{
				case 'isDebugging':
					self::$_instance->setIsDebugging($value);
					break
				default :
					throw new Exception('Cannot write property [' . $prop . ']',1);
			}
		}
		else
		{
			throw new Exception('Undefined property [' . $prop . ']',1);
		}
	}
	public static function __get($prop)
	{
		if (isset(self::$_instance->$prop))
		{
			switch ($prop)
			{
				case 'isDebugging':
					return self::$_instance->isDebugging
					break;
			       default :
					throw new Exception('Cannot read property [' . $prop . ']',1);
			}
		}
		else
		{
			throw new Exception('Undefined property [' . $prop . ']',1);
		}
	}
}
?>

This is a testing script for the above. Note there are some commented lines for testing the exception thowing.

<?php
	include 'config.inc.php';
	// First reference
	$myConfig1 = Config::getInstance();
	// Get property
	echo ('$myConfig1->isDebugging:' . ($myConfig1->isDebugging ? "true" : "false")) . '<br/>';
	// Set property
	echo 'Set $myConfig1->isDebugging = true <br/>';
	$myConfig1->isDebugging = true;
	echo ('$myConfig1->isDebugging:' . ($myConfig1->isDebugging ? "true" : "false")) . '<br/>';
	// Second reference
	echo '<br/>';
	echo 'Add second reference and not getInstance args<br/>';
	echo '$myConfig2 = Config::getInstance(); <br/>';
	$myConfig2 = Config::getInstance();
	echo ('$myConfig1->isDebugging:' . ($myConfig1->isDebugging ? "true" : "false")) . '<br/>';
	echo ('$myConfig2->isDebugging:' . ($myConfig2->isDebugging ? "true" : "false")) . '<br/>';
	// Third reference<br />
	echo '<br/>';
	echo 'Add third reference and change prop via getInstance arg <br/>';
	echo '$myConfig3 = Config::getInstance(array(\'isDebugging\'=>false)); <br/>';
	$myConfig3 = Config::getInstance(array('isDebugging'=>false));
	echo ('$myConfig1->isDebugging:' . ($myConfig1->isDebugging ? "true" : "false")) . '<br/>';
	echo ('$myConfig2->isDebugging:' . ($myConfig2->isDebugging ? "true" : "false")) . '<br/>';
	echo ('$myConfig3->isDebugging:' . ($myConfig3->isDebugging ? "true" : "false")) . '<br/>';
	// Set property via second instance
	echo '<br/>';
	echo 'Set property via second instance <br/>';
	echo 'Set $myConfig2->isDebugging = true <br/>';
	$myConfig2->isDebugging = true;
	echo ('$myConfig1->isDebugging:' . ($myConfig1->isDebugging ? "true" : "false")) . '<br/>';
	echo ('$myConfig2->isDebugging:' . ($myConfig2->isDebugging ? "true" : "false")) . '<br/>';
	echo ('$myConfig3->isDebugging:' . ($myConfig3->isDebugging ? "true" : "false")) . '<br/>';
	// Set property to incorrect data type
	echo '<br/>';
	echo 'Set $myConfig1->isDebugging = 123<br/>';
	echo 'No exception for invalid data type and not prop change.<br/>';
	$myConfig1->isDebugging = 123;
	echo ('$myConfig1->isDebugging:' . ($myConfig1->isDebugging ? "true" : "false")) . '<br/>';
	echo ('$myConfig2->isDebugging:' . ($myConfig2->isDebugging ? "true" : "false")) . '<br/>';
	echo ('$myConfig3->isDebugging:' . ($myConfig3->isDebugging ? "true" : "false")) . '<br/>';
	// Setter throws undefined property exception
	//$myConfig1->test = true;
	// Getter throws undefined property exception
	//echo '$myConfig1->test:' . $myConfig1->test . '<br/>';
	// Setter throws cannot write property exception
	//$myConfig1->version = '2.2';
	// Setter throws cannot read property exception
	//echo '$myConfig1->cannotReadProp:' . $myConfig1->cannotReadProp . '<br/>';
?>
Categories
Articles

Flex LocalConnection Error 2044 Unhandled StatusEvent Level

I have seen this error when trying to use SWFLoader and LocalConnection with a Flash SWF. The problem is related to using the LocalConnection but the Flash SWF has not played the requisite frame where its side of LocalConnection code appears. As such there is no local connection.

To see sample code to overcome this look at my post on using Flex, SWFLoader and LocalConnection: Flex LiveConnection and Legacy Flash SWFs

Categories
Articles

Flex LiveConnectionand Legacy Flash Swfs

The more RIA shops move web apps into Flex the ugly issue of integration of legacy Flash SWFs into Flex may show up.

The likely Flex component to use for loading Flash SWFs is SWFLoader. It can handle Actionscript 2 legacy Flash 8 or CS3 SWFs.

You may also use SWFLoader for cases of separate independent Flash SWFs that also need to be used into a Flex app and you may not have control over the SWF internal development requiring preparedness for just about anything.

For example you get SWFs with independent inputs from places such as FlashVars, external XML or even another SWF container. Perhaps there are internal functions in place handling these tasks.

However you find that code you need to call from Flex is not available on frame 1. You may find SWFLoader cannot call those functions due to timing inside the Flash SWF and you do not want to recode the SWF.

Then you might find using LocalConnection as a solution. You have the SWF invoke functions in the Flex SWFLoader component to inform ready states such as code available on a certain frame. Then the Flex function can use LocalConnection to call the SWF function.

Here is an example where the requisite code was on frame 10 of the FLA file.

[cc lang=”actionscript” tab_size=”3″ line_numbers = “true”]
System.security.allowDomain(“*”);
var _fromFlex_lc:LocalConnection = new LocalConnection();
_fromFlex_lc.allowDomain(“*”);

_fromFlex_lc.loadXML = function(xmlStr:String):Void
{
Main.getInst().loadXML ( xmlStr );
_fromFlex_lc.close();
}

_fromFlex_lc.connect(“flex2Swf_lc”);
var _outgoing_lc:LocalConnection = new LocalConnection();
_outgoing_lc.allowDomain(“*”);
_outgoing_lc.send( “swf2Flex_lc”, “swfReadyToLoad” );

[/cc]
Here is the SWFLoader component:


xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="initSwfComp()">



Categories
Articles

Papervison3D

This example is remake of Lee Brimelow’s example. I removed the tweener library and used the Flash Tween class.I also took the Actionscript code out of the Fla and created an Actionscript class to give a start for creating a component version.

Complete example:

Flash CS3 Actionscript 3 Papervision3D 1.5 Carousel

Categories
Articles

Papervision 3d Great White Rotating Cube Multiple Bitmap Materials Example

September 2007 I meet with Sci-Fi channel over some potential web site work. During the process they asked if I had worked with Papervision. I had not but heard of it. After the meeting I went back and did the usual downloads to try it out. I found the community following it cannot express themselves clearly but I muddled through the few examples and documentation. Then I lost interest.

More recently I got some interest because I am working with the Verizon Wireless (VZW) web site team. The team is reviewing some of the static Flash product display animations that have hard coded data sources and tying them into live active data. As part of that process I decided to consider some of the more advanced Flash RIA capabilities.

So on my own time I decided to revisit the Papervision3D world. I found that there is a new version 2 dubbed Great White for development. For VZW I thought it would be better to stick with the 1.5 version of Papervision3D.

I wanted to try a rotating cube with each face having a different bitmap material. I downloaded the 1.5 zipped version and proceeded to find examples on the net for this application. However I soon discovered (actually hours) that although the examples and the documentation indicated that multiple materials were possible, it did not work. I suspected there were updates and you really needed to be using subversion to keep up.

Finally I decided to use subversion. I also decided skip to the Great White version. I started to see a sync in the code with the examples seen on the net.

So an example is posted here for your interest: Flash CS3 Actionscript 3 Papervision3D 2 (Great White) 3D Cube Rotation Example.

I added a second example that provides a Plane for a perspective on the rotating Cube. New controls to move the camera. I changed the rotation to y only. Added to that is a Timer to control the speed of rotation and allow stopping and starting it. Here is the link:

Flash CS3 Actionscript 3 Papervision3D 2 (Great White) 3D Cube Rotation Example With Controls for Animation and Camera Position

Categories
Articles

Astro is Flash 10

After a summer working long hours on micro sites for clients of the advertising agency Digitas in NYC followed by a super car and hiking trip through the US Midwest (videos) for a few weeks and some “retirement” time off, I am back in the tech seat. So I saw this a while ago, but I reluctant to get glued into my PC for too much during my break.

At MAX 2007 Chicago video cameras were rolling to show Adobe’s new direction with Flash/Flex/AIR development. It is code named Astro. What we see now Flash 10 and Astro are the same.

Here is one YouTube links you can see for yourself.

As well you can follow the progress of Astro at this link at Adobe Labs.

One impressive item was the attempt to allow designers create local test data that normally would server from the internet. This will extend designers further into the development and design cycle without the need to code.

3D is starting to show up in the Flash Player. Right now it is called 3D effects. Not sure how limiting that term is but there is an indication of an API for 3D.

More image processing functionality under the name Hydra that allows custom image filters and effects. Sounds like fun for the showy needs.

There is no beta as of this writing.

Categories
Articles

Actionscript 3 Animating Sprite Rotation Following Mouse Movement

By Lon (Alonzo) Hosford

This my own version of of Keith Peter’s Foundation Actionscript 3.0 Animation: Making Things Move chapter 3 implementation of sprite rotation following a mouse.

Download files
[August 10 2010 – I updated this to an Actionscript project in Flex Builder 4. ]

Keith Peters AS3 Animation
Learn More

You can build this with the free Flex SDK by using the code in the src folder. Same for Flash CS3 and later versions. You need to create a Flash Document in the src folder and set the document class to Chapter03_Rotation_AS3. For your convenience the Flash CS4 example download is included.

This article shows the code for the Flex project.

Application Class – Chapter03_Rotation_Flex
This Flex version is a spark implementation. The SpriteVisualElement component shown on line 51 is used to add the code to the application display on line 31.

<?xml version="1.0" encoding="utf-8"?>
<!--
	Application class for showing sprite rotation following mouse movement. 
	<p>Author: Lon Hosford https://www.lonhosford.com 908 996 3773</p>
    <p>Reference: Keith Peter's Actionscript 3.0 Animation Chapter 3</p>
	
-->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
			   xmlns:s="library://ns.adobe.com/flex/spark" 
			   xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="400"
			   creationComplete="creationCompleteHandler(event)" 
			   viewSourceURL="srcview/index.html">
	<fx:Script>
		<![CDATA[
			import mx.events.FlexEvent;
			
			// Properties for background
			private static const backgroundColor:Number = 0x0000ff;
			private static const backgroundBorderColor:Number = 0x666666;
			private static const backgroundBorderWeight:Number = 2;
			/**
			 * Handler for Application creationComplete event
			 * */
			protected function creationCompleteHandler(event:FlexEvent):void
			{
				// Create an Arrow object
				var arrow:Arrow = new Arrow();
				// Wrap arrow object into a RotateSpriteToMouse object
				var rotateToMouse:RotateSpriteToMouse = new RotateSpriteToMouse(arrow);
				// Add rotateToMouse Sprite to a SpriteVisualElement
				arrowVisualElement.addChild(rotateToMouse);
				// Center the SpriteVisualElement
				arrowVisualElement.x = background_bc.width / 2;
				arrowVisualElement.y = background_bc.height / 2;
			}

		]]>
	</fx:Script>
	<!--- 
	Background for app 
	--> 
	<s:BorderContainer id = "background_bc"
					   width="{width}" height = "{height}"
					   borderWeight="{backgroundBorderWeight}"
					   borderColor="{backgroundBorderColor}"
					   backgroundColor="{backgroundColor}">

		<!--- 
		Spark container for Sprite 
		--> 
		<s:SpriteVisualElement id="arrowVisualElement" />

	</s:BorderContainer>
					   
</s:Application>

[ad name=”Google Adsense”]
RotateSpriteToMouse Class
This is the class that does the work. Listening to the Event.ENTER_FRAME event leads to the update_rotation() method that does the work of updating the rotation.

package
{
	import flash.display.Sprite;
	import flash.events.Event;
	/**
	 * Rotates sprite to mouse position
	 * */
	public class RotateSpriteToMouse extends Sprite
	{
		private var _sprite_to_rotate:Sprite;	// Sprite to rotate to mouse
		/**
		 * Constructor 
		 * @param sprite_to_rotate The sprite to rotate
		 * */
		public function RotateSpriteToMouse(sprite_to_rotate:Sprite)
		{
			_sprite_to_rotate = sprite_to_rotate;
			addChild(_sprite_to_rotate);
			addEventListener(Event.ENTER_FRAME, enterFrameEventHandler);
		}
		/**
		 * The event handler for Event.ENTER_FRAME
		 * */
		private function enterFrameEventHandler(event:Event):void
		{
			update_rotation();
		}
		/**
		 * Updates the rotation of the _sprite_to_rotate
		 * */
		private function update_rotation():void
		{
			// Triangle adjacent angle side distance for the x value.
			var dx:Number = mouseX - _sprite_to_rotate.x;
			// Triangle opposite angle side distance for the y value.
			var dy:Number = mouseY - _sprite_to_rotate.y;
			// Compute angle in radians from the sprite to the mouse position.
			var radians:Number = Math.atan2(dy, dx);
			// Convert radians to degrees
			_sprite_to_rotate.rotation = radians * 180 / Math.PI;
		}
	}
}

Arrow Class
Simple arrow sprite that Keith wrote. Key here is the center registration point.

package
{
	import flash.display.Sprite;
	/**
	 * Creates an arrow sprite with fixed dimensions
	 * */
	public class Arrow extends Sprite
	{
		public function Arrow() 
		{
			draw();
		}
		/**
		 * Draw the arrow
		 * */
		private function draw():void
		{
			graphics.lineStyle(1, 0, 1);
			graphics.beginFill(0xffff00);
			graphics.moveTo(-50, -25);
			graphics.lineTo(0, -25);
			graphics.lineTo(0, -50);
			graphics.lineTo(50, 0);
			graphics.lineTo(0, 50);
			graphics.lineTo(0, 25);
			graphics.lineTo(-50, 25);
			graphics.lineTo(-50, -25);
			graphics.endFill();
		}
	}
	
}