Posted by: edsyrett | 18 February 2009

New line in DataGrid, using XML

Alex Harui has a post here about having a dummy line at the bottom of a DataGrid that the user could tab to or click on to add a new line.  Alex’s version uses arrays of objects.  However, we use a lot of XML in our projects, and whilst we could actually make it work with an XMLList, I set about trying to do it properly with an XMLListAdapter, which is the XML equivalent of the ArrayCollection.  I think I managed it, but it was difficult because I ran in to a couple of issues with DataGrid and the XMLListAdapter itself.  I couldn’t get the grid to work properly without these changes.  

My test app is here.  As usual you can right-click and select “view source”.

Advertisements
Posted by: edsyrett | 15 January 2009

Runtime error handling in Flash and AIR

Back in the days when I was doing Windows 3.0 with Microsoft C 6.0, you could add a try/catch block around the message loop and your app would happily show you when any runtime error occurred.  

Unfortunately the standard Flash Player and AIR runtime just ignore any such errors – the user won’t get an error message and will most likely just see very strange and erroneous behaviour, and there is absolutely nothing useful he or she can tell the developers.

It seems that this is a big issue with developers as it really restricts our ability to track down bugs in live systems.  There’s a bug report here – Ability to intercept system error dialogs – for Flash Player. It’s been hanging around since June 2007, and nothing appears to have been done.  Please vote for this one, add a comment, and add your voice to the ever growing band of developers who need a global error handler of some sort.
 

Posted by: edsyrett | 13 January 2009

Speedtest.net

Test your Internet connection speed at Speedtest.netI just love the look and feel of this website, and as you might expect, it uses Flash Player.  The app loads in no time, the response is good, and the animations run smoothly.  

 

And it tells me that I’m getting a decent download speed from my ISP…

Posted by: edsyrett | 12 January 2009

Adobe AIR Install Problem

Andy Quayle has posted a handy hint about getting around problems installing updates of the AIR runtime.   

There seem to be a number of problems with updating a client machine with either an AIR app or the AIR runtime itself.  I really hoped that it would all just work, but it seems that we need to find workarounds to the issues that Andy found, and others.

As I mentioned in my comment on Andy’s blog, we have steered away from installing AIR apps on user’s machines just avoid the potential hazard of having to update them with fixes.  When you already have a big user base of Citrix clients, why bother installing it on all those machines when you can just stick it on one or two Citrix servers…….

Posted by: edsyrett | 23 December 2008

Appcelerator Titanium – competitor for AIR?

I just had a look at the post on The Register about Titanium. Apparently Titanium is competitor for AIR – it enables you to write a desktop app in HTML, CSS and JavaScript.

I’m afraid it just doesn’t make sense to me. Why would anybody want to propagate old technologies like HTML, CSS, and JavaScript, when instead they can have a leading edge technology in Flex?

Just off the top of my head, I thought of these objections:

  • My experience of JavaScript is that it isn’t typesafe – everything is an Object.  However, ActionScript is a fully-featured Object-Oriented language.
  • Writing with HTML means that a lot of the layout would be done by some runtime or other.  However, in Flex, everything eventually boils down to ActionScript, and you can see the framework code and debug it.
  • I really don’t believe that I could reproduce all the controls available in Flex in HTML/JavaScript, or if I did really need to do such a thing it would take me ages.  However, in Flex, you get a whole bunch of controls that work straight out of the install.
  • I’d be interested to know whether HTML/CSS/JavaScript source can be shared across both a browser-based app and in a Titanium desktop app.  I doubt it – I suspect there will need to be major differences.  However, I just created an AIR app from our existing browser-based app in under an hour – only one file is different and that’s the main application mxml file.

As I mentioned in the last point above, I just created an AIR app from an existing web app.  This now gives us three methods of deployment:

  • Standard web application
  • AIR application running on a user’s desktop
  • AIR application deployed on a Citrix server and delivered to the user via a Citrix session.

