Deploying Flash / Flex to server using Ant.

This post contains a few simple steps to setting up an Ant target that will deploy a Flash or Flex project ( or anything really ) to a server.

This is a useful addition to an Ant build, saving time copying files manually and preventing potential errors occurring when trying to remember which files to copy.

To begin with it is assumed that you are using Flash/Flex Builder/Eclipse and that Ant is set up for it. If you don't have Ant set up then there are plenty of good tutorials showing how to, such as this one.

The main Ant task used is the SCP task, documentation for which can be found here. This isn't included in the Ant distribution and requires the jsch library. I had problems using the latest version in Flex Builder 3 with Ant 1.7, but found version 0.1.29 to work fine. This version is available here.

To set up the jar file in Eclipse go to the Window menu and select Preferences.... Open Ant in the tree menu on the left and select Runtime. Then under the Classpath tab to the right select Global Entries and click on the Add External JARs... button. Browse to and select the jsch jar file. You should now be set to use the various jsch tasks including the SCP task.

A basic target to copy a bin folder to a folder on a server would look something like this:


<target name="deploy" >
    <scp 
        trust="true"
        password="${password}" 
        todir="${server.user}@${server.address}:${server.loc}">
        <fileset dir="${bindir}" /> 
    </scp> 
</target>

Obviously all the variables are held in a .properties file declared earlier in the build file making the target more reusable, but you could equally hard code the values in.

If you don't want to have a password in a .properties file then you can add a dialog to the task for password entry. Ant offers the input task, but doesn't provide any way of *ing out the text entry. There are several third party tasks that offer this functionality. One good one is the query task from the JeraAntTasks library.

To use this download the jar file from the above link and add it to Ant's Global Entries in Eclipse the same way the jsch jar was added above. Then go to the Types tab and click on the Add Type... button. In the window that opens enter a name ( this is the name that you will use in your build file ), select the JeraAntTasks.jar from the location dropdown. Navigate to the anttasks package in the bottom left tree menu and select Query.class in the bottom right hand menu. Press OK.

You can now add a password dialog box to the target so it looks something like this:


<target name="deploy" > 
    <query name="password" password="true" />
    <scp
        trust="true" 
        password="${password}" 
        todir="${server.user}@${server.address}:${server.loc}"> 
        <fileset dir="${bindir}" /> 
    </scp> 
</target> 

In place of having a password variable in a .properties file, it is now declared by the query task. Remember to replace query with whatever you called it in the previous step.

This is a relatively simple target, but could be expanded to do pretty much whatever you like when combined with other build targets and other tasks, such as the SSHEXEC task for example.

AIR 2 Native Process Example - Mouse Screen Position

I had been wanting to have a play around with the native process classes that were added in AIR 2 for quite some time, but only recently managed to get around to doing so. Something that had always bugged me with AIR (and the Flash platform in general) was the lack of any way of getting the screen mouse position when the application wasn't being interacted with. So as a way of experimenting with the native process feature I wrote a little AIR application that interacts with a c++ process and outputs the mouse position at all times.

Starting and interacting with a native process from AIR is actually pretty straightforward. It is essentially a case of setting up a NativeProcessStartupInfo object, a NativeProcess object and adding event listeners to the NativeProcess. Here is this section in the example application:

This is in fact all the Actionscript code in the example. Application complete calls onAppComplete which checks if native process is supported. If so a NativeProcessStartupInfo is created and a reference to the process file set on it's executable property. This is then passed to a NativeProcess object, which is started and has several listeners added to it.

Of the listeners added the most important to this example is ProgressEvent.STANDARD_OUTPUT_DATA. This listens for updates to the process' standard output, and updates the output variable in the application.

The second part to this example is the c++ application. Before I go into this I'd like to note that I'm no c++ developer, so there are probably faster/cleaner/better ways to go about what I have done. Below is the code for the small application used:

This program takes the current mouse position, converts it to a string of the form 'x : y' and outputs it on the standard output. This is done on an infinite loop every 100 milliseconds. This output is picked up by the AIR application and displayed as described earlier.

