Adobe
Products
Acrobat
Creative Cloud
Creative Suite
Digital Marketing Suite
Digital Publishing Suite
Elements
Photoshop
Touch Apps
Student and Teacher Editions
More products
Solutions
Creative tools for business
Digital marketing
Digital media
Education
Financial services
Government
Web Experience Management
More solutions
Learning Help Downloads Company
Buy
Home use for personal and home office
Education for students, educators, and staff
Business for small and medium businesses
Licensing programs for businesses, schools, and government
Special offers
Search
 
Info Sign in
Welcome,
My cart
My orders My Adobe
My Adobe
My orders
My information
My preferences
My products and services
Sign out
Why sign in? Sign in to manage your account and access trial downloads, product extensions, community areas, and more.
Adobe
Products Sections Buy   Search  
Solutions Company
Help Learning
Sign in Sign out My orders My Adobe
Preorder Estimated Availability Date. Your credit card will not be charged until the product is shipped. Estimated availability date is subject to change. Preorder Estimated Availability Date. Your credit card will not be charged until the product is ready to download. Estimated availability date is subject to change.
Qty:
Purchase requires verification of academic eligibility
Subtotal
Review and Checkout
Adobe Developer Connection / Flash Developer Center /

Creating the Kuler panel for Flash CS3 Professional

by Ben Pritchard

Ben Pritchard
  • pixelfumes.com

Modified

2 February 2009

Page tools

Share on Facebook
Share on Twitter
Share on LinkedIn
Bookmark
Print
ActionScript components Flash Professional CS4 JSFL

Requirements

Prerequisite knowledge

This article is intended for Flash developers who have an intermediate understanding of ActionScript, ActionScript classes, and JSFL. Before you get started, install the Kuler panel for Flash CS3, available in the source code linked to above. You can familiarize yourself with the panel's functionality without installing it by watching a demo of the panel in action created by John Nack, senior product manager of Adobe Photoshop.

Familiarity with the Kuler API may be of additional benefit as well. You can familiarize yourself with the Kuler API by visiting the Kuler API page in the Adobe Developer Connection.

User Level

Intermediate

Sample files

  • kuler_panel_source.zip (747 KB)

A while ago I took the opportunity to brush up on my ActionScript 3.0 proficiency by creating a custom panel for Adobe Flash CS3 Professional. I have been a big fan of the Kuler web-hosted application, not to mention the different display incarnations to which it has been ported. I felt that I would try to make my contribution to the Flash community as well. This article provides you with an overview of how I created the Kuler panel for Flash CS3 Professional (see Figure 1) and highlights some of the great new features and methods it gives you in the Flash authoring environment—as well as the Kuler APIs.

kuler panel for Flash CS3 Professional
Figure 1. Kuler panel for Flash CS3 Professional

Flash CS4 Professional users enjoy the added benefit of having a native Kuler panel in the IDE (accessible from Window > Extensions), which allows them to create Kuler themes directly from Flash. For those of you who might not have had the opportunity to upgrade yet, this panel will provide you with the ability to use Kuler themes that you and others have created.

Kuler background

Kuler is a great color theme-sharing tool released by Adobe. It started out as a web-based application that enabled users to create, save, and download community-created color themes or harmonies. Downloaded themes are provided in the Adobe Swatch Exchange (ASE) format, enabling users to access the themes in their Creative Suite products. Users can create and rate themes, as well as filter them by most recent, popular, and highest rated. The Kuler website also provides search functionality and RSS feeds that list the different filtered theme lists.

Kuler was then released as a Dashboard widget for Mac OS X (see Figure 2; download (ZIP, 164K). This brought to the user's desktop the ability to browse through color themes. Colors can be selected and copied to the Clipboard for use.

kuler Dashboard widget for Mac OS X
Figure 2. Kuler Dashboard widget for Mac OS X

Adobe has released an AIR version of Kuler (see Figure 3; download (AIR, 627K). This cross-platform version of Kuler can be used right on the user's desktop.

Adobe AIR version of kuler
Figure 3. Adobe AIR version of Kuler

The Kuler API

Porting the Kuler application is quite easy because Adobe provides an API to return RSS feeds for each of the Kuler filters. You can easily consume the Kuler API feeds and display the results in your own custom user interface. This is what led me to the development of the Kuler panel for Flash CS3 Professional.

The Kuler API provides a set of URLs that return RSS feeds. These APIs give additional functionality over the current kuler.adobe.com interface and RSS feeds by providing such features as returning images of the swatches in a color theme.

Additional information on the usage of the Kuler API can be found on the Kuler API page in the Adobe Developer Connection.

Designing the user interface

One of the most important things to take into account when developing a custom panel for Flash CS3 Professional is ease of use. Adobe provided a great UI style for Kuler, so I decided to follow their lead and style the panel UI after the web-based, Dashboard widget, and Adobe AIR versions of the application. In Figure 4 you can see what I started off with. The UI primarily consists of a V3 Flash Scroll Pane component, an input text area, and controls to select the feed the user wants to view.

Original kuler panel UI
Figure 4. Original Kuler panel UI

Constructing the user interface and complementing code

Skinning the Version 3 (V3) components (see Figure 5) is an extremely easy task compared to modifying earlier versions of the UI components. You can modify the appearance of the component simply by double-clicking it and editing it in Flash as you would any other movie clip.

Skinning scrollbar components
Figure 5. Skinning scroll bar components

The main Timeline of your Flash panel is responsible for tying the code from your ActionScript classes together. The primary classes that I created for the panel were JSFLKuler and KulerItem. I will show you how these classes are implemented on the main Timeline of the panel:

import com.pixelfumes.kuler.*; import flash.events.Event;

Grant Skinner recently released several classes that enable you to modify properties such as the scroll bars' width of the V3 components easily. I imported these classes as well, because I really wanted to tweak the way the scroll bars look on the default scroll pane:

import fl.managers.StyleManager; StyleManager.setStyle("scrollBarWidth",11);

I instantiate an instance of the JSFLKuler class here and give it a variable name of kuler. I then tell it to load the RSS feed for the most recent color combinations in Kuler using the Adobe Kuler API. Notice the use of my developer key in the URL for the feed. The Adobe Kuler API requires the use of a valid developer key in order to return a feed. You can sign up for your own developer key on the Kuler API page.

Once we have a valid developer key we are able to instantiate the instance of the JSFLKuler class using the following code:

var devKey:String = "29CE344635AB36DB7F2A50B3C8AC7E55"; kuler.loadFeed("http://kuler-api.adobe.com/rss/get.cfm?listtype=recent&key="+devKey);

In order to tell when the RSS feed has loaded or failed, I set up listeners that will listen for the JSFLKuler class to dispatch the FEED_LOADED or FEED_FAILED event:

kuler.addEventListener(com.pixelfumes.kuler.JSFLKuler.FEED_LOADED,onFeedReady); kuler.addEventListener(com.pixelfumes.kuler.JSFLKuler.FEED_FAILED,onFeedFailed);

There are several different ways to populate the new V3 ScollPane component with content. In this case I create a new, blank movie clip named stubMC. I set stubMC as the source for the scroll pane, which has an instance name of sp. Now any items that I add to stubMC will appear within the scroll pane:

var stubMC:MovieClip = new MovieClip(); sp.source = stubMC;

When the feed is loaded, I can loop through the results and create instances of the KulerItem class, the class that handles the display of each swatch group. Using the getItemCount method from the JSFLKuler class, I can get the number of swatch groups I am working with.

As I loop through the items, I assign the name, swatch colors, and rating that I parse from the RSS feed. In the code below, you will notice that I am instantiating instances of the KulerItem class. This works a little like the attachMovie method from ActionScript 2.0 in this case. I will cover the KulerItem class in detail later in this article:

function onFeedReady(e:Event):void{ if(kuler.getItemCount() < 1){ feedControl_mc.status_txt.text = "No Results"; }else{ for(var i:uint=0;i<kuler.getItemCount();i++){ var ki = new KulerItem(); stubMC.addChild(ki); ki.y = i*60; ki.setLabel(kuler.getItem(i).title); ki.setSwatchColors(kuler.getItem(i).hexColor) ki.setRating(kuler.getItem(i).rating); } sp.refreshPane(); } hidePreloader() }

In the event that the RSS feed load should fail, you need to display a notification to the user:

function onFeedFailed(e:Event):void{ feedControl_mc.status_txt.text = "Feed Load Failed"; hidePreloader(); }

In order to remove items from the stubMC with the scroll pane, I simply set the stubMC to null and recreate it as a fresh, empty movie clip. I use this function primarily to wipe the previous swatch groups from the panel display each time a new RSS feed is loaded:

function removeKulerItems():void{ stubMC = null; stubMC = new MovieClip(); sp.source = stubMC; }

Listening for the click on an instance of KulerItem is easy: I simply add an event listener for the ITEM_SELECTED event to be broadcast. This fires the onItemSelected function on the main Timeline:

this.addEventListener(com.pixelfumes.kuler.KulerItem.ITEM_SELECTED, onItemSelected);

The onItemSelected function gathers arguments such as the swatch colors, swatch group name, and rating from the event that is broadcast and uses them as arguments being passed to the JSFL function:

function onItemSelected(e:Event):void{ var args:Array = e.target.swatchColors; args.push(escape(e.target.schemeName)); trace(e.target.swatchColors); executeJSFL(["kuler/kuler.jsfl","addSwatches",args]); }

JSFL file and general panel creation notes

The JSFL file for the Kuler panel handles the click of a color theme within your panel. Its job is to accept the arguments passed to it and use them to display the color swatches on the Stage. As you saw previously, the onItemSelected event function calls a function within a JSFL file named kuler.jsfl. This file should be located in your Commands folder and inside of a folder named kuler.

If you are unfamiliar with the creation of a custom panel for Flash, this procedure may be new for you. Your JSFL file will be called from the Kuler panel SWF file, which I named kuler.swf. This is really just a SWF file that resides within a folder on your system called WindowSWF. After your panel files have been created, they will need to be located in the following directories on your system:

  • kuler.swf (primary panel file)

    Windows Vista:[boot drive]\Users\username\Local Settings\Application Data\Adobe\Flash CS3\language\Configuration\WindowSWF

    Windows XP: [boot drive]\Documents and Settings\user\Local Settings\Application Data\Adobe\Flash CS3\language\Configuration\WindowSWF

    Mac OS X:[hard drive]/Users/userName/Library/Application Support/Adobe/Flash CS3/language/Configuration/WindowSWF

    Windows XP:[boot drive]\Documents and Settings\user\Local Settings\Application Data\Adobe\Flash CS3\language\Configuration\WindowSWF

    Mac OS X:[hard drive]/Users/userName/Library/Application Support/Adobe/Flash CS3/language/Configuration/WindowSWF

  • kuler.jsfl

    Windows Vista:[boot] drive\Users\username\Local Settings\Application Data\Adobe\Flash CS3\language\Configuration\Commands\kuler

    Windows XP:[boot] drive\Documents and Settings\user\Local Settings\Application Data\Adobe\Flash CS3\language\Configuration\Commands\kuler

    Mac OS X:[hard drive]/Users/userName/Library/Application Support/Adobe/Flash CS3/language/Configuration/Commands/kuler

As you are testing and creating these files, it is a good idea to place them in their proper locations. Having your Kuler FLA file publish to the WindowsSWF directory enables you to test the panel each time you publish it. You can access the panel by selecting Window > Other Panels > [Your SWF] from the main Flash menu. To see updates to the SWF file, you must close the panel and reopen it each time you republish the SWF file.

Examining the JSFL functions

The JSFL file itself contains only two functions: one to add the selected swatches to the Stage that the user has selected and one to display an alert box when the user clicks the info button at the bottom of the panel.

Take a look at the first function, called addSwatches. This function is passed a single argument containing six items. Items one through five contain the hex codes for the swatch group that was clicked, and the sixth item passes in the name of the color theme:

function addSwatches(args){ colors = args.split(","); schemeName = colors[5];

Now that the arguments have been split apart, you can use the theme name to create a new layer within your current Flash document:

var layer = fl.getDocumentDOM().getTimeline().addNewLayer("** Kuler - "+unescape(schemeName)+" **"); _fill = fl.getDocumentDOM().getCustomFill("toolbar");

Next, you can create your swatches on the new layer. In the case below, your swatches will be squares that are 50 pixels wide. You can loop through each swatch in the color theme and apply the hex value to the squares you create using the JSFL addNewRectangle method:

var swatchSize = 50; for(i=0;i<5;i++){ if(colors[i] != undefined){ _fill.color = "#"+colors[i]; _fill.style = "solid"; fl.getDocumentDOM().setCustomFill(_fill); fl.getDocumentDOM().addNewRectangle({left:i*swatchSize,top:0,right:swatchSize+swatchSize*i,bottom:swatchSize},0,false,true); } } }

Finally, the second function enables you to use a simple alert call to display additional information about your panel:

function showInfo(){ alert("Written by Pixelfumes 2008\nwww.pixelfumes.com\nKuler Panel for Flash CS3 Version 1.4\nKuler is a registered trademark of Adobe."); }

Consuming the Kuler RSS feeds

Flash CS3 Professional gives you some great new methods for handling XML loading and parsing. In the example below, you will see the primary class for the Kuler panel.

The JSFLKuler class is responsible for loading and parsing the Kuler API RSS feeds. I also use the same class to gather information from each of the swatch sets I get from the Kuler API feed. I then use E4X methods to parse through the RSS once it is loaded. Because the JSFLKuler class extends the EventDispatcher class, I can dispatch events to other objects within the panel. In this case I have created FEED_LOADED and FEED_FAILED static variables, which will serve as the events being dispatched. I am able to listen on the main Timeline for these events to fire:

package com.pixelfumes.kuler{ import flash.events.*; import flash.net.URLLoader; import flash.net.URLRequest; import flash.xml.XMLDocument; public class JSFLKuler extends EventDispatcher{ private var feedXML:XML; private var kulerNS:Namespace private var xmlLoader:URLLoader; private var xmlString:URLRequest; private var kulerItem:XMLList; private var kulerThemeItem:XMLList; private var kulerItemCount:int; public static const FEED_LOADED:String = "feedLoaded"; public static const FEED_FAILED:String = "feedFailed"; function JSFLKuler(){ } public function loadFeed(feedURL:String):void{ if(xmlLoader){ xmlLoader.close(); } xmlString = new URLRequest(feedURL); xmlLoader = new URLLoader(xmlString); xmlLoader.addEventListener("complete", onFeedLoaded); xmlLoader.addEventListener(IOErrorEvent.IO_ERROR,onFeedFailed); } private function onFeedFailed(ioError:IOErrorEvent):void{ dispatchEvent(new Event(JSFLKuler.FEED_FAILED)); }

It is important to note that consuming the RSS feed from the Kuler API may be a bit different than you are used to, because it contains a kuler namespace. For example, the nodes that you will be parsing through appear as such:

<kuler:themeItem>

The XML namespace is defined at the top of the RSS feed:

<rss xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:kuler="http://kuler.adobe.com/kuler/API/rss/" xmlns:rss=http://blogs.law.harvard.edu/tech/rss version="2.0">

ActionScript 3.0 gives you the ability to set the namespace you are parsing through. In this case, the namespace is kuler. I set the namespace in the script using the following code:

private function onFeedLoaded(event:Event):void{ var xDoc:XMLDocument = new XMLDocument(); xDoc.ignoreWhite = true; feedXML = new XML(xmlLoader.data); kulerNS = feedXML.namespace("kuler"); //E4X parsing kulerItem = feedXML..item; kulerItemCount = feedXML..item.length(); dispatchEvent(new Event(JSFLKuler.FEED_LOADED)); }

The JSFLKuler class also provides methods for returning the number of swatch groups in the RSS feed and a method for gathering data from each of them:

public function getItemCount():Number{ return kulerItemCount; } public function getItem(n):Object{ var obj:Object = new Object(); obj.title = kulerItem[n]..kulerNS::themeTitle; obj.themeID = kulerItem[n]..kulerNS::themeID; obj.downloadCount = kulerItem[n]..kulerNS::themeDownloadCount; obj.createdAt = kulerItem[n]..kulerNS::themeCreatedAt; obj.editedAt = kulerItem[n]..kulerNS::themeEditedAt; obj.authorID = kulerItem[n]..kulerNS::authorID; obj.authorLabel = kulerItem[n]..kulerNS::authorLabel; obj.rating = kulerItem[n]..kulerNS::themeRating; obj.link = kulerItem[n].link; obj.hexColor = [kulerItem[n]..kulerNS::swatchHexColor[0],kulerItem[n]..kulerNS::swatchHexColor[1],kulerItem[n]..kulerNS::swatchHexColor[2],kulerItem[n]..kulerNS::swatchHexColor[3],kulerItem[n]..kulerNS::swatchHexColor[4]]; obj.description = kulerItem[n].description; return obj; }

Displaying the Kuler swatches

The KulerItem class is attached to a movie clip within the Library (see Figure 6). Because ActionScript 3.0 does not contain an attachMovie method, I use an external class to handle the creation and manipulation of instances of the clip itself. Displaying these movie clips is as simple as the code I used in the onFeedReadyevent on my main Timeline:

var ki = new KulerItem(); stubMC.addChild(ki);

The addChild method visually adds the kuler_mc clip from my Library to the Stage and applies the methods and properties assigned to it through the KulerItem class.

Setting the properties that link the KulerItem class to a movie clip
Figure 6. Setting the properties that link the KulerItem class to a movie clip

The KulerItem class needs to extend MovieClip because it is a movie clip in the Library. This ensures that I have access to all of the methods and properties inherent to the MovieClip class.

I also need access to the EventDispatcher class in order to broadcast events. Classes can extend only one class, so I must implement the IEventDispatcher class. This implements an interface for the EventDispatcher class and gives me access to its methods:

public class KulerItem extends MovieClip implements IEventDispatcher{ private var swatchTween:Tween; public var swatchColors:Array; public var schemeName:String;

Next, I can assign event listeners that will handle this item's interactions:

public static const ITEM_SELECTED:String = "itemSelected"; function KulerItem(){ this.addEventListener("mouseOver",onMouseOver); this.addEventListener("mouseOut",onMouseOut); this.addEventListener("mouseDown",onMouseDown); } public function onMouseDown(e:Event):void{ dispatchEvent(new Event(KulerItem.ITEM_SELECTED,true)); }

Because I know that I am actually within the kulerItem_mc within the Library, I can address other objects within that scope. In this case I am setting events that will grow and shrink the swatchBlock movie clips on the Timeline of kulerItem_mc:

public function onMouseOver(e:Event):void{ swatchTween = null; swatchTween = new Tween(this.swatchBlock1_mc, "scaleX", Strong.easeOut, this.swatchBlock1_mc.scaleX, 3.5, 1, true); swatchTween.addEventListener("motionChange",onMotionChanged); } private function onMotionChanged(e:Event):void{ this.swatchBlock2_mc.x = this.swatchBlock1_mc.x + this.swatchBlock1_mc.width; this.swatchBlock2_mc.scaleX = this.swatchBlock1_mc.scaleX; this.swatchBlock3_mc.x = this.swatchBlock2_mc.x + this.swatchBlock2_mc.width; this.swatchBlock3_mc.scaleX = this.swatchBlock1_mc.scaleX; this.swatchBlock4_mc.x = this.swatchBlock3_mc.x + this.swatchBlock3_mc.width; this.swatchBlock4_mc.scaleX = this.swatchBlock1_mc.scaleX; this.swatchBlock5_mc.x = this.swatchBlock4_mc.x + this.swatchBlock4_mc.width; this.swatchBlock5_mc.scaleX = this.swatchBlock1_mc.scaleX; } public function onMouseOut(e:Event):void{ swatchTween = null; var swatchTween:Tween = new Tween(this.swatchBlock1_mc, "scaleX", Strong.easeOut, this.swatchBlock1_mc.scaleX, 1, 1, true); swatchTween.addEventListener("motionChange",onMotionChanged); } public function setLabel(s:String):void{ this.label_txt.text = s; this.schemeName = s; } public function setSwatchColors(a:Array):void{ this.swatchColors = a; for(var i:uint=0;i<5;i++){ var target:MovieClip = this["swatchBlock"+(i+1)+"_mc"]; var colorTransform:ColorTransform = target.transform.colorTransform; colorTransform.color = parseInt(a[i],16); if(a[i] == undefined){ target.visible = false; }else{ target.transform.colorTransform = colorTransform; } } } public function setRating(n:Number):void{ for(var i:uint=0;i<n;i++){ var target:MovieClip = this["star"+(i+1)+"_mc"]; var colorTransform:ColorTransform = target.transform.colorTransform; colorTransform.color = 0x999999; target.transform.colorTransform = colorTransform; } }

Where to go from here

Panels can be much more complex than this example, and can take a good deal of time to create and test. To help you best understand the examples and code displayed in this article, I suggest downloading the panel's source code and playing with it.

Be sure to check out the Kuler APIs as well, as it offers numerous feeds to provide you with new methods of searching and gathering data on Kuler themes. Keep those Kuler swatches coming!

More Like This

  • Five demos of Flash CS4 Professional
  • Exploring the new 3D features in Flash CS4 Professional
  • Automating tasks with JavaScript Flash
  • Combining animation and ActionScript using Flash Professional CS5 and Flash Builder 4
  • 3D view controller in Flash using ActionScript 3
  • Using the FLVPlayback component with Flash Player 9 Update 3
  • Creating your first ActionScript 3 class
  • Creating movie clips with reflections in ActionScript 3.0
  • Skinning the Flash CS3 components
  • 3D moving stars in Flash using ActionScript 3

Flash User Forum

More
04/23/2012 Auto-Save and Auto-Recovery
04/23/2012 Open hyperlinks in new window/tab/pop-up ?
04/21/2012 PNG transparencies glitched
04/01/2010 Workaround for JSFL shape selection bug?

Flash Cookbooks

More
02/13/2012 Randomize an array
02/11/2012 How to create a Facebook fan page with Flash
02/08/2012 Digital Clock
01/18/2012 Recording webcam video & audio in a flv file on local drive

Products

  • Acrobat
  • Creative Cloud
  • Creative Suite
  • Digital Marketing Suite
  • Digital Publishing Suite
  • Elements
  • Mobile Apps
  • Photoshop
  • Touch Apps
  • Student and Teacher Editions

Solutions

  • Digital marketing
  • Digital media
  • Web Experience Management

Industries

  • Education
  • Financial services
  • Government

Help

  • Product help centers
  • Orders and returns
  • Downloading and installing
  • My Adobe

Learning

  • Adobe Developer Connection
  • Adobe TV
  • Training and certification
  • Forums
  • Design Center

Ways to buy

  • For personal and home office
  • For students, educators, and staff
  • For small and medium businesses
  • For businesses, schools, and government
  • Special offers

Downloads

  • Adobe Reader
  • Adobe Flash Player
  • Adobe AIR
  • Adobe Shockwave Player

Company

  • News room
  • Partner programs
  • Corporate social responsibility
  • Career opportunities
  • Investor Relations
  • Events
  • Legal
  • Security
  • Contact Adobe
Choose your region United States (Change)
Choose your region Close

North America

Europe, Middle East and Africa

Asia Pacific

  • Canada - English
  • Canada - Français
  • Latinoamérica
  • México
  • United States

South America

  • Brasil
  • Africa - English
  • Österreich - Deutsch
  • Belgium - English
  • Belgique - Français
  • België - Nederlands
  • България
  • Hrvatska
  • Česká republika
  • Danmark
  • Eastern Europe - English
  • Eesti
  • Suomi
  • France
  • Deutschland
  • Magyarország
  • Ireland
  • Israel - English
  • ישראל - עברית
  • Italia
  • Latvija
  • Lietuva
  • Luxembourg - Deutsch
  • Luxembourg - English
  • Luxembourg - Français
  • الشرق الأوسط وشمال أفريقيا - اللغة العربية
  • Middle East and North Africa - English
  • Moyen-Orient et Afrique du Nord - Français
  • Nederland
  • Norge
  • Polska
  • Portugal
  • România
  • Россия
  • Srbija
  • Slovensko
  • Slovenija
  • España
  • Sverige
  • Schweiz - Deutsch
  • Suisse - Français
  • Svizzera - Italiano
  • Türkiye
  • Україна
  • United Kingdom
  • Australia
  • 中国
  • 中國香港特別行政區
  • Hong Kong S.A.R. of China
  • India - English
  • 日本
  • 한국
  • New Zealand
  • 台灣

Southeast Asia

  • Includes Indonesia, Malaysia, Philippines, Singapore, Thailand, and Vietnam - English

Copyright © 2012 Adobe Systems Incorporated. All rights reserved.

Terms of Use | Privacy Policy and Cookies (Updated)

Ad Choices

Reviewed by TRUSTe: site privacy statement