Archive for November, 2008

Tour de Flex Unveiled!

Posted in Adobe Flex, Flex/AIR with tags , , , , , , on November 21, 2008 by devgirl

So I’ve just returned from Adobe MAX 2008 and I’m very excited about finally being able to talk about the latest and greatest application I had the pleasure of working on… Tour de Flex!

If you haven’t already hear about it, Tour de Flex is an AIR application that allows you to explore and learn about Flex and AIR through a variety of code samples and illustrations. It includes samples for using the core SDK, as well as a bunch of 3rd party code samples from people like ILOG, Degrafa, and from the community of Flex coders like Doug McCune.  It even includes an entire category devoted to using a bunch of the ActionScript Cloud APIs to interface to things like Twitter, Flickr, eBay, Salesforce.com and many more, which I found particularly fun to work on. The really neat thing is that Tour de Flex will continue to grow with more samples since we have made it a community-friendly app where developers are encouraged to submit their own samples. Check out the project home page for more details.

Another great part of this endeavour, was the brilliant idea James Ward had to offer a way to interface to the Tour de Flex app right from inside your IDE, so we went ahead and built a plugin for Eclipse/Flex Builder to do just that. The idea is that you can search for code samples right from your IDE and instantly grab what you need via copy/paste of the sample code back into your source code or download the sample zip right from Tour de Flex to your hard drive. I have been using this in my dev’t for a few weeks now and became even more excited about it after finding it so useful myself! I would not have been able to write this plugin so quickly without the functionality provided from the Merapi APIs. This was absolutely key in allowing us to communicate between the Eclipse/Java side and the AIR/Flex side in such a timely manner. Please refer to my latest blog article to find out more details. Also, please stay tuned for more information on the making of the Tour de Flex plugin!

Flex/AIR to Java Communication Using Merapi

Posted in Adobe Flex, Flex/AIR, Java with tags , , , , on November 13, 2008 by devgirl

If you’re looking for a way to communicate between Flex and Java, there’s a great API available for doing just that. It’s called Merapi and is basically a bridge for sending messages between Java applications and Flex/AIR apps. I recently worked on a project for Adobe (shhh, until MAX!) where I used Merapi to communicate between an Eclipse plugin and an AIR app and found it extremely cool! One of the greatest things I found with it is the fact that it is written on top of the AMF3 libraries so passing objects between the two is a piece of cake!

In this post I will show how I was able to use Merapi to suit my needs of communication. I started with Merapi on the Java side by creating a Merapi Bridge instance and registering the various messages I wanted to listen to along with the handler object. The object specified as the handler needs to implement the handleMessage() method and gets called when a message being listened to is received. Each message has a name to identify it between the Java and ActionScript/Flex side. The code to register the messages in Java looks like the following:

          Bridge br = Bridge.getInstance();
          br.registerMessageHandler(MSG_FINDCOMPS, this);      // MSG_FINDCOMPS is a static String with value FindComponents
          br.registerMessageHandler(MSG_FINDFEATCOMPS, this);  // MSG_FINDFEATCOMPS is a static String with value FindFeaturedComponents

and the code to handle those messages when they are received on the Java side looks like the following:

          public void handleMessage( IMessage message ) {
		// Check message type and handle accordingly
		if (message.getType().equals(MSG_FINDCOMPS)) {
			final IMessage m = message;
			resultTableDisplay.syncExec(new Runnable() {
		        public void run() {
		            final ArrayList<Component> al = (ArrayList<Component>)m.getData();
		        	compList.setComponents(al);
			    }
		        });
		}
		if (message.getType().equals(MSG_FINDFEATCOMPS)) {
		    // In this case, we want to go ahead and reply with a message containing the Plugin Transfer
		    // Object so we have the Eclipse workspace path etc... back in the AIR app
		    TDFPluginTransferObject tpto = new TDFPluginTransferObject();
		    tpto.setSelectedComponentId(null);
		    try {
	                IPath path = (IPath) org.eclipse.core.resources.ResourcesPlugin.getWorkspace().getRoot().getRawLocation();
			tpto.setPluginDownloadPath(path.toString());
			this.sendMessage(MSG_SENDINFO,tpto);
		    }
		    catch (IllegalStateException ex) {
			System.out.println("IllegalStateException:" + ex);
		    }

		    final IMessage m = message;
		    featuredTableDisplay.syncExec(new Runnable() {
		    public void run() {
		        final ArrayList<Component> al = (ArrayList<Component>)m.getData();
		             featuredCompList.setComponents(al);
		        }
		    });
		}
	}