Yes, we are looking at deploying AIR via Citrix, and it works.  If a set of users already have the Citrix client installed, why not use it?  We actually haven’t made a decision on which one we’ll go for as we’d really like to use the Citrix deployment, but if the bandwidth isn’t up to it then we may use either of the other two.

But the main point is that Flex Builder offers us a great development environment, and more than one option for deployment.  And for that reason I think Titanium isn’t anywhere near a competitor for AIR – it’s just a gimmick.

Posted by: edsyrett | 19 December 2008

PopupButton.closeOnActivity

As I mentioned in a previous post, I’m working on a dashboard application, and I wanted a control bar at the top of the main application window with a PopupButton on it that drops down a list of the available windows to show in the dashboard.  You might think that this is pretty easy, and you’d almost be right….

I derived a class, PopupCheckboxList,  from PopupButton, which sets a List as its popup.  I created an item renderer, CheckboxListItemRenderer, that contains a checkbox and a label in a HBox.  I added overrides for dataProvider and labelField in PopupCheckboxList so that it could pass on these values to the list.  And I thought that I was finished.  However, there was still a problem.  When I clicked on the button, the list dropped down, but as soon as I clicked anywhere on the list, it closed again.  Whilst I could still click on an individual checkbox to set or clear it, I had to click on the button to reopen the list every time.

I found this code in PopupButton.as…

private function popUpItemClickHandler(event:Event):void { if (_closeOnActivity) close(); }

So I looked for some way to set _closeOnActivity to false. I found this…

/** * @private * Specifies popUp would close on click/enter activity. * In popUps like Menu/List/TileList etc, one need not change * this as they should close on activity. However for multiple * selection, and other popUp, this can be set to false, to * prevent the popUp from closing on activity. * * @default true */ private function get closeOnActivity():Boolean { // We are not exposing this property for now, until the need arises. return _closeOnActivity; } /** * @private */ private function set closeOnActivity(value:Boolean):void { _closeOnActivity = value; }

OK, this was a bit of a surprise…

“for multiple selection..this can be set to false”

No it can’t!…It’s private….

We are not exposing this property for now, until the need arises.

But you just said it can be set to false….make up your mind…

So I had to resort to good old Monkey Patching. The end result is
here. You can click on the down arrow on the button to drop the list, and then click as many times as you like to check or uncheck items. Then click anywhere on the button to close the list (and hopefully do something with your selection)

I had a quick Google for “closeOnActivity” and found
this. So this is a known bug, and until Adobe see fit to fix it, you and I have to keep going with Monkey Patching.

Posted by: edsyrett | 18 December 2008

How to load the same module repeatedly…

I’m currently working on a dashboard application that loads up the same module over and over.  Each module contains a chart component, and the only difference in the way the module is used is the data that is passed in from the server.  It makes sense to use the same module because the charts are all presented in the same way.

So I started off setting ModuleLoader.url over and over, and I ran into a bunch of exceptions.  After having a good look at ModuleManager, it wasn’t hard to see why…

Have a look at this code…


public function getModule(url:String):IModuleInfo
{
    var info:ModuleInfo = moduleList[url] as ModuleInfo;

    if (!info)
    {
        info = new ModuleInfo(url);
        moduleList[url] = info;
    }

    return new ModuleInfoProxy(info);
}

If you request the same URL over again, you’ll get the same instance of ModuleInfo. But in ModuleInfo there are a bunch of private vars – loader and factoryInfo.

If you end up calling getModule() with a url that you’ve already requested, and that module hasn’t finished loading yet, loader and factoryInfo get overwritten, and from that point on, you’re doomed.

I’ve created a little test app here that demonstrates this problem. It shows code that sets ModuleLoader.url to the same value in a tight loop. And if you do that, it will fail. You could wait until the module has loaded the first time before requesting it again, but to my mind that’s a poor solution because it would take ages to load a number of modules, and the Flex Framework is perfectly capable of loading them in parallel.

But look at the code from ModuleManager again – it decides whether or not to return the same ModuleInfo based on the URL. So if you can fake the URL but make it load the same module, you’re in business. And that’s just what the test app does, by appending an index (it could be anything) as though it’s a parameter on the end of the URL.

So instead of this…

http://.../TestModule.swf

… we’re using this…

http://.../TestModule.swf?1

ModuleManager is obviously like this by design – after all, who’s going to be daft enough to load the same module over and over… But quite why it is designed like this is beyond me. loader and factoryInfo are written to behave almost like Global vars, and you know how dangerous they are.

But for now, the solution I suggest above seems to work, and we’re going to use it in our Dashboard app…

Posted by: edsyrett | 29 November 2008

My flash package has gone missing…

Just recently I’ve noticed something very strange happening in Flex Builder running on Windows XP.  It seems to have forgotten about the flash.* package.

Flex Builder doesn’t offer any of the classes in the flash package during code completion.

Much worse, what used to happen was that when I saved or pressed Ctrl-Shift-O to sort my imports, anything in the flash package would just disappear from my imports.

As it happens, I’ve been able to work around this last problem by unchecking “Keep imports organized” in Windows/Preferences/Flex/Editors/ActionScript code.  But I still have to add imports in the flash package manually.

A similar issue has been reported on the Adobe Bug Management System here, although this particular report seems to be more to do with Ubutu.  However, one guy has posted a possible solution for Windows that I have reproduced here:

Windows + Flex SDK 3.1.0.2710 + Flex Builder 3.0.194161 
To fix it: 
1) move /frameworks/libs/player/9/playerglobal.swc to /frameworks/libs/player/playerglobal.swc 
2) edit /frameworks/flex-config.xml 
<external-library-path> 
  <path-element>libs/player/playerglobal.swc</path-element> 