This program is built and bundled with the AIR application, which is then built as a native installer for Windows. This is one of the limitations of using native processes. You have to build the application as a native application, which means having to do it for each individual platform you intend it to be deployed on. In this examples case, it will only work on Windows, because the underlying process will only work on Windows. Although it could be built to work on other platforms, doing so would add effort and potential problems.

The c++ element of this example was build using Microsoft Visual c++ 2010 Express as a Win32 console application.

Project Files

Using the Flex Singleton register Pt 1/3

This is the first in a 3 part post about using the Flex Singleton register. This post will deal with what the Flex Singleton register is as well as how and why its used. The second will look at how to register your own classes with the Singleton register (not as easy as it sounds) and the third will be a real life example.

The final post will show you how to give the Alert control the ability to create a modal overlay that supports a custom chrome in Adobe Air. The big pain with a custom chrome (say a splat shape) is that the modal overlay covers the entire bounds of the window - including any transparent areas. So for irregular shapes/chrome - like a splat as a background, you get a big square slapped over the top - not ideal. What you want is ONLY the splat to be overlaid with the modal background.

By using the Singleton register and a custom implementation of the PopupManager we can add this functionality without having to create a custom Alert class. You don't have to change any of your existing app code where Alerts are used, all existing calls to Alert will now have our new and improved modal background!


The Singleton register

Flex has many singletons that are used as the default functionality for its components - the popup manager being one of them. At start up, the default implementations that flex uses are registered with the static class Singleton. When a class such as the PopupManager is first used, it will retrieve the class that defines its core functionality from the Singleton class.

The classes are registered against an interface, and it is by the interface that they are retrieved. Thus any class implementing the correct interface could be registered and used instead of the default class.

The ability to define custom implementations is a great feature of the flex framework, but is largely undocumented and support for actually overriding the default implementations is greatly lacking. However, it can be done!


Retrieving a class from the register

The PopupManager class is simply a Static class, that upon first use, will retrieve a singleton object that defines its core functionality.

