Posted by admin on 18th June 2009
Cloning an array using concat will not clone the Objects contained by the array. Cloning with concat and then modifying one of the object will be modified in both arrays because the array contains references to the same object. That’s why we need to do a deep copy of the array, like in the following function.
/**
* will do a deep copy of the Object
*/
public static function deepClone(source:Object):*{
var myBA:ByteArray = new ByteArray();
myBA.writeObject(source);
myBA.position = 0;
return(myBA.readObject());
}
The above function will clone the Array and all the objects that are contained, however it has a major disadvantage. Custom Objects contained in the cloned array will lose their class definition and array[i] as CustomClassVO will give null. This is hapening because during the deep copy the objects loose their class association. To prevent this, the following line(s) has to be added just before doing the deep copy:
import flash.net.registerClassAlias;
registerClassAlias("com.client.vo.CustomClassVO", CustomClassVO);
Now, there is a more easy way to handle deep copy without loosing the custom class definition, just add the following line just before your custom class definition
[RemoteClass] /*this will help cloning the item and retaining class information*/
public class CustomClassVO{
public var variableName:String = '';
public var variableValue:Object;
public function CustomClassVO(pVariableName:String = '', pVariableValue:Object = null){
variableName = pVariableName;
variableValue = pVariableValue;
}
}
Noticed the [RemoteClass] ? It does all the job, now copying an array of CustomClassVO’s using the deepClone() is simple.
Posted in <Flash>, <Flex> | No Comments »
Posted by admin on 16th March 2009
I’m just back from Adobe Flex Camp Timisoara organized by Adobe Romania http://myadobe.ro/2009/02/19/flex-camp-timisoara-its-a-go/
I went to Timisoara (from Cluj Napoca, 350 km) by train (with Anca(Flash) and Bianca(Flash/Flex) my coworkers, Andrei(Bainca’s husband) and Amalia(my girlfriend)), didn’t sleep for about 48 hours at all, but it all worth it. The evangelists from Adobe Romania(Mihai Corlan, Miti Pricope and Cornel Creanga) made a really cool presentation, all the stuff they were speaking about I already know from blogs and the adobe labs page http://labs.adobe.com/
I asked the adobe people about bugs (see my post Flex Bugs) and what’s the reason they are not looking at community raised bugs on their Jira. They sad, they are looking, but there are so many community raised bugs, that they can’t take a look at every of them and most of the time they can’t reproduce it. They also sad, the bugs are prioritized and they are looking first at the bugs that have the bigger impact. We can increase community bugs priority by voting them.
Now that Timisoara Flex Camp is over, I just can’t wait Adobe to come in Cluj Napoca too.


Posted in <Flex> | No Comments »
Posted by admin on 9th March 2009
Flash/Flex/AIR produces a poor quality(pixelated) image when you load a larger image and try to re size it in the player to a much smaller size.
I searched the web and found this post http://www.cafesilencio.net/blog/bitmapdata-resize-quality-in-flex-and-air, tried the code but I didn’t see any improvements on the image quality.
It seams that Flash player doesn’t use a bilinear/bicubic interpolation algorithm to resize images, probably that’s why the produced image is so bad.
I came up with a solution, it seams that if you first apply a Blur effect on the image, then resize it, the produced image will appear much nicer. Of course the amount of Blur has to be calculated, otherwise we will end up with a poor quality image…again.
Check out the image before/after my solution, also you can try out the solution here
(don’t forget to check the “Apply Blur” check box to see my re size solution)
Here is the code for resize images using blur.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
creationComplete="applyEffects()">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.core.UIComponent;
[Bindable] private var blurQualityDP:ArrayCollection = new ArrayCollection([{label: 'Low', value: BitmapFilterQuality.LOW},
{label: 'Medium', value: BitmapFilterQuality.MEDIUM},
{label: 'High', value: BitmapFilterQuality.HIGH}
]);
public static function getUIComponentBitmapData( target:UIComponent ):BitmapData {
var bd:BitmapData = new BitmapData( target.width, target.height, true, 0 );
var m:Matrix = new Matrix();
bd.draw( target, m, null, null, null, true );
return bd;
}
private function applyEffects():void {
var w:int = widthSlider.value;
var ratio:Number = w / originalImage.width;
var h:int = originalImage.height * ratio;
if (applyBlur.selected){
var blurXValue:Number = Math.max(1, originalImage.width / w) * 1.25;
var blurYValue:Number = Math.max(1, originalImage.height / h) * 1.25;
var blurFilter:BlurFilter = new BlurFilter(blurXValue, blurYValue, int(blurQuality.selectedItem.value));
originalImage.filters = [blurFilter];
} else {
originalImage.filters = [];
}
var bd:BitmapData = getUIComponentBitmapData(originalImage);
var rbd:BitmapData = resizeImageBD(bd, w, h);
img1.source = new Bitmap(rbd, PixelSnapping.AUTO, true);
}
public static function resizeImageBD( bitmapData:BitmapData, width:Number, height:Number ):BitmapData {
var newBitmapData:BitmapData = new BitmapData( width, height, true, 0x000000 );
var matrix:Matrix = new Matrix();
matrix.identity();
matrix.createBox( width / bitmapData.width, height / bitmapData.height );
newBitmapData.draw( bitmapData, matrix, null, null, null, true );
return newBitmapData;
}
]]>
</mx:Script>
<mx:VBox>
<mx:HBox>
<mx:Label text="Image Width" />
<mx:HSlider id="widthSlider"
value="300" minimum="0" maximum="1600"
width="800"
change="applyEffects()" liveDragging="true"
snapInterval="5"
dataTipPrecision="0"/>
<mx:CheckBox id="applyBlur" label="Apply Blur" change="applyEffects()"/>
<mx:ComboBox id="blurQuality" dataProvider="{blurQualityDP}" change="applyEffects()"/>
</mx:HBox>
<mx:Label text="Image Width: {widthSlider.value}" />
<mx:Canvas>
<mx:Image id="originalImage" source="@Embed(source='test7.jpg')"
x="100" y="100"/>
<mx:Image id="img1"
/>
</mx:Canvas>
</mx:VBox>
</mx:Application>
Posted in <Flex> | 2 Comments »
Posted by admin on 16th January 2009
Bugs…they are so frustrating. But whats worse then having your own bugs is: having other peoples bugs. Why? Because you can fix your bugs if you want to. But for bugs produced by other people you have to wait and wait and waaaaiiit.
This is the list of bugs I found during development in Flex in the last few weeks that are appearing from Adobe:
image doesn’t show up correctly when setting image.x + image.width > 8192!!!(ex x= 200, width=8100)
BitmapData not working as stated in the documentation
resize of an air application is enabled while in full screen mode
FileReference does not fire DataEvent.UPLOAD_COMPLETE_DATA when server takes too long to respond(about 30 seconds)
Image is fireing Click events when image.enabled=false
Downloading (using FileReference) more then 2 files simultaneously fails
Now, I’m sure the list will just grow bigger and BIGGER, I just hope Adobe will fix them, I mean, that’s why I reported to them.
Posted in <Flex> | No Comments »
Posted by admin on 31st October 2008
ViewStacks are great for storing containers and showing the one that is needed.
You can use the view stacks selectedIndex property for changing between the different views. However, by using the selectedIndex, often you have to change the indexes, because in case you comment or remove a container the indexes are changing for the views that are remaining.
The view stack has a selectedChild property, where you can set the view that needs to be shown by his id, but for using that in any part of the application, you should have access to the container.
Instead of using the id, I came up with a solution by using the containers name. Here it is:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
xmlns:local="*" >
<mx:Script>
<![CDATA[
import mx.core.Container;
import mx.core.UIComponent;
[Bindable] public static var STACK_CONTENT_NAME_1:String = 'stack1';
[Bindable] public static var STACK_CONTENT_NAME_2:String = 'stack2';
[Bindable] public static var STACK_CONTENT_NAME_3:String = 'stack3';
[Bindable] public static var STACK_CONTENT_NAME_4:String = 'stack4';
private function onClick():void{
myViewStack.selectedChild = myViewStack.getChildByName(STACK_CONTENT_NAME_3) as Container;
}
]]>
</mx:Script>
<mx:VBox>
<mx:LinkBar dataProvider="{myViewStack}" />
<mx:ViewStack id="myViewStack">
<mx:HBox label="ViewStack Item #1" name="{STACK_CONTENT_NAME_1}">
<mx:Label text="ViewStack Content #1" />
</mx:HBox>
<mx:HBox label="ViewStack Item #2" name="{STACK_CONTENT_NAME_2}">
<mx:Label text="ViewStack Content #2" />
</mx:HBox>
<mx:HBox label="ViewStack Item #3" name="{STACK_CONTENT_NAME_3}">
<mx:Label text="ViewStack Content #3" />
</mx:HBox>
<mx:HBox label="ViewStack Item #4" name="{STACK_CONTENT_NAME_4}">
<mx:Label text="ViewStack Content #4" />
</mx:HBox>
</mx:ViewStack>
<mx:Button label="change" click="onClick()" />
</mx:VBox>
</mx:Application>
Posted in <Flex> | No Comments »
Posted by admin on 22nd October 2008
Flash player prior to version 10 was unable to directly read and write data/files from and to the local drives. We could browse for files, upload/download them, but only by using server side script(we are talking about flex applications, not AIR ones). Adobe just made our life a little bit easier, by adding the load() and save() methods to the FileReference class.
Points to keep in mind:
- the location files are not exposed to ActionScript
- we can call the load() and save() APIs only on user action(such as a mouse click)
- The APIs are asynchronous (non-blocking)
You can read more about this on Mike Chambers blog, there are also sample applications to review.
Posted in <Flash>, <Flex> | No Comments »
Posted by admin on 22nd October 2008
Today I was trying to create a Flex application, that when loaded by the browser will go on full screen. After a few tentatives (that didn’t work of course) I searched the help and found this page about
Programming ActionScript 3.0 > Flash Player APIs > Flash Player Security > Full-screen mode security.
I will highlight the main features here:
- The ActionScript that initiates full-screen mode can be called only in response to a mouse event or keyboard event. If it is called in other situations, Flash Player throws an exception. In other words: bye bye full screen at startup
- Users cannot enter text in text input fields while in full-screen mode. All keyboard input and keyboard-related ActionScript is disabled while in full-screen mode, with the exception of the keyboard shortcuts (such as pressing the Esc key) that return the application to normal mode. This is not cool…Not at all, but I understand. Consider a page that renders a full screen flex window showing a standard Windows log in screen. How many will think that something weird has happened to Windows once again and enter the login credentials into the malicious window
- Full-screen mode is always permitted in the stand-alone player or in a projector file. OK, but who cares? I wanted to do full screen in THE BROWSER.
Posted in <Flex> | No Comments »
Posted by admin on 20th October 2008
SharedObject is very useful for storing data on the users local machine. However, if you try to store a custom class and read that data back, you will see that the class became an object and if you try to cast the object to your custom class it won’t work.
The solution for that issue is to put [RemoteClass] before your custom class declaration, like this:
package com.valueObjects{
[Bindable]
[RemoteClass]
public class SharedDataVO {
public var userName: String = '';
}
}
Now, when you write your custom class to the shared object and read it back, the class type will be SharedDataVO just as we expected it to be.
Posted in <Flex> | No Comments »
Posted by admin on 17th October 2008
Many times we need to use additional compiler settings when building our flex applications. Here is a list, of the options we can use with mxml:
-benchmark
-compiler.accessible
-compiler.actionscript-file-encoding
-compiler.allow-source-path-overlap
-compiler.as3
-compiler.context-root
-compiler.debug
-compiler.defaults-css-url
-compiler.doc
-compiler.es
-compiler.external-library-path [path-element] [...]
-compiler.fonts.languages.language-range
-compiler.fonts.local-fonts-snapshot
-compiler.fonts.managers [manager-class] [...]
-compiler.fonts.max-cached-fonts
-compiler.fonts.max-glyphs-per-face
-compiler.headless-server
-compiler.include-libraries [library] [...]
-compiler.incremental
-compiler.keep-all-type-selectors
-compiler.keep-generated-actionscript
-compiler.library-path [path-element] [...]
-compiler.locale
-compiler.namespaces.namespace
-compiler.optimize
-compiler.profile
-compiler.services
-compiler.show-actionscript-warnings
-compiler.show-binding-warnings
-compiler.show-deprecation-warnings
-compiler.source-path [path-element] [...]
-compiler.strict
-compiler.theme [filename] [...]
-compiler.use-resource-bundle-metadata
-compiler.verbose-stacktraces
-compiler.warn-warning_type
-compiler.warn-array-tostring-changes
-compiler.warn-assignment-within-conditional
-compiler.warn-bad-array-cast
-compiler.warn-bad-bool-assignment
-compiler.warn-bad-date-cast
-compiler.warn-bad-es3-type-method
-compiler.warn-bad-es3-type-prop
-compiler.warn-bad-nan-comparison
-compiler.warn-bad-null-assignment
-compiler.warn-bad-null-comparison
-compiler.warn-bad-undefined-comparison
-compiler.warn-boolean-constructor-with-no-args
-compiler.warn-changes-in-resolve
-compiler.warn-class-is-sealed
-compiler.warn-const-not-initialized
-compiler.warn-constructor-returns-value
-compiler.warn-deprecated-event-handler-error
-compiler.warn-deprecated-function-error
-compiler.warn-deprecated-property-error
-compiler.warn-duplicate-argument-names
-compiler.warn-duplicate-variable-def
-compiler.warn-for-var-in-changes
-compiler.warn-import-hides-class
-compiler.warn-instance-of-changes
-compiler.warn-internal-error
-compiler.warn-level-not-supported
-compiler.warn-missing-namespace-decl
-compiler.warn-negative-uint-literal
-compiler.warn-no-constructor
-compiler.warn-no-explicit-super-call-in-constructor
-compiler.warn-no-type-decl
-compiler.warn-number-from-string-changes
-compiler.warn-scoping-change-in-this
-compiler.warn-slow-text-field-addition
-compiler.warn-unlikely-function-value
-compiler.warn-xml-class-has-changed
-debug-password
-default-background-color
-default-frame-rate
-default-script-limits
-default-size
-dump-config
-externs [symbol] [...]
-file-specs [path-element] [...]
-frames.frame [label] [classname] [...]
-help [keyword] [...]
-includes [symbol] [...]
-lazy-init
-licenses.license
-link-report
-load-config
-load-externs
-metadata.contributor
-metadata.creator
-metadata.date
-metadata.description
-metadata.language
-metadata.localized-description
-metadata.localized-title
-metadata.publisher
-metadata.title
-output
-raw-metadata
-resource-bundle-list
-runtime-shared-libraries [url] [...]
-use-network
-version
-warnings
Posted in <Flex> | No Comments »
Posted by admin on 17th October 2008
Today, while working on one Flex application, I had to add a listener to the stage for FullScreen changes. I thought, this is a simple task, in my
<mx:Application added the creationComplete=”onCreationComplete()” , and defined that function on the Script section, like this:
private function onCreationComplete():void{
stage.addEventListener(FullScreenEvent.FULL_SCREEN, onFullScreenEvent);
}
It compiled without errors, but when running the application I received TypeError: Error #1009: Cannot access a property or method of a null object reference, on the line where I added the listener.
The solution for this is simple, it seems that on the creationComplete event the stage is null, so we need to add our code in the applicationComplete like this: <mx:Application applicationComplete=”onApplicationComplete()”>
and define our function as:
private function onApplicationComplete():void{
//add event listener for the full screen event(stage is null when onCreationComplete, that's why we add the listener here)
stage.addEventListener(FullScreenEvent.FULL_SCREEN, onFullScreenEvent);
}
Posted in <Flex> | No Comments »