Flex Pasta » Flex 3
Time travel between Flex, BlazeDS, and Java can be quite complicated to keep the three correctly in sync. Time travel, aka remote objects that carry date members, can mean different things to each piece of software. Java is very time zone aware, where as Flex is very time zone unaware. Since time in Java, BlazeDS, and Flex is defined in milliseconds since 1970, it can mean translation via BlazeDS can result in inconsistencies. How can this be?
Java
When it comes to time zones and daylight savings time, Java is very smart. It uses the Olson Database to determine how to translate a time in milliseconds since 1970 into an actual date/time based on the current timezone. The Olson Database knows when daylight savings time started and ended in each time zone each year. If you remember, prior to 2007, daylight savings time in the United States started the first weekend in April and ended the last weekend in October. But, it an effort to be more energy conscious, the government changed it to the second weekend of March through the first weekend in November. Java knows about daylight savings time and time zones as they existed in the past. Therefore, milliseconds since 1970 for a date of March 15th, 2006 in Java maybe different than on another platform.
BlazeDS
BlazeDS(and the Flex RPC library) translate time via AMF between Flex and Java. It knows nothing about time zones or daylight savings time. When sending a remote object that contains a date, it will be converted to date.getTime() - milliseconds since 1970. BlazeDS is always translating dates in the present and has no understanding of the client and server’s time awareness.
Flex
Flex only knows about daylight savings time now. Meaning, Flex will think March 15th, 2006 was during daylight savings time. But in 2006, daylight savings time didn’t start until April so Java will have a different answer than Flex to milliseconds since 1970? To be fair, it is not Flex or Flash that aren’t time zone savy. It is the user’s browser and computer that are ultimately at fault. The flash player will just pull the information from them. Imagine if a user enters a date/time today(during daylight savings time). At some point in the future, the government changes daylight savings time to start tomorrow. After the change occurs, the date the user entered will be correct in Java(because Java knows of daylight savings time in the past), but will be one hour off when displayed in Flex.
Creating an identical date/time object in both Flex and Java can cause different results for milliseconds since 1970. Take for example a user entering a birth date on a Flex form as March 15th, 2006 and another user entering a birth date as March 15th, 2009. The following screen shots show a simple Flex app with a date chooser and a label showing the time in milliseconds since 1970.
When the user selects March 15, 2009, the date is correctly translated to Java via BlazeDS as March 15th, 2009. Notice that Java says EDT(Eastern Daylight Time).
Now look at the same test for March 15, 2006.
Notice for the March 15th, 2006 date translation is incorrect. The date given to us via BlazeDS will actually be on March 14th at 11pm. Java correctly identifies the time zone EST(Eastern Standard Time). Java is correct. Back in 2006, March 15th was during eastern standard time. Because this date today is in eastern daylight time, Flex incorrectly reports milliseconds since 1970 to a number off by one hour.
Now the incorrect birth date is put in the database as March 14th!! Want to run a query to find all people born on March 15th, 2006? That could be a problem. There are several ways to solve this problem. One might be creating a JustADate class that has year, month, day fields on it so BlazeDS will send it without using getTime(). Another option might be sending date only fields as strings to avoid the getTime() translation. When working with dates in Flex, BlazeDS, and Java, be sure to consider time travel and its inconsistencies!
“Once confined to fantasy and science fiction, time travel is now simply an engineering problem.” -Michio Kaku
If you’ve dealt with item renderers in any kind of complexity, you’ve probably run into scroll bars gone wild. Problems usually start happening when you have a list based component that needs to scroll, and each item may have a variable row height. Painful symptoms of scroll bars gone wild include: text being cut off, scrolling becoming choppy, or lots of inner scroll bars appearing and disappearing. A really easy way to run into problems with item renderers is by using images that are loaded by a url at runtime. Take a look at the following simple example that uses mx:List to show a description next to a dynamic image. Try scrolling with the down arrows and scroll thumb to see the less than desirable results(note there are 4 items in the list).
There are many ways to tackle out of control item renderers. In this case, it’s a Repeater For the Win! Take a look at the identical application using an mx:Repeater tag instead of mx:List. The scrolling is smooth and the down arrow works!
The draw back to using the mx:Repeater tag is that there is no item recycling. Meaning, unlike using an item Render, which will be reused when I scroll, the mx:Repeater will draw everything at once. For small lists, using a repeater tag should be ok, but for large data sets, a repeater tag could cause memory problems. Also note, one other benefit to using the repeater tag in this instance is that the images are loading once. In the first example, the item renderers are being recycled as scrolling occurs, this means the images are reloaded everytime they appear on the screen.
It’s tax season here in the US until April 15th. I decided to get an early start. I opened up TurboTax(tax software). After entering some numbers, you will notice the little “Federal Refund” ticker at the top that keeps a running total of the money you will get, or owe, based on all the numbers entered. The refund ticker also has a cool animation on it when it goes up or down. I quickly got bored of doing my taxes and instead decided to write the little number changer component in Flex.
<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” layout=”vertical”>
<mx:Script>
<![CDATA[
[Bindable] private var currentNumber:int = 0;
private var difference:Number;
private function buttonClick():void
{
difference = numberInput.value - currentNumber;
timer.addEventListener(TimerEvent.TIMER, timerExecute);
doTimer();
}
private var timer:Timer = new Timer(1,0);
private function doTimer():void
{
if(currentNumber<numberInput.value && difference >0)
{
if(numberInput.value-currentNumber < difference/350)
{
currentNumber = numberInput.value;
}
else
{
currentNumber+=difference/350;
timer.start();
greenGlow.play();
}
}
else if(currentNumber>numberInput.value && difference <0)
{
if(currentNumber - numberInput.value < difference/-350)
{
currentNumber = numberInput.value;
}
else
{
currentNumber-=difference/-350;
timer.start();
redGlow.play();
}
}
else
{
timer.stop();
greenGlow.stop();
redGlow.stop();
}
setColor();
}
private function setColor():void
{
var newColor:String = currentNumber>=0?’green’:'red’;
if(currentNumber==0)
newColor = ‘black’;
numberLabel.setStyle(’color’, newColor);
}
private function timerExecute(event:TimerEvent):void
{
doTimer();
}
]]>
</mx:Script>
<mx:CurrencyFormatter id=”currencyFormatter” precision=”2″ useThousandsSeparator=”true”/>
<mx:Box id=”box” borderThickness=”1″ borderStyle=”solid” backgroundColor=”#FFFFFF” borderColor=”#000000″ dropShadowEnabled=”true” width=”200″ horizontalAlign=”right”>
<mx:Label id=”numberLabel” text=”{currencyFormatter.format(currentNumber)}” fontWeight=”bold” fontSize=”22″ creationComplete=”setColor()” fontFamily=”Courier New”/>
</mx:Box>
<mx:Glow color=”red” id=”redGlow” target=”{box}” duration=”1000″/>
<mx:Glow color=”green” id=”greenGlow” target=”{box}” duration=”1000″/>
<mx:Spacer height=”100″/>
<mx:NumericStepper maximum=”10000000″ id=”numberInput” value=”20000″ minimum=”-1000000″ stepSize=”1000″/>
<mx:Button click=”buttonClick()” label=”Render”/>
</mx:Application>
It has been about a year now since Adobe announced it was open sourcing the Flex SDK, BlazeDS, and the Flex Compiler. Today on my way home, I started thinking about improvements to the Flex Open Source Adobe that I would like to see in the future.
5. Upgrade LCDS/BlazeDS to Java 5.
I am not sure the reasoning for having BlazeDS written in Java 1.4. Most projects using Flex are going to use Java 1.5 since they are most likely newer software. If for whatever reason, BlazeDS to Java 5 is not viable, at least create a separate Java 5 project that extends the BlazeDS code base. This project could use features of Java 5 to give developers more tools. In particular, annotations with remote objects would be a huge advantage for developers. Bean property configuration, service method security, better enum handling, code generator support, etc would all be great.
4. Bring the Flex Compiler Source Code out from the shadows
After attending MAX last month, I heard little about improvements to the Flex Compiler for Gumbo. I guess the compiler isn’t the sexy part of Flex so maybe that is why. But the compiler is just as important as the Flex SDK itself, so I would love to understand how it works. I think the community would benefit with more exposure to the compiler code base.
3. Make it easier to set up the Flex SDK, BlazeDS, and the Flex Compiler for local builds
The most looked at code base of the three components is probably the Flex SDK, just because we can hit F3 in eclipse and go look at the source code. However, how many people out there(other than Adobe employees) know how to check out the source code for the Flex SDK, BlazeDS, and the Flex Compiler and then be able to make changes to the code? I have been able to do it for the Flex SDK and BlazeDS, but it took some time(I also don’t think my config was ideal). I spent a couple of hours trying to figure out the Flex Compiler with no luck. I am hopefull for a little documentation for those of us out on an island trying to set it up.
2. Improve the ability to run different versions of the Flex SDK
If you go out and download Flex Eclipse plug-in site today, you will probably get Flex version 3.2. The rest of the development team might be using another version; say version 3.0 on the project. Figuring it might be a good idea to have the same version of Flex as your coworkers, you visit opensource.adobe.com to download version 3.0. The nice interface in FlexBuilder lets you have multiple Flex SDK’s installed and you can easily flip the compiler between different versions of the SDK. One problem: Charts. When you download the plugin, you get the charts bundled with the source code, but when you download releases from the open source page, charts are left off(I’m not sure the reason). This means a project using charts won’t compile for you without some hacking to get it to work.
1. Avoid using mx_internal/private in the Flex SDK
There are important instances where the private keyword is usefull(when I don’t want a subclass to override it or even be able to call it). However, and I admit to doing this as well, we tend to use the private keyword by default when we don’t want a method to be public. The protected keyword would be a much better option for the majority of methods in the Flex SDK. I have found it difficult at times to extend Flex components and even BlazeDS code because the methods are private or mx_internal. Maybe it was the intent of the authors to keep these methods private to avoid future upgrade hassles, but it can be problamtic to extend them. My latest example of one such problem involves creating a ColumnChart. I created the chart and had a ColumnSeries. The chart was simple and I set the properties labelAlign=”center” labelPosition=”outside”. I was wanting to center the labels at the top of the bars on the outside.
As you can see in the picture, the labels are left aligned. The as-doc states that labels on the outside can only be left aligned. I want to try and extend column series to get the labels in the middle. I find the method:
private function renderExternalLabels
I can’t extend it since it’s private. Ok, so I find where renderExternalLabels method is called.
mx_internal function updateLabels()
This goes on for four or five methods before there is one that can be extended. The point is that marking methods protected more aggressively can help everyone out who is trying to extend these components.
Those are my top five wishes for Flex Open Source. What are your wishes?
There is no compile or run time error, but executing the following code will not work. I knew this going in but wanted to try it just to see what happened:
<mx:TabNavigator>
<mx:Text text=”Tab 1“/>
</mx:TabNavigator>
The reason it doesn’t work is because a tab navigator requires its children to be of type container. There is a simple fix, one that requires more work
<mx:TabNavigator>
<mx:Box label=”Tab 1“>
<mx:Text text=”Everything else“/>
</mx:Box>
</mx:TabNavigator>
I don’t want to wrap a box around all ten of my tabs! One solution is to do the following:
- Create a new Actionscript class called BoxText.as which extends Box.
- Make a bindable property text:String in the Box.
- Add an event listener for FlexEvent.CREATION_COMPLETE.
- When creation complete occurs, simply add the text to the box.
Here is the output for BoxText.as:
package
{
import mx.containers.Box;
import mx.controls.Text;
import mx.events.FlexEvent;
public class BoxText extends Box
{
public function BoxText()
{
super();
this.addEventListener(FlexEvent.CREATION_COMPLETE, creationComplete);
}
private function creationComplete(event:FlexEvent):void
{
_text.text = text;
this.addChild(_text);
}
[Bindable]
public var text:String;
public var _text:Text;
}
}
Now I just use my component in the TabNavigator. It saves time and clutter!
<mx:TabNavigator>
<local:BoxText label=”Booyah” text=”My Text to show in the Tab“/>
</mx:TabNavigator>




