About Me:

Customizing PDF Portfolio Layouts
Part 1: The "Hello World" Example

Hello World!

Introduction:

If you've reached this page, hopefully you already know what a PDF Portfolio is but if not, you can watch this video on Adobe TV to get a good overview of this cool new feature in Acrobat 9.

Adobe Acrobat 9 comes with a set of PDF Portfolio layouts and these are great for the general use case of bundling up a set of files and sending them around as a single PDF file. There are some basic features to customize headers and welcome screens and to apply different color palettes. But, with Acrobat 9, we introduced a built-in Flash player a rich ActionScript API that can be used to create highly branded custom PDF Portfolio layouts or, as I'll refer to them for the remainer of this series, "Navigators".

Each article in this series will cover a single topic related to learning the Acrobat ActionScript API and eventually developing your own custom navigator. The Acrobat ActionScript SDK and the example Flex projects will be linked to at the end of each article. Additionally, each article will include a brief video introduction so you can get an idea of what the examples will show.

You can get started by watching the first video and then coming back here for more details on customizing PDF Portfolio Layouts.

What You'll Need to Get Started:

What You Need Where to get it if you havn't got it:
Adobe Acrobat 9 Pro or
Adobe Acrobat 9 Pro Extended
If you don't already have a copy of Acrobat, you can buy it here. For Windows users, you can download a fully functional 30 day trial here.Sorry - we don't have a trial version for OSX.
Flex Builder 3 You can purchase or download a 60 day free trial of Flex Builder 3 here
Note: If you have updated from version 3.0 of Flex Builder. You will need to download and install the 3.0 SDK. The AcrobatAPI.swc won't work with higher versions of the Flex SDK.
The Acrobat 9 ActionScript SDK (Prerelease version) You can get The Acrobat 9 ActionScript SDK here. This is a prerelease version but any navigators that you build will work with Acrobat 9.0 and higher.
An XML or simple text editor. You won't actually need this until the Part 2 of this series. When I'm working on my Navigators, I like to keep everything in Flex so I use XMLBuddy but have been known to DreamWeaver for XML editing too.
Zip archiving tool. Again, I like to keep everything in Flex so I use Flex Ant Tasks to zip my files up into a Navigator. Instructions on how to set this up are in Part 2.

A PDF Portfolio Navigator includes a SWF application that can be used to navigate the contents of a PDF Portfolio. The application can do just about anything that you can program in ActinScript 3 and can play in version 9 of the Flash Player. The .NAV file, a container format that holds the SWF, can also reference other files video clips, images, and sound files to provide a rich multi-media experience. The ActionScript application can interact with PDF Portfolios through the Acrobat ActionScript API (AcrobatAPI.swc).

Acrobat Pro and Acrobat Pro Extended let you apply PDF Portfolio Navigators to a PDF Portfolio. When a Navigator is applied to the PDF Portfolio and the Portfolio is saved, the Navigator is saved into the Portfolio. For this reason, you may want to be careful when it comes to including video or large graphics.

The "Hello World" Example:

The "Hello World" example is a very basic navigator that simply displays a list of the files in the PDF Portfolio. However, it does demonstrate the basic plumbing required to bootstrap any custom navigator. The example code and the Acrobat 9 ActionScript SDK are linked to at the end of this article.

Five steps to bootstrapping your navigator:

Step 1: Create the top level object. Use a "Module" rather than an "Application" and implement the "acrobat.collection.INavigator" interface. The INavigator interface enables the initial hand shake with the Acrobat ActionScript API. Its only member is the set host function, which your application implements. During the initialize cycle, the Acrobat ActionScript API invokes your set host function. Your set host function then initializes itself, can add event listeners, and performs other setup tasks.Your code might look something like this.

<mx:Module
     xmlns:mx="http://www.adobe.com/2006/mxml"
     implements="acrobat.collection.INavigator"
     height="100%" width="100%"
     horizontalScrollPolicy="off" verticalScrollPolicy="off"
>

Step 2: Create your user interface elements. In this example, I'm using a "DataGrid" which is overkill for a simple list but I'm going to expand on this example in the future. Also notice that I'm using "fileName" in the dataField. The "fileName" is a property of an item in the PDF Portfolio "items" collection. Later when we set the dataProvider of the DataGrid, the grid will fill with the fileNames of the files in the Portfolio.

