Category: Development

I Updated yesterday from an early release of Windows 7 to the retail release doing a complete wipe of my computer. After installing Flex Builder 3 I tried to do some work, yet every time I launched the program Windows 7 alerted me that I was running a program with an unknown publisher. After hitting my self in the head I released that unlike my regular Eclipse environment, Flex Builder was not using my VM but the one that is packaged. This packaged version is NOT signed.

For some reason this worked fine before; but now, not so much. Setting the [-vm c:\pathto\javaw.exe] in the eclipse.ini did not work, but changing the shortcut did work. Any insite into this is welcome!

So in short, on windows 7, force your VM to a legit installed JRE to get this pop-up message to go away if your getting it! The packaged one is not in favor with Windows 7 security!

After years of abuse of pop-ups and confirmation boxes users have become so honed at the skill of simply clicking the OK button on any kind of confirmation box that pops up that it has become almost nothing more than a reflex. This can cause some serious issues when it really matters.

In my flex application I needed to increase the chances of a user actually reading the notice in the pop-up box as much as reasonably possible within the user experience. The solution I decided to use is I believe fairly common to anyone with windows experience; it's also one I would use sparingly!

When the confirmation dialogue is presented the OK button is disabled at first. Instead a countdown timer is displayed on the button. After that timeout the user can then click "OK"; The cancel button is available at all times.


The code isn't rocket science and making use of the pop-up is so simple I won't even bore you with an example, but it is a nice quick fix if you need it.

Source view is enabled on the Flex demo

A little while ago I started using a screenshot of our flex app login to use as the background for a few of our web apps. As usage grew I ran into multiple color and title needs. So instead of doing things the simple way and just using Photoshop, I decided to make this an example of taking and using "screen shots" (not using mx.graphics.ImageSnapshot).

First I built a plain-jane panel component that I wanted to use as my background in my HTML based application

Then in my main MXML file I wrapped the login component and 3 empty canvases in one larger canvas. I did this in order to more easily control position inside the greater app while easily being able to build my Rectangles.

<mx:Canvas id="loginForm" backgroundColor="{this.backgroundColor.selectedColor}" width="400" height="296">   
    <local:LoginForm title="{this.windowTitle.text}" borderColor="{this.panelColor.selectedColor}" width="360" y="15" horizontalCenter="0"/>
    <mx:Canvas id="loginHeader" width="368" height="48" y="11" horizontalCenter="0"/>
    <mx:Canvas id="loginBody" width="368" height="59" y="78" horizontalCenter="0"/>
    <mx:Canvas id="loginFooter" width="368" height="67" y="219" horizontalCenter="0"/>
</mx:Canvas>


I positioned the 3 boxes to be in the size and position of my 3 desired screen shots: A header, a repeating body and a footer. In my code I use these to create a very easy way to visualize what I'm capturing. In the real world outside of my very specific goal these might be controllable by the end-user.

To create my screen caps first I take a snap of the entire formpublic function takeSnapshot():void {
    var imageSnap:ImageSnapshot = ImageSnapshot.captureImage(this.loginForm);
    var imageByteArray:ByteArray = imageSnap.data as ByteArray;

    var loader:Loader = new Loader();
    loader.contentLoaderInfo.addEventListener(Event.COMPLETE, getBitmapData)
    loader.loadBytes(imageByteArray);
}


Then I loop over my 3 targets to create the specific sub-images that I need:
var bd:BitmapData = Bitmap(e.target.content).bitmapData

for each (var target:Canvas in [this.loginHeader, this.loginBody, this.loginFooter]) {
    rect = new Rectangle(target.x, target.y, target.width, target.height);

 bd2 = new BitmapData(target.width, target.height);
    bd2.copyPixels(bd, rect, pt);

    var m : Matrix = new Matrix();
    bd2.draw( bd2, m );

    encoder = new JPEGEncoder(100);
    ba = encoder.encode(bd2);

    rawImages[target.id] = ba;
}

this.amfService.save(this.downloadUUID, rawImages);



The flex app has view source enabled and the ColdFusion code for the backend is included as well...

 

Are you using flash.net.FileReference's download function and having your download fail? I was too and it took stumbling on a flash kb article to get me on the right path.

My issue:private function downloadFile():void {
    var f:FileReference = new FileReference();
    f.addEventListener(Event.COMPLETE, myFnc);
    f.download(myURLRequest, strDefaultFileName);
}

This should work in my mind... However it does not. It will most likely fail with absolute silence.

Instead, init a globabl FileReference.private var fileRef:FileReference;

private function init():void {
    this.fileRef = new FileReference();
    this.fileRef.addEventListener(Event.COMPLETE, myFnc);
}

private function downloadFile():void {
    this.fileRef = new FileReference();
    this.fileRef.addEventListener(myURLRequest, strDefaultFileName);
}

This my friends will now work. It shouldn't require this code layout IMO, but it does...

I got caught up in a little gotcha last night that took me a few minutes to fully fix.

Like a High School romance I believe my love for Adobe Air has fallen by the way-side. Like many of you I saw the huge potential of Flex Apps on the desktop, all the cool amazing things I could do and all of the amazing new capabilities. I was drooling to write my first AIR apps after MAX Vegas...

Then reality hit me after recently being charged with creating several Adobe AIR applications; 1 large and 2 small ones. I love flex, I love ActionScript, I even still really like the Air Runtime. AIR truly allows you to do some things with the client side computer that will never be possible via a web browser. The local database, file extension capabilities and encrypted file store are a few. Also you can run larger applications faster and you can easily write agile “sometimes-connected” applications.

What is the reason for my waning love affair? It's really very simply: capabilities!

Adobe has tried so hard to lock down AIR to avoid the possibilities of someone writing a malicious program that they have turned it into a small shadow of what it COULD be.

 

  • ZERO ability to make system API calls
  • Inability to load DLLs and other Libraries
  • No registry functionality 
  • Can't launch outside/non-air applications 
  • Horribly locked down and inflexible install process/package 
  • Piss-poor uninstall capabilities

 

These are just a few of the things that have come to erk me over the last few months with AIR. The more I look at what I can't do with Adobe AIR, the more I realize that there just is absolutely no need for me write an AIR App unless it HAS to support “sometimes-connected” and I can't take the time to write it in anything else!

I understand that every technology has it's place and application; however I think AIR is missing a massive massive market by willingly or even striving at making it's self so ham-fisted just to play it safe. People write malicious VB, C++, C# and so on applications all the time. You don't see any calls out there from the masses: “Oh my god don't download that application, it was written in Visual C++ and might do bad things”!

My few months of working with Adobe AIR has left me feeling the same way about it as I do about Apple and their asinine rules surrounding the iPhone. Adobe can still fix this though, they can still add in the capabilities that I think should have been there from the start. Until then, I will continue to simply use Flex where it kicks-ass the most: the web!