Forcing ComboBox to use htmlText

January 26, 2009

If your datasource values are in html format (I use <b></b> frequently to provide simple formatting and highlighting), you can simply force the textInput control that handles the display of the selected item text to use its htmlText field.

override protected function updateDisplayList(w:Number, h:Number):void
{
     super.updateDisplayList(w, unscaledHeight);
     // force use of htmlText
     textInput.htmlText = selectedLabel;
}

Not a completely robust solution, but it works nicely for me.  Occasionally I’ll use this with a custom list item renderer that does the same thing.


Simple Flex Number Formatting

September 4, 2008

I’m sure this is something that most Flex developers know all about, but I was (as usual) going down the wrong rabbit hole (NumberFormatter) before I discovered NumberBase.

What I wanted was to get a number formatted like “x,xxx.xx”. I want two decimal points at all times, even when they would be zero (eg. 1,234.00).

As I mentioned, I found NumberBase, which has all sorts of cool number formatting and parsing functions.

NumberBase.formatThousands() provides the commas for the thousands, and I’m using NumberBase.formatPrecision() to add the decimal points:

var b:NumberBase = new NumberBase();
return b.formatPrecision(b.formatThousands(team.pointsTotal.toString()), 2);

I would imagine that this tip applies best to places where you are formatting numbers in ActionScript (as opposed to MXML)


Flex Builder: An internal build error has occurred

July 16, 2008

So this error caused me some wasted time yesterday. I was happily coding away, most likely listening to some old school gangsta rap (cause I keeps it real), when this uninformative error stopped me in my tracks.

“An internal build error has occurred. Right-click for more information”

So I decided to play along. I right-clicked and selected “More Information” from the context menu. This opened up a web page describing how to get more information about Flex Builder errors.

Here’s where I made my mistake. I decided to read the top portion of that page and followed the instructions to view the specific error in the Flex Builder logs. I chased the error down that particular rabbit hole for quite some time.

What I should have done was noticed the little “Common Errors” section talking about ASC-2839.

Evidently there’s a Flex Builder bug that throws this wonderful error when you have an empty switch statement. Of course, that’s exactly what I had.

switch(event.kind)
{
}

So kids, don’t do what Donny Don’t does. Had I read the entire “More Information” page before plowing headlong down the first path presented, I would have saved quite a bit of time.


Flex Binding Chains

June 20, 2008

I recently had an issue where I could not get binding in one of my custom components to work. I was simply testing some things out and has a label tag bound to the length property on one of my data model objects. The problem was that the text was not being updated.

< mx:Label text='{obj.anotherObject.yetAnotherObject.length}' />

I initially thought that it might be due to the fact that this object was inherited and the bindable stuff was in the parent class, but it didn’t change when I moved the stuff into the class itself. Next up, blame it on the fact that it was a custom binding job with a read only property:

[Bindable("lengthChanged")]
public function get length():int
{
     return _length;
}

private function addObject(obj:Object, id:String):void
{
     _objects[id] = obj;
     _length++;
     dispatchEvent(new Event("lengthChanged"));
}

(Or something like that, the code has since changed).

This too turned out to be not the case. I changed the property to be a simple public variable on a [Bindable] class. No joy.

I finally figured out that I had to cast the second to last value in the property chain to its proper type. This allowed the compiler to pick up the proper events and add the proper event listeners (or whatever other data binding voodoo that it does).

< mx:Label text='{YetAnotherObjectType(obj.anotherObject.yetAnotherObject).length}' />

Works like a charm.


Controlling Flex swf Size via Judicious Font Embedding

May 12, 2008

Embedding fonts in your application can quickly cause your swf to balloon in size.  When it simply cannot be avoided, you can try to limit the damage by only embedding the glyphs (characters) that you plan on actually displaying in your application.

For example, in my current application, we needed a countdown clock.  The designers were kind enough to send me a cool scoreboard font, and I embedded it in the app.

@font-face {
src:url("../fonts/scoreboard.ttf");
fontFamily: scoreboard;
fontWeight: normal;
unicodeRange: U+0030-U+003A;
}

By simply adding that unicodeRange value, I was able to decrease the size of my compile swf by 24k. Not the largest of differences, but when you are embedding multiple fonts, the differences can add up fairly quickly.

What happened there? Well, we told the Flex compiler to only include the glyphs between 0030 and 003A. 0030 – 0039 are the digits 0-9 while, luckily for us, 003A is the colon character. Those are the only glyphs that we need for our ticker.

You can find complete lists of unicode codes at the Unicode web site.  As well, Adobe livedocs has an article with a few more useful ranges listed and more information on unicodeRange.


Adobe’s new Flash socket policy rules

May 7, 2008

With the release of Flash Player 9,0,124, Adobe has decided to change the way that socket policy files are handled. They have put together a 7 page article that gives an overview of the issue, but does not really provide enough specific information to let you solve the problem.

The product on which I am currently working uses a socket server on the back end. The client is in constant communication with this server (we also use a crossdomain.xml to allow us to access web services, but that stuff hasn’t changed).

Prior to the latest Flash player, we could simply serve a crossdomain.xml via a web server on port 80 and that would allow the client to connect on the socket that we specified. As of the upgrade, this no longer works.

After reading through the limited info that we could find about this upgrade, we finally figured out what our problem was; in order for a socket policy file to work, it must be served via a socket server (as opposed to an HTTP server). If a policy file is served via HTTP, it only works to allow HTTP requests (like HTTPService).

There was repeated mention of a policy socket server in the Adobe article, but there were no concrete examples. So one of our backend types (thanks Dave) whipped one up. It works like a charm. Basically, this server spews out the XML content of a socket policy file (think crossdomain.xml) whenever a client connects to it.

I’m using Security.loadPolicyFile('xmlsocket://' + serverName + ':' + socketPolicyPort); to load the policy info in my client. This is required because we are not using the Adobe “standard” of serving these policies on port 843 which would allow the client to automatically load the policy without explicit code in the client.

The contents of the policy data served looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<cross-domain-policy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.adobe.com/xml/schemas/PolicyFileSocket.xsd">
<allow-access-from domain="[redacted]" to-ports="[redacted]" secure="false"/>
</cross-domain-policy>

The allow-access-from line is where you make your money. The from attribute specifies that this line applies to swfs served from these locations (*.yourdomain.com for example). The to-ports attribute lists the port(s) on this server that you will allow access to. You can specify “7400″, “7500, 7502″ or “7600-7610″. You can even get crazy and specify “7700, 7702, 7800-7820″. I’m pretty sure the secure attribute is only used for HTTP policy files, but we still have it there because it makes us happy (and because we totally cut and pasted this from our old HTTP crossdomain.xml).

Hope this helps.


Follow

Get every new post delivered to your Inbox.