Notice in the code shown above, I am also sending a message to the AIR side with a custom object containing data I need there as a response to a message I had received. That object is represented by a class on both the the AIR and Java side and all serializing/deserializing of it is done for me underneath, which is awesome! More about that again shortly. My sendMessage() method is where I actually do all the sending from the Java side to the AIR side and looks like the following:

        public void sendMessage(String msgType, Object msgData) {
		try {
			Bridge.getInstance().sendMessage(new Message(msgType,null, msgData));
		}
		catch(Exception ex) {
			System.out.println("Exception " + ex);
		}
	}

So now we need to head over to the AIR side to see how this all fits together. First I need to make sure that the app was called from my plugin since I have specific behavior that is needed in that case. So to do this I check for an invoke argument that I pass from the Eclipse side when I invoke the AIR app. If found, then I want to create a Merapi Bridge instance and listener, along with a specified handler method for the responses. As you have probably noticed, the Bridge object is implemented as a Singleton, so you always get that one instance.

	if (invokeEvt.arguments[0] == "plugin") {
	        isPlugin = true;
		bridge = Bridge.instance;
	  	bridge.addEventListener(ResultEvent.RESULT,handleResponse);
	}

The handleResponse() method to specified above is called when a response is received from Java and that handler looks like the following:

       private function handleResponse(event:Event):void
       {
            var ev:ResultEvent = ResultEvent(event);
		var msg:Message = Message(ev.result);
		if (msg.type == "FindComponents") {
			if (msg.data != null) {
				var msgType:String = msg.type;
				comps = objectData.getFilteredComponents(String(msg.data));

	    		}
			var m : Message = new Message();
           		m.type = "FindComponents";
               		m.data = comps;
               		bridge.sendMessage(m);
		}
		else if (msg.type == "SendPluginTO") {
		        pluginTransferObject = TDFPluginTransferObject(msg.data);
		}
		else if (msg.type == "Minimize") {
			this.minimize();
		}
		else if (msg.type == "Dock") {
			this.dock();
		}
		else if (msg.type == "Undock") {
			// We need to figure out what the download path is from the returned message and set it
			pluginTransferObject = TDFPluginTransferObject(msg.data);
			this.objectList_change(null); // Fire the navigation to the component double-clicked from plugin
			this.undock(event);
		}
		else if (msg.type == "Exit") {
			isPlugin = false;
			onExiting(event);
		}
     }

The Java side is the ‘initiator’ of the communication, and the AIR app handles it’s requests via the above method, however the AIR side can also send a message to the Java side once the bridge has been established. An example of that is shown below, were we specify the component type name and its data before sending.

                var m : Message = new Message();
	       	m.type = MSG_FINDCOMPS;  // where MSG_FINDCOMPS is a static variable string with value FindComponents
	        m.data = featuredComps;
	        bridge.sendMessage(m);

There is one line of code from the handleResponse() method I’d like to point out in particular, where I’m creating the custom object below:

        pluginTransferObject = TDFPluginTransferObject(msg.data);

This is the other side of the object serialization that occurs automatically for me so my object is ready to go upon receipt. Two main things to be noted here… 1) you MUST put the remote path of the Java side object to be mapped to inside your custom ActionScript object (such as in my TDFPluginTransferObject in this case). That statement looks like the following:

[RemoteClass(alias="com.adobe.tourdeflex.core.TDFPluginTransferObject")]

and 2) all properties of the object must match exactly to the fields on the Java side, names, capitalization, everything.

So that about sums it up. The use of Merapi in this application definitely added that ‘WOW’ factor, and is still super cool to me and everyone that sees it so I highly recommend checking it out! The Merapi project is currently in private beta and about to be released soon. The guys behind it, namely Adam Flater and Dave Meeker, have been working very hard to support it and were extremely helpful in making sure we were able to use it for our needs. Thanks Adam & Dave :)!! They will also be at Adobe MAX, so be sure and check out all the cool stuff they’re doing!

Generate PDF’s from your Flash, Flex and AIR apps

Posted in Flash, Flex/AIR with tags , , , , , , on November 3, 2008 by devgirl

If you’re looking to generate a client side PDF from your Flash, Flex or AIR applications, there is a great ActionScript 3 library available now for doing just that. It’s called AlivePDF and was built under an MIT license so you are free to use it in your applications. I downloaded it and tried it myself and was generating a PDF from my AIR app in seconds! I found it very easy to use, and without requiring extensive coding. The download includes examples which are extremely helpful to get started quickly. There are some more useful notes about the API, as well as a sample of how to open and view that PDF just generated here as well: http://code.google.com/p/alivepdf/wiki/APINotes.

PDF Away! 🙂