Home
eMail

If you're seeing something other than Verdana, the Font is Graublau Sans Web by FDI fonts.info

Working with Rich Media Annotations
Updated 11/13/2009

Inter-RMA Communication

Skills Required: Flex, ActionScript, Acrobat 9

The Basics of SWF in PDF

One of the great new features of Adobe Acrobat 9 Pro and Pro Extended is the ability to add SFW based Rich Media Annotations (RMAs) developed in Flash or Flex. These SWF files can be placed in a PDF file using the new Flash Tool in Acrobat 9 and play using the built-in Flash Player. The built-in player provides greater security and consistency for Flash playback inside any PDF file. For those of you that attempted to use Flash in a PDF with earlier versions of Acrobat, you'll remember that the user experience wasn't’t all that great. Acrobat 9 provides tight integration between the PDF document and the RMAs well as other content types that run in the Flash Player such as FLV and H.264 encoded video.

There are two ways to play the RMA in a PDF file, on the page or in a floating window.


The floating window has certain advantages when you need the RMA to be present regardless of what page you are on in the PDF file.


When the RMA is played on the page, you are able to use the Acrobat commenting features to review and markup the interactive content.

Read “Add multimedia files to a PDF” to learn how to add RMAs to PDF files using the new Flash tool rather than the legacy multimedia object.

Communicating Between Rich Media Annotations

The title of this article aside, in order to communicate between Rich Media Annotations (RMAs), you need to communicate through the PDF file. There really is no way to communicate directly from one RMA to another. This tutorial builds on "Using the JavaScript/ActionScript Bridge" so if you have not read that one yet, now would be the time.

In the example file (linked below) there are two RMAs on the page; the top line chart "Revenue Timeline" and the bottom chart "Regional Breakdown" which is initially empty.

When a user clicks on one of the data points in the "Revenue Timeline", it sends data to the the "Regional Breakdown" chart which shows a pie chart.

Click on other points of the "Revenue Timeline" and the pie should update based on the month you click.

To set this up, I modified this Flex Dashboard example. In the original dashboard, the three pods were all part of the same application so communication between the pods was pretty easy. It's not quite the same with Acrobat but the concepts are similar enough that having a look at the original example is valuable.

Four steps to Inter-RMA communication

  1. Set up the JavaScript/ActionScript Bridge as discussed in "Using the JavaScript/ActionScript Bridge".
  2. Set up a method in Acrobat that will call an ActionScript method for each RMA on the page.
  3. Send Acrobat a string that represents the data you want to transfer.
  4. Execute the method from step 2 with the data from step 3 as a parameter.

Step 1:
Re-read Using the JavaScript/ActionScript Bridge if it's not fresh in your mind

Step 2:
With Acrobat JavaScript, there are two ways to get an AnnotRichMedia object; per page by name or by index number.

By name:
The method getAnnotRichMedia takes a page number and the name of an AnnotRichMedia object. Unfortunately, the is no UI in Acrobat that will tell you the names of the AnnotRichMedia objects on the page, however, they are always named "RMxxx" where "xxx" is a number. The number portion of the name is created when the RMA is added to the page. Even though there are only two RMAs on the page, in the example file, the RMAs are named "RM7" and "RM40". It took me a few tries to get the file working properly and the number start to add up. The effect of adding the same SWF to a file repeatedly as you make chages to it is that you can't count on the first RMA being "RM1" and the second being "RM2".

By index:
The method getAnnotsRichMedia returns an array of AnnotRichMedia objects for a given page. So if I wanted to get the context of the second RMA on a the first page, my JavaScript code might look like this...

rma = this.getAnnotsRichMedia(0)[1]

Unfortunately, I have no idea whether that object is the line chart or the pie chart. I just know it's the second element in the array of RMA objects. Again, ther is no UI in Acrobat that will tell you which is the one you actually want.

The solution:
If you are trying to call a method in an RMA and you are unsure of which RMA it is, the easiest thing to do is simply try all of them. It only takes milliseconds and only the one with a callback to the method properly set up will react. In Acrobat JavaScript, the code might look like this...

function updatePieChart()
{
	RMAs = this.getAnnotsRichMedia(0)
	for each (RMA in RMAs)
	{
	    RMA.callAS("updatePieChart", newPieData);
	}
}
Note: To make adding this script to Acrobat a little easier, I use the RMA to do it rather than adding the script using Acrobat's Document JavaScripts interface. The script is stored in the RMA as an MXML <mx:String> object and then I use ExternalInterface to "eval" it into Acrobat during the RMA creationComplete event. You can see how this works by looking at the example project.

Step 3:
The line chart in the top of the example uses an XML file as a dataSource. The itemClick event in the line chart triggers a method that creates a JavaScript for Acrobat to set a variable equal to the hitData XML and then uses ExternalInterface to send the JavaScript to to run.

 var stringForPDF:String = "newPieData=\""+itemForPDF+"\""; 	
 ExternalInterface.call("eval", stringForPDF); 

Step 4:
Now that I have the variable "newPieData" in Acrobat's memory, I can use ExternalInterface again to execute the method that calls the exposed method "updatePieChart" in each of the RMAs on the page.

ExternalInterface.call("eval", "updatePieChart()")

Step 3 and 4 can be collapsed but I find it easier to debug when I separate getting the string into Acrobat and sending it back into the RMAs.

Open the Example PDF file
Download the Flex Project for the RMAs in the example

Comments: