Tuesday, December 23, 2008

Some objective comparison of Adobe Flex and Microsoft Silverlight

In the past I've read a number of posts comparing Silverlight to Flex. Often the authors remain very vague on why Flex is better than Silverlight. We all know by now that the Silverlight plug-in isn't near the installed base of the Flash player but there's more than that. Therefore I think it's about time to give an overview of my recent experience.

I've been developing a proof of concept application in Silverlight after having developed the exact same proof of concept application in Flex. Just to be clear: I have much more experience with Flex than Silverlight but I'm pretty sure that the information below is based on facts, not fud.

1. Binding - Both technologies support binding but binding in Silverlight is way more cumbersome. First of all you need a special hack (using StaticResource) to bind UI components together. Even worse is the fact that you need to dispatch property changed events yourself (in Flex you simply specify the [Bindable] attribute on class and/or property level). A direct binding to an expression is also not an option in Silverlight. The fact that there's 2 way binding in Silverlight is an advantage for Silverlight because the current version of Flex is limited to 1 way binding (the upcoming release of Flex has 2 way binding).

2. Data communications - In Silverlight you're more or less stuck with SOAP and JSON for the time being (you could consider using WebOrb or FluorineFx - this gives Silverlight AMF support).

3. Layouting - Thank God there's Flex. Need to layout a data entry form? In Flex you can use Form and FormItem. In Silverlight you need to use Grid, RowDefinition and ColumnDefinition. Not too bad if you didn't have to specify Column and Row IDs because what do you need to do when you need to insert a line in your form... right... renumber everything. There are also no 'right' and 'bottom' properties in Silverlight - pretty annoying.

4. Exception handling - This is a 'bad in both cases' topic. In Flex there's still no global exception handler. Silverlight has one but for some strange reason the screen goes blank after certain exceptions. In other words: there's global exception handler support in Silverlight but it doesn't work...

5. Code behind - To me it's not essential but the fact that there's no out of the box support for code behind in Flex is a pitty. The fact that there's no out of the box WYSIWYG design support in Visual Studio 2008 is probably much more problematic for developers starting with Silverlight (or do you really expect them to constantly switch between slow blend and quick visual studio???).

6. Multi-language - I haven't completely figured out the multi-language support in Silverlight but it's already clear to me that it's way easier to implement in Flex. Just to be clear: the internationalization in Flex is also far from perfect. You need to take care of date formats, decimal and thousands separator support yourself because there's no application global setting in Flex (which is problematic when using validators and binding).

7. Validation - although not perfect in Flex (do they really think all telephone numbers are formatted the US way...), the support in Silverlight is simply absent. You will need to develop validators and the nice red "error tips" yourself.

8. Generics and LINQ - currently there's no support for generics in Flex (actually Actionscript).

What's even worse: there's no LINQ (or something similar) in Actionscript. Silverlight comes with LINQ and that is definitely an advantage (you can't use it for database querying however). Support for partial classes and extension methods is another advantage of Silverlight over Flex. It's clear that we're in need of Actionscript 4 (even if that results in non-compliance with Ecmascript).

9. Components - The Silverlight component set is smaller than the Flex component set (eg. a menu bar component is missing). This might change quicky however. There are already more 3rd party component development companies working on Silverlight controls than companies working on Flex controls.

10. Browser compatibility - Although there are some issues with Flash player running in Google Chrome - the situation is much better compared to Silverlight. That one just doesn't work in Google Chrome.

I'll probably discover more differences during the coming weeks. If so I'll post a new overview over here.

Sunday, December 14, 2008

Flip book using the nice component built by Ruben Swieringa

I've created a mini-site for a family member using the flip book component built by Ruben Swieringa:

http://klepsydra.vdeprojects.com.

What do you think? Would it make sense to build a Flex-based CMS solution for creating this type of projects? Do you think there's a demand for a CMS to build this type of mini-sites?

Tuesday, December 2, 2008

Why is it called Flash Catalyst???

Why are the project names always better than the names the marketing department can come up with???? Thermo is now called "Flash Catalyst". Can someone explain to me why "Flash" had to be added to the name? "Flash Catalyst" imports Photoshop, Fireworks and Illustrator files and 'converts' them to Flex projects. I don't see any "Flash" in this... Why not simply call it "Adobe Catalyst" (or Ca in short)? My guess is that we'll end up in a similar naming soup like we had with the data services thing. That one has been renamed in the past as well (and I hope it will be renamed once more because the current situation is also far from logical). My 2 cents of course :)