</external-library-path>

I haven’t tried this yet as I’m seeing the problem on my work pc, so I’ll try it out on Monday.

It’s also interesting that I have this problem at work where I have an older version of Eclipse with the Flex Builder plugin, but at home I have Flex Builder 3.0.205647 (not the plugin), which doesn’t show the same problem. This version is obviously later than the version mentioned in the bug report, so maybe the issue has gone away in my home version.

It seems that I’m not the only one with this problem.  I notice that Tink has encountered this problem from his blog post here. He is a lot further forward in figuring out what to do to make it go away. So I’ll be watching both his blog and the bug report for any developments.

Posted by: edsyrett | 24 November 2008

OLAP and Cubes

And for my next trick, it’s OLAP Cubes in Flex…

When I started researching for this prototype, I couldn’t find much about programmatically setting up the cube dimensions in ActionScript – the documentation seems to advise that we should do it in MXML.  But thats really limiting, because it means that you can’t dynamically alter the cube and the query.

However, after digging around it seems it’s not that bad at all, and after a few hours work, here’s my OLAP test app.

The app takes an XML data source which contains the data and the schema, i.e. a list of the fields in each row.  I then populate a bunch of combos so that you can dynamically select each axis.  In the example, the data is really simple with only four axis values and one measure value.

The combos force you to select at least one row and column axis, then you can click on Refresh to populate the grid.  If you want to change anything, click on Reset to clear the grid and all the combos.

I’m still working on it, and on the list of things to do, there are the following items:

  • Make the combos and the related axis colour coded, so that you can easily see which axis came from which combo.
  • Plug the data from the cube into a chart.  Whilst this is theoretically possible, I suspect it’s going to be really fiddly…

 

Posted by: edsyrett | 14 November 2008

Feel The Heat…

Heat Map

Heat Maps are basically an easy way to show a number of points on a map, and see where the points are most concentrated.  From the marketing perspective, you’d probably want to plot a bunch of possible clients, and concentrate your efforts on the areas that have most clients.

The points on the map represent the locations of service stations that sell LPG, apparently.  But you can see the point – from the map you can see that you’re OK in London and most of the rest of England, but go up to Scotland and you better have a full tank…

Click on the image to see my attempt at a Heat Map using Google Maps.

Read More…

« Newer Posts - Older Posts »

Categories