W-Arial Text Cut Off Issue in Flex

This is the first post of my new blogging  journey on Flex .  Why I love Flex ? [ more on this , in About me ].

Well coming back to the problem,

this issue can be seen more specifically when one uses , Arial Font with size=12.  Now the Text control of flex, or TextField of the Flash package, would clip off some of the area of the left edge of the string. When used with single line, or multiline text, issue remains the same.

Resolution :

The solution is to use the TextFormat to set the left margin to 0.6 . This workaround seems to work. Although there is a very good post for this issue, http://bryanlangdon.com/blog/2008/12/15/w-arial-text-cut-off-fix-for-as2-and-as3/

But this solution is for Flash TextField.

So , if someone uses this approach in Flex Text controls, then we don’t have setTextFormat property, so  if one doesn’t uses the TextField, then the problem is still there.

So I have created the custom Text Control, which extends the default Text Class, and overrides the commitProperties function to set the textFormat() before the internal text written to Text control is displayed back to user. This works cause, internally the Text control, uses the TextField as the placeholder for the text written it.

var tf:TextFormat = new TextFormat();
tf.leftMargin = .6;
getTextField().setTextFormat(tf);

Use this control the same way as normal Text control,  but with the  issue resolved.  There  may be other ways, to get this done, like CSSStyleDeclaration etc., but I haven’t given that approach a try. This works for me.  If someone has any ideas on that approach , please do share.

But till then , try the source code below. See the snapshot below of how the problem/solution looks like.


I have pasted the source here, my as file  [myText.as ]  — custom Text Control

myText.as

package
{
import flash.text.TextFormat;
import mx.core.mx_internal;
import mx.controls.Text;
use namespace mx_internal;

public class myText extends Text
{
private var widthChanged:Boolean = true;
public function myText()
{
super();
}

override protected function commitProperties():void
{
super.commitProperties();
// if explicitWidth or percentWidth changed, we want to set
// wordWrap appropriately before measuring()

var tf:TextFormat = new TextFormat();
tf.leftMargin = .6;
getTextField().setTextFormat(tf);

if (widthChanged)
{
textField.wordWrap = !isNaN(percentWidth) || !isNaN(explicitWidth);
widthChanged = false;
}
}

}
}

main.mxml

<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml&#8221; layout=”absolute” xmlns:local=”*”>
<mx:Script>
<![CDATA[
[Bindable]
var string:String = “W — see the left edge carefully . “;

]]>
</mx:Script>

<mx:Panel width=”100%”  height=”50%”>

<mx:HBox x=”18″ y=”120″>
<mx:Label x=”31″ y=”48″ text=”My Custom Text control”/>
<local:myText  fontFamily=”Arial” fontWeight=”bold” fontSize=”12″ x=”176″ y=”46″ text=”{string}”   width=”466″/>
</mx:HBox>

<mx:HBox  x=”10″ y=”40″>
<mx:Label x=”10″ y=”105″ text=”Default Flex Text Control”/>
<mx:Text   fontFamily=”Arial” fontWeight=”bold” fontSize=”12″ x=”155″ y=”105″ text=”{string}”   width=”466″/>
</mx:HBox>
</mx:Panel>
</mx:Application>

Cheers, and Happy Flexing  🙂

AIR Uninstall Error – keeps getting en error : Sorry, an error has occured. An error occured while uninstaling Adobe AIR. Uninstalling may not be allowed by admin. Please contact Admin.

This is the blog post describing , when one is stuck in an infinite loop while installing /uninstalling AIR.  Many people have faced this issue, and because of the way AIR installation is done, if it fails then the only way is to clean uninstall and then try the installation.

So the way to uninstall is :

First Option :

1) Make a shortcut of the Adobe AIR installer executable.
2) Right-click the executable, go to properties, click on the “shortcut” tab.
3) In the “Target” field, add “-uninstall” (minus quotes) to the end of the existing text.
4) Run the file, and Adobe AIR will truly be uninstalled this time.
5) Now run the original installer file to install the program.

This usually solves the problem , and clean uninstalls. But there may be scenarios when you try this , there is another error.

Uninstalling Adobe AIR (all versions)

failed (consult log)

In this case , we need to  look into certain issues :

  • the proper location of the log file; [Normally this is not easily found , sigh ]
  • the meaning of the error code in the log; [This is not necessarilyAIR related, but windows error code , so please read this carefully ]
  • how to uninstall programs — using Windows Installer Cleanup Utility when other uninstallers fail. [including AIR itself or various AIR apps].

AIR logs [in AIR 2] are to be found at location…

C:\Documents and Settings\<username>\Local Settings\Application Data\Adobe\AIR\logs\Install.log

This will give you the log and hopefully the error code [for the reason why its not uninstalling].

For example, you might see something like this ,

[2010-06-03:16:56:01] error during install: [ErrorEvent type=”error” bubbles=false cancelable=false eventPhase=2 text=”1612” errorID=0]

Here “1612” is the error code for Windows , which means ,