Sunday, November 16, 2008

Focus in all cases

Have you also noticed that Flex draws a focus border around its components when you give them focus using the keyboard (by using the tab button)?

Great but why is the focus border not drawn when using the mouse to give a component the focus?

The solution is simple: extend the existing components and force the border drawing yourself:

<mx:CheckBox
      xmlns:mx="http://www.adobe.com/2006/mxml"
      focusIn="onFocusIn()">
<mx:Script>
//
// Support to draw the focus border on focusIn
//
private function onFocusIn(): void
{
      this.drawFocus(true);
}
</mx:Script>
</mx:CheckBox>

Thursday, November 13, 2008

Discount code for Adobe Max in Milan

It seems that those who haven't registered yet for Adobe Max can get in for less than those who registered a month ago. Interested in knowing more? Just contact me.

Saturday, November 8, 2008

"Classes must not be nested" error

If you ever come across the "classes must not be nested" error (and/or the "internal build" error) then you're in trouble :) There are different possible causes for these errors. In my case it was because I was referring to a none existing component from within an itemRenderer. A good list with a number of potential causes can be found on http://rjowen.wordpress.com/2007/06/21/internal-build-error-or-classes-must-not-be-nested-error/.

Saturday, September 27, 2008

FileReference events not firing?

If the UPLOAD_COMPLETE_DATA event (or any other FileUpload related event) isn't fired after a succesful upload then you need to check whether your page returns something. It's enough that it just returns for example 'OK' but it at least has to return something.

Tuesday, August 5, 2008

Certified Adobe Flex Developer

I've waited and waited but it seems that the Adobe Flex 3 certification exam won't come before the release of Adobe Flex 4... Therefore I finally decided to do the Adobe Flex 2 certification and guess what: I passed :) It was a nice bunch of questions, some on UI, some on application design (even some UML) and some on data services. Most of them were 'practical' question but of course some are less 'obvious'.

Wednesday, June 18, 2008

Where to put your removeEventListeners?

Everyone tells you to make sure to execute a removeEventListener for each addEventListener but where do you put this code? Most people put their addEventListeners in the creationComplete event but there's no destructionComplete event...

There are 2 options:
  • Or you don't use removeEventListener and make sure that you use a weak reference when doing addEventListener (setting the 5th parameter of addEventListener to true)
  • Or you attach event listeners in the "addedToStage" event and you remove them again in the "removedFromStage" event

Why Adobe didn't set the 'weak reference' parameter by default to 'true' is unclear to me. The current situation is probably one of the major causes of memory leaks in Flex applications...

Degrafa component not showing up?

There seems to be some problem when building a Degrafa component in MXML. It seems that using "Surface" as the outer container results in an invisible component. The workaround is simple: put a Canvas around it but don't ask me why :)

Tuesday, May 27, 2008

Dynamic (Advanced)DataGrid columns

Trying to add columns dynamically to your DataGrid or AdvancedDataGrid and having trouble with specifically setting the width of a column?

Try the following:

var cols: Array = datagrid.columns;
cols.push(newColumn);
datagrid.columns = cols;
// The following line is very important
// (otherwise the grid won't be aware of the new columns yet)
datagrid.validateNow();
// Force the width of a specific column
cols[0].width = 40;

Thursday, May 15, 2008

Reducing the space between the legend marker and the legend label

If you ever try to reduce the space between the legend markers and the legend labels:

LegendItem
{
horizontalGap: 0;
verticalGap: 0;
}

Monday, April 21, 2008

Deep object compare

Ever wanted to check in Flex whether all the public members of an object are the same? You can use the ObjectToString method in that case:

public class SerializeUtil
{
public static function ObjectToString(object: *): String
{
var ba: ByteArray = new ByteArray();
ba.writeObject(object);
return ba.toString();
}
public static function ObjectToByteArray(object: *): ByteArray
{
var ba: ByteArray = new ByteArray();
ba.writeObject(object);
ba.position = 0;
return ba;
}
}

To do the actual comparison:

if (SerializeUtil.ObjectToString(object1)==SerializeUtil.ObjectToString(object2))
{
// Objects are 'equal'
}
else
{
// Objects are not 'equal'
}

Thursday, February 14, 2008

ChartItemEvent.CHANGE in conflict with IndexChangedEvent

Earlier this week I ran into a strange problem when the ChartItemEvent.CHANGE event is raised. It seems that the string behind the constant is 'change' and this happens to be the same as the string behind the IndexChangedEvent.CHANGE event. Probably programmed on monday morning :)

Fortunately there's a simple workaround:
Put a container around your 'problematic' charting component (for example a canvas) and attach a listener to the ChartItemEvent.CHANGE event to stop it from propagating.

<mx:Canvas id="canvas" creationComplete="canvasInit()">
  <mx:PieChart id="pieChart" ... />
</mx:Canvas>

// Hack to prevent propagation of the ChartItemEvent.CHANGE as it is in conflict with IndexChangedEvent.CHANGE
private function canvasInit(): void
{
canvasInit.addEventListener(ChartItemEvent.CHANGE, chartItemEventChange, true, 0, true);
}

private function chartItemEventChange(event: Event): void
{
event.stopImmediatePropagation();
}

Tuesday, January 29, 2008

Is your PopupButton suffering from Alzheimer?

Recently I noticed that my PopupButton didn't want to popup anymore... Sometimes it worked and most of the time it didn't. The problem is related to a 'fix' Adobe did to get rid of a memory leak. The 'fix' may have fixed the memory leak but introduced serious trouble. Scott Melby seems to have found a workaround that works most of the time. More information on http://tech.groups.yahoo.com/group/flexcoders/message/99105. Let's hope this gets fixed soon because it's clearly a bad fix.

Thursday, January 24, 2008

How to use a percentage for maxWidth or maxHeight?

Recently I wanted to set the maxHeight of a component to a percentage. Sadly enough this isn't supported in Flex. There's however a very simple workaround that seems to work all the time: set the maxHeight or maxWidth in the resize event of its container:

<mx:Canvas
  id="cnvsComponent"
  resize="childComponent.maxHeight = cnvsComponent.height"
  width="100%" height="100%">
    <mx:Tree id="childComponent" />
</mx:Canvas>

Tuesday, January 22, 2008

Taming your combobox width

Recently I discovered that setting a combobox to width="100%" doesn't mean the combobox won't grow bigger than the width of its container. If the text cannot be completely displayed your combobox becomes wider than 100%. You can use the following construction to tame its width:

<mx:canvas id="cnvs" width="100%" resize="cb.width = cnvs.width">
  <mx:combobox id="cb" text="this is a rather long combobox text" />
</mx:canvas>

Simply add a canvas around the combobox and explicitly set the width of the combobox to the width of the canvas through the resize event of the canvas. This solution works because the problematic behaviour only occurs when using a percentage width.


The same applies to the Label component (and probably some other components as well).

Friday, January 18, 2008

Trouble centering your popups ???

I had some trouble centering popups created through PopupManager. If you simply use 'this' as the parent display object then the popup is 'centered' according to the parent component specified (instead of to the complete stage). If you want to center your popup in the middle of your application screen you should specify 'Application.application.parentDocument'...