Below is how the PopupManager retrieves the singleton that it will use for its core functionality. This is a static method in the PopupManager.

 
private static function get impl():IPopUpManager 
{ 
    if (!_impl) 
    { 
        _impl = IPopUpManager( 		Singleton.getInstance("mx.managers::IPopUpManager"); 
    } 

    return _impl; 
} 

The key line is :

 
Singleton.getInstance("mx.managers::IPopUpManager") 

This will perform a look up on the static class Singleton for a class that has been registered against the interface mx.managers::IPopUpManager.

If one is found, its static getInstance method is called and the instantiated singleton is returned. This instance is then used as the implementation of the PopupManagers core functionality. So, if you could register your own class against mx.managers::IPopUpManager, you could completely change how the PopupManager works!
Registering a class with the Singleton register

When the flex framework initializes, it registers each of these implementations with the static class Singleton. This simply adds the class to a class map, indexed by the interface name that it implements.

The class that is registered must adhere to the following 2 points.

  1. It must implement the interface it is registered against.
  2. It must implement a static method getInstance that returns the singleton instance of itself.


In the case of the PopupManager, the singleton class that is registered is mx.managers.PopUpManagerImpl. Its is registered against, and implements the interface mx.managers.IPopUpManager and it contains a static method getInstance as below...

 
 public static function getInstance():IPopUpManager 
 { 
    if (!instance)             instance = new PopUpManagerImpl(); 
    return instance; 
 } 
 

The registration is on a first come first serve basis, so the first class to be registered against a particular interface is stored in the Singleton registry. Any subsequent registrations for the same interface are ignored.

The PopupManger will be registered like this...

 
Singleton.registerClass("mx.managers::IPopUpManager", mx.managers.PopUpManagerImpl); 


Custom registration..... The drawback is, that all the classes are registered by the time the Flex framework has initialized, and as the register is on a first come first serve basis any subsequent registrations would be ignored.

The next post will show you how to register your own implementations before the Flex classes are registered.

Dynamically resizing AIR windows with non-resizing content.

Following on from my previous post concerning dyncamically resizing AIR windows with user resize (based on Daniel Wabyick’s example here), I wanted to cover a further modification I made; that of having the window resize dynamically, but the content stay the same.

To be more specific, I wanted a content area to remain a fixed size when the window resized dynamically, but maintain a percentage width of the area when the window was resized by the user. (If that makes no sense, download the example after the jump.)

There are two main additions made to the previous example to achieve this. Firstly was to fix the width of the non-resizing area at the start of the resize effect. This was done by adding effectStart="{mainHBox.width=mainHBox.width}" to the Resize effect.

The second part is to return the area to a percent width when the user resizes the window, so the gripperDownHandler method becomes:

 
private function gripperDownHandler():void 
{ 
    //adds an extra bit of safety incase the mouseUp occures outside the gripper      
    stage.addEventListener( MouseEvent.MOUSE_UP, gripperUpHandler ); 
    
    chrome.setStyle("top", 10); 
    chrome.setStyle("bottom", 10); 
    chrome.setStyle("left", 10); 
    chrome.setStyle("right", 10); 
    chrome.setStyle("resizeEffect", null); 
 
    mainHBox.percentWidth = 
        (mainHBox.width / (chrome.width - (mainContent.getStyle("paddingLeft")  		+
        mainContent.getStyle("paddingRight") + mainContent.borderMetrics.left 		+
        mainContent.borderMetrics.right))) 		*100;


    nativeWindow.startResize(); 
} 

The resizeHandler code has also undergone a slight tweak. It now bases the reduction target size for the chrome on the width of mainHbox. This prevents rounding errors, which could create scrollbars or slowly enlarging margins on continued resizes.

Dynamically resizing AIR windows with user resize (gripper).

I am a big fan of Daniel Wabyick's dynamically resizing window example. ( http://www.wabysabi.com/blog/2008/01/29/example-air-app-dynamically-resizing-windows-based-on-content-area/ ). A simple and elegant solution to accommodate dynamically expanding and contracting windows in an AIR application.

I've since extended this example to fill two extra requirements. The first of these was to add a gripper that allows users to resize the window; the focus of this article. The second was to allow the window to dynamically resize, but to keep it's content the same, which I will cover in the future.

For the addition of a gripper to handle user window resizing, I've essentially added three extra elements to the original example. The main one is an Image component positioned in the bottom right that acts as the resize control. The other two elements are a mouseUp and mouseDown handler on this Image which handler the resize.

The mouseDown removes the resize effect from the main content area, locks the main content area to the window and starts the native window resize. The mouseUp then resets the resize effect and main content position.

Here are the two event handler added to the gripper component:

[sourcecode language="ActionScript3"] private function gripperDownHandler():void { //adds an extra bit of safety incase the mouseUp occures outside the gripper stage.addEventListener( MouseEvent.MOUSE_UP, gripperUpHandler ); chrome.setStyle("top", 10); chrome.setStyle("bottom", 10); chrome.setStyle("left", 10); chrome.setStyle("right", 10); chrome.setStyle("resizeEffect", null); nativeWindow.startResize(); } private function gripperUpHandler(event:MouseEvent=null):void { chrome.x = chrome.y = 10; chrome.setStyle("resizeEffect", resize); //clean up the event added in gripperUpHandler stage.removeEventListener( MouseEvent.MOUSE_UP, gripperUpHandler ); } [/sourcecode]

I've attached an example project which differs a little from the original example on Daniel Wabyick's blog, but should illustrate the principle at work.

My apologies in advance for it's ugliness.

AirResizeGripperExample

HTML Text in a Flex Alert box

A quick and easy way to render HTML text with the body of a Flex Alert box. There is no API to set the htmlText property of the Alert text field, but you can access it using the mx_internal namespace.

 
var title:String ="HTML Alert!"; 
var htmlBody:String = "This is my HTML message with <b>Bold</b> text and <br/> HTML formatting <b/>"; 
 var alert:Alert = Alert.show(str,  htmlBody);  // now target the Alert text field (after we have opened it) and set the HTML text property	
 
use namespace mx.core.mx_internal; 
IUITextField(alert.alertForm.textField).htmlText = htmlBody;