The installation source for this product is not available. Verify that the source exists and that you can access it

In this case, there is no option but to clean the uninstaller as the msi used to install this software in the first place is not to be found.

So run the “Windows Installer Cleanup Utility“. It should display AIR as being installed, and let you select it for cleanup.  Behind the scenes it will clean up the  registry.

This will resolve the issue , and you will be able to uninstall the AIR properly and then move on installing again.

Hope this helps somebody 🙂 .

Cheers 🙂 🙂 🙂

Convert Flex DataGrid to Excel

To convert the Flex DataGrid into the Excel sheet, we have to convert DataGrid to htmlTable , to send over to some server-side script from Flex application.

The output shows something like this :

Although there are many versions out there , for this problem, One thing to mention, that now when we try the htmlTable in Flex SDK 3.2, and Coldfusion 8 [as the Server Side technology], I couldn’t get the existing solutions to work, cause I was not passing the htmlTable correctly from the Flex app, and hence the Server Side, i.e, CF received an invalid POST variable, and hence Corrupted Excel file.

So , there are some changes, the most narrowed down simple code… [of course can be formatted to create more complex Excel files]

Flex Code ::

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

 import mx.core.UIComponent;
 import mx.core.Container;
 import mx.events.ItemClickEvent;
 import mx.utils.ObjectProxy;
 import flash.errors.*;
 import flash.events.*;
 import flash.external.*;
 import flash.net.URLLoader;
 import flash.net.URLVariables;
 import flash.net.URLRequest;

 //The location of the excel export file
 public var urlExcelExport:String = "http://localhost:8500//flex2excel.cfm";

 private function convertToHTML(myDG:DataGrid):String
 {
 var font = myDG.getStyle('fontFamily');
 var size = myDG.getStyle('fontSize');
 var str:String = '<html><body><table width="'+myDG.width+'"><thead><tr width="'+
 myDG.width+'">';
 for(var i=0;i<myDG.columns.length;i++)
 {
 var style = 'style="font-family:'+font+';font-size:'+size+'pt;"';

 if(myDG.columns[i].headerText != undefined)
 {
 str+="<th "+style+">"+myDG.columns[i].headerText+"</th>";
 }
 else
 {
 str+= "<th "+style+">"+myDG.columns[i].columnName+"</th>";
 }
 }

 str += "</tr></thead><tbody>";

 //Loop through the records in the dataprovider to populate the htmlTable.
 for(var j:int =0;j<myDG.dataProvider.length;j++)
 {
 str+="<tr width=\""+Math.ceil(myDG.width)+"\">";

 for(var k:int=0; k < myDG.columns.length; k++)
 {
 if(myDG.dataProvider.getItemAt(j) != undefined && myDG.dataProvider.getItemAt(j) != null)
 {
 if(myDG.columns[k].labelFunction != undefined)
 {
 str += "<td width=\""+Math.ceil(myDG.columns[k].width)+"\" "+style+">"+myDG.columns[k].labelFunction(myDG.dataProvider.getItemAt(j),myDG.columns[k].dataField)+"</td>";
 }
 else
 {
 str += "<td width=\""+Math.ceil(myDG.columns[k].width)+"\" "+style+">"+myDG.dataProvider.getItemAt(j)[myDG.columns[k].dataField]+"</td>";
 }
 }
 }
 str += "</tr>";
 }

 str+="</tbody></table></body></html>";

 return str;

 }

 private function loadmyDGInExcel():void
 {
 var variables:URLVariables = new URLVariables();
 variables.htmlTable    = convertToHTML(mymyDG);

 var url:URLRequest = new URLRequest(urlExcelExport);
 url.data = variables;
 url.method = URLRequestMethod.POST; //It has to be POST
 navigateToURL(url,"_self");
 }  

 ]]>
</mx:Script> 

 <mx:DataGrid id="mymyDG" x="237" y="145" width="466">
 <mx:ArrayCollection>
 <mx:Object>
 <mx:Artist>Pavement</mx:Artist>
 <mx:Price>11.99</mx:Price>
 <mx:Album>Slanted and Enchanted</mx:Album>
 </mx:Object>
 <mx:Object>
 <mx:Artist>Pavement</mx:Artist>
 <mx:Album>Brighten the Corners</mx:Album>
 <mx:Price>11.99</mx:Price>
 </mx:Object>
 </mx:ArrayCollection>
 </mx:DataGrid>
 <mx:Button x="291" y="89" label="Convert DataGrid to Excel" click="loadmyDGInExcel()"/>
</mx:Application>

ColdFusion Code  [flex2excel.cfm] ::

<cfcontent type="application/msexcel">
<cfheader name="Content-Disposition" value="filename=convertedExcel.xls">
<cfoutput>
#url.htmlTable#
</cfoutput>

So ideally, I just placed the script in the ColdFusion’s webroot, and run the flex app .Of course, ColdFusion should be running.  This should give you, atleast the bare-bone Excel file, with which we can play with.

Please feel free to update /add features to this code.  Cheers, and happy flexing 🙂