<mx:DataGrid id="itemList" initialize="onInitialize()" width="350" rowCount="12">
     <mx:columns>
          <mx:DataGridColumn dataField="fileName" headerText="Name"/>
     </mx:columns>
</mx:DataGrid>    

Step 3: Respond to the "initialize" event during the creation of your interface components. This is important because there is no coordination of the Flash Player's initialization of your UI components and the set host(), so these two important milestone events in your navigator's startup phase could occur in either order. The gist of a good way to handler this race condition is to have both your INavigator.set host() implementation and your initialize() or creationComplete() handler both funnel into a common function that starts interacting with the collection only after you have a non-null host and an initialized UI. You'll see in the code samples below and in step 4, both events funnel into the "startEverything()" function. I'll duscuss that function in the 5th step.

			private function onInitialize():void 
			{
				_listInitialized = true; 
				startEverything();
			}

Step 4: Respond when Acrobat finishes creating the PDF portfolio navigator interface. The "set host()" is called early with a non-null host instance, at which point the PDF portfolio navigator can initialize itself and add event listeners. This is likely to occur shortly after construction and may occur before any children have been added (in the case of MXML components). When the host shuts down, the PDF portfolio navigator calls this method once again with a value of null. At this point the INavigator instance is expected to shut itself down.

			public function set host(host:INavigatorHost):void 
			{
				if(host != null) {
					_host = host;					
					startEverything();						
				} else {
					_host = null;
					Alert.show("Navigator Ending");
				}
			}

Step 5: Populate the PDF portfolio navigator with PDF portfolio information. Now the I have a connection to the host and my UI is ready to be populated, I can set the dataProvider on the DataGrid.

			private function startEverything():void 
			{
				if(_host && _listInitialized)
				{
					Alert.show("Navigator Started");
					itemList.dataProvider = currentItems;
				}	
			}

Notice I'm using the variable "currentItems" as the dataProvider. The "Binding" statement below requires some clarification.The "acrobat.collection" or in this case the "_host" INavigatorHost object has a "currentFolder" property. If this property is "false" then Acrobat is looking at the root of the PDF Portfolio. If it is true, then Acrobat is looking at a folder within the Portfolio.The Binding statement uses the currentFolder property to keep the currentItems object set to whatever Acrobat is looking at.This allows the user to switch to the list view of a PDF Portfolio, which will unload your navigator, and then come back to your navigator without losing their place in the folder hierarchy.

<mx:Binding 
destination="currentItems"
source="_host.currentFolder ? new ListCollectionView(_host.currentFolder.children) : new ListCollectionView(_host.collection.items)" />

These five steps are the basics of getting a your ActionScript code connected to the Acrobat API and are necessary for any Navigator to start up properly. I'll expand on this example and show you how to actually interact with the PDF Portfolio in future articles.

Files:
The Acrobat 9 ActionScript SDK
The Hello World Flex Project

After downloading this example and compiling the code, you can install the Navigator by following these simple steps.

Installation:

Windows:

1. From Windows, select "Start" then "Run". Paste the following line into the text box and press enter

%USERPROFILE%\Application Data\Adobe\Acrobat\9.0\

2. Create a directory called "navigators" if you don't already have one

3. Drag the "_01_HelloWorld.swf" file to the "navigators" directory
4. Restart Acrobat if it's running.
5. In the "Edit PDF Portfolio" panel you should see an "Other Layouts" category in addition to "Basic Layouts"

OSX:

1. Open Finder.
2. Browse to this location: /Applications/Adobe Acrobat 9 Pro/Adobe Acrobat Pro
3. Hold the Ctrl key and select the Adobe Acrobat Pro application. Choose Show Package Contents.
4. Browse to this folder location in the Adobe Acrobat Pro application: /Contents/Resources/en.lproj/Navigators
5. Drag the "_01_HelloWorld.swf" file to this location in Finder.
6. Restart Acrobat if it's running.
7. In the "Edit PDF Portfolio" panel you should see an "Other Layouts" category in addition to "Basic Layouts"

Conclusion:

I kept this first article pretty short and the code pretty simple so that you can see how easy it is to connect your code to the Acrobat API. All Navigators will build off of this initial model. In Part 2, I'll discuss how to bundle the "bald" .swf into a full blown navigator file.