Monday, January 31, 2011

Localizing Flex application preloader

Recently there was a request to localize labels on preloader of Flex application, such as "Initializing" and "Loading":



First of all I've provided modification for HTMl content page to path needed parameters with "FlashWars":

AC_FL_RunContent(
"src", "${swf}",
"width", "${width}",
"height", "${height}",
"align", "middle",
"id", "${application}",
"quality", "high",
"bgcolor", "${bgcolor}",
"name", "${application}",
"wmode", "transparent",
"FlashVars", "initLabel=Init Some Application&downloadLabel=Downloading Some Application",
"allowScriptAccess","sameDomain",
"type", "application/x-shockwave-flash",
"pluginspage", "http://www.adobe.com/go/getflashplayer",
"allowFullScreen", "true"
);


Populating "FlashVars" can be done dynamically for example if you have JSP page. In such case you can access needed bundle and get corresponding labels:

"FlashVars", "initLabel=<%= localizedInitLbl%>&downloadLabel=<%= localizedDownloadLbl%>"

Next step is to create custom preloader for your application and use it. Custom preloader is set to Flex application in next way:

<:mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
preloader="com.somecompany.preloader.DownloadProgressBarCustom">


Code of preloader is next:

package com.somecompany.preloader
{
import flash.events.Event;
import flash.geom.Rectangle;

import mx.preloaders.DownloadProgressBar;

public class DownloadProgressBarCustom extends DownloadProgressBar
{
public function DownloadProgressBarCustom()
{
super();
// Clear the initialization label till translation is received.
initializingLabel = "";
// Clear download label till translation is received.
downloadingLabel = "";
// Set the minimum display time to 5 seconds (for testing only).
//MINIMUM_DISPLAY_TIME = 5000;

this.addEventListener(Event.ADDED_TO_STAGE, addToStageHandler);
}

// Need to get parameters for label translation.
private function addToStageHandler(e:Event):void
{
//more safe to remove EventListener than using weak reference
this.removeEventListener(Event.ADDED_TO_STAGE, addToStageHandler);

var params:Object = this.stage.loaderInfo.parameters;
initializingLabel = params.hasOwnProperty("initLabel") ? params.initLabel : "Initializing";
downloadingLabel = params.hasOwnProperty("downloadLabel") ? params.downloadLabel : "Loading";

}

// More space for text.
override protected function get labelRect():Rectangle
{
return new Rectangle(5, 17, 170, 16);
}
}
}


Main idea is listen to "Added To Stage" event to have access to "FlashVars" with help of loaderInfo instance.

As result, you will have custom message on preloader:

Flex: White color issue with "wmode" set to "transparent" under 16-bit color depth

Recently I've faced with pretty strange issue in Flash Player. Our application written in Flex was using "wmode" parameter set to "transparent" in params for embeding flash to HTML:

AC_FL_RunContent(
"src", "${swf}",
"width", "${width}",
"height", "${height}",
"align", "middle",
"id", "${application}",
"quality", "high",
"bgcolor", "${bgcolor}",
"name", "${application}",
"allowScriptAccess","sameDomain",
"wmode","transparent",
"type", "application/x-shockwave-flash",
"pluginspage", "http://www.adobe.com/go/getflashplayer"
);


Issue was related to rendering labels with white color when user had set up 16-bit color depth:


Example of code in Flex is pretty simple:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">

<mx:VBox>
<mx:Label text="Some Label" color="#FFFFFF" fontFamily="Arial" fontSize="14" fontWeight="bold" />
<mx:Text text="Some Text" color="#FFFFFF" fontFamily="Arial" fontSize="14" fontWeight="bold" />

</mx:VBox>

</mx:Application>


After some investigation, solution was found - I've used "cacheAsBitmap" property set to "true" for text and label. After that issue vanished:

<mx:Label text="Some Label" cacheAsBitmap="true" color="#FFFFFF" fontFamily="Arial" fontSize="14" fontWeight="bold" />
<mx:Text text="Some Text" cacheAsBitmap="true" color="#FFFFFF" fontFamily="Arial" fontSize="14" fontWeight="bold" />


As result text and label was rendered correctly:

Wednesday, July 21, 2010

Flex: AdvancedDataGrid - Memory Leak

There is known memory leak issue with AdvancedDataGrid. It happens, when we have instance of AdvancedDataGrid loaded with some data and want to update it with newly received data and recreating columns in it. Found workaround is next - create new class, which extends and use it in your code. Add next method to it:

public function clearRenderers():void {
   this.itemRendererToFactoryMap = new Dictionary(false);
   this.visibleData = new Object();
   this.listData = null;
}


Call clearRenderers() method before setting new columns. It will fix memory leak completely.

Flex: Scrolling issue with VBox content

Recently I've faced with strange issue for apps developed in Flex 3.3. I had VBox container, which is populated with new components after clicking on corresponding "Add Item" button. This VBox has fixed size and disabled horizontal scrolling:

mx:VBox height="440" width="900" verticalScrollPolicy="auto" horizontalScrollPolicy="off" ...

Issue was next - when user has added a lot of items, vertical scroll bar appears and after scrolling top and down for few times UI garbage is shown instead of properly rendered items that were added. I mean that all those items were only partially visible and messed up with each other.

Setting cacheAsBitmap="false" and cachePolicy="off" didn't helped (as we know caching as bitmap in Flex is buggy). After small investigation I got to mx.core.Container.updateDisplayList method:


override protected function updateDisplayList(unscaledWidth:Number,
unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);

..............

var backgroundColor:Object = enabled ?
null :
getStyle("backgroundDisabledColor");

if (backgroundColor === null || isNaN(Number(backgroundColor)))
backgroundColor = getStyle("backgroundColor");

..............


contentPane.cacheAsBitmap = (backgroundColor != null);

}

After looking at the last command in this method I got back to my code with VBox and found next style property - backgroundColor="0xffffff". After removing it, scrolling issue vanished.

If there is a need to set background color for your VBox and get rid of this issue, you can play with backgroundAlpha style property - refer mx.core.Container.updateDisplayList method for details.

Wednesday, November 25, 2009

Firefox - Dynamically loaded IFRAME breaks page styling

We had a button on page, which provided possibility to load IFRAME dynamically with help of JavaScript functions. It was working ok in IE, but in Firefox for 3.0.15 version and some specific machines were problems. First of text labels for all buttons were shifted, table styling was broken, text was shifted too. Even page itself was looking zoomed out, because one additional horizontal scrolling bar appeared.

After making Zoom In and Zoom Out, everything was looking ok. First of all I tried to uninstall all plugins from Firefox and clear all private data. But it didn't help.

After that when page was loaded again and issue happened, I pressed Ctrl + 0 (Zero) combination to reset text to normal size. Issue was fixed and didn't happen again after reloading page and restarting Firefox.

RoboHelp - Flash content isn't rendered under Mac OS

This bug was really interesting, but I've spent some time to fix it.

There was a generated help by Adobe RoboHelp 7.0.3 version. Everything was working fine under Windows OS, but not under Mac OS. Flash part of it wasn't rendered at all (it was rendering approximately one time per 50-70 launches).

It was pretty confusing, so I started analyzing JavaScript files generated by RoboHelp. I found out that JavaScript functions, which had to be called when Flash objects are loaded, aren't called at all. So I decided to investigate way of communication between Flash and JS in RoboHelp.

After decompiling .swf files of RoboHelp I saw that JavaScript is called from Flash with help of instances of LocalConnection class. So I started looking for known issues in Flash for this class under Mac OS and found this post - http://forums.adobe.com/thread/495868.

So it's became clear that newest version of Flash player should be installed - 10.1 http://labs.adobe.com/downloads/flashplayer10.html.

Flash content isn't clickable over table in Firefox

This issue was related to the Flash object, which was placed on the top of page. After clicking on menu button, new options were expanded and rendered over table. But these new buttons weren't clickable in Firefox.

After looking for known issues in Firefox, I've found solution. Main cause of it was that table, over which expanded Flash content was rendered, had "overflow" attribute set to "auto" value. But if change it to "hidden", everything will be ok.

So I've added small JavaScript function, which is called when Flash menu is expanded and changes "overflow" table attribute to "hidden". After Flash menu is collapsed, same JavaScript sets "auto" value back for table.