Postcards From My Life

Lint I find in my mind's belly-button.
  • EPK
  • Consulting
  • Resume
  • Nerd Herding
  • Talks
  • How to Plan a Website
  • Zend Framework
« Open Teams
Dynamically loading images from the web in Flex 3 »

A Flex 3 custom events primer

Dear Reader,

I am a web developer. It’s been over 10 years since I’ve done serious desktop application development. So when I fire up Flex Builder to write my first AIR application, it takes a while for things to start coming back to me. One of the things that is only now starting to come back is Event Driven Programming.

This past week I decided to start working on a small project to scratch a personal itch. The project itself fizzled but I learned something none-the-less. I learned how to create custom events in Flex 3.

The project required selecting a file for processing. Flex 3 has a control for actually opening the dialog box and selecting the file but no control that shows the button and the selected file name.


Since I plan on working with Flex a lot, I decided to start my own library of controls and build my own. The first thing I learned is that to be included in a package, you have to use code, not visual classes. Here’s the code for my FilePicker control.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package com.calevans.controls
{
	import com.calevans.Events.FileSelected;
 
	import flash.events.Event;
	import flash.filesystem.*;
 
	import mx.binding.utils.BindingUtils;
	import mx.containers.HBox;
	import mx.controls.Button;
	import mx.controls.Spacer;
	import mx.controls.TextInput;            
 
	[Event(name="fileSelected", type="com.calevans.Events.FileSelected")]
	public class FilePicker extends HBox
	{
		[Bindable] public var buttonLabel:String = "Select File";
 
		protected var selectedFile:File;
		protected var btnMain:Button;
		protected var tiFileName:TextInput;
 
		private var defaultDirectory:File; // The default directory
 
		public function FilePicker()
		{
			defaultDirectory = File.documentsDirectory;
			this.addChild(new Spacer());
			/*
			 * Select file Button
			 */
			btnMain = new Button();
			btnMain.addEventListener('click', openFile);
			BindingUtils.bindProperty(btnMain,"label",this,"buttonLabel");
			this.addChild(btnMain);
 
			/*
			 * textInput to display the file name
			 */
			tiFileName = new TextInput();
			tiFileName.percentWidth=100;
			tiFileName.editable=false;
			this.addChild(tiFileName);
 
			this.addChild(new Spacer());
			return;					
		}
 
 
		private function openFile(event:Event):void 
		{	
			var fileChooser:File;
			fileChooser = defaultDirectory;
			fileChooser.browseForOpen("Open");
			fileChooser.addEventListener(Event.SELECT, fileOpenSelected);
			return;
		}
 
		private function fileOpenSelected(event:Event):void 
		{
			selectedFile = event.target as File;
			selectedFile.removeEventListener(Event.SELECT, fileOpenSelected);
			tiFileName.text = selectedFile.nativePath;
			dispatchEvent(new FileSelected(FileSelected.FILE_SELECTED,false,false,selectedFile)); 
			return;
		}
 
 
	}
}

As you can see, there’s not a lot of ground breaking code here. Most of this is standard Actionscript code. However, once I got it written and working, I realized that to be useful in an application, something needed to happen in the main application after I selected the file. I knew what I needed, I need for the control to allow me to define an event and assign it code to execute.

Looking through the docs was informative but confusing. Most of the examples I could find on the web were contrived and not really helpful. I finally pieced together almost all of the piece. With the help of my friend Marco Tabini I got it working. Here’s what I did.

The first thing you have to do is define an Event class. Here is mine.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.calevans.Events
{
    import flash.events.Event;
    import flash.filesystem.File;
 
    public class FileSelected extends Event
	{
		public static const FILE_SELECTED:String = 'fileSelected';
		private var _selectedFile:File;
 
	   // Public constructor.
		public function FileSelected(type:String, bubbles:Boolean, cancelable:Boolean, selectedFile:File=null) 
		{
			super(type,bubbles,cancelable);
			_selectedFile = selectedFile;
			return;
		}
 
		public function get selectedFile():File{
			return _selectedFile;
		}
 
		override public function clone():Event 
		{
            return new FileSelected(type, bubbles, cancelable, _selectedFile);
        }
 
	}
}

I am still new at Flex so I’m not going to pretend to tell you what each of these pieces mean. My hope is to tell you what you need to get it working.

  1. The constructor, you can pass your own parameters in but you have to pass in the first three. Inside the constructor, call the super passing the three default parameters
  2. You have to override the clone function. I don’t know why but every tutorial out there said you had to. Make sure you pass the standard parameters plus any custom parameters you defined. The signature has to match the constructor.
  3. The public static constant is important as it define the name (or names) of the events you can dispatch with this class.

Now to use it.

1
<controls :filepicker="" buttonlabel="Select File" width="90%" fileselected="doMe(event);"></controls>

The thing I missed in all the tutorials was this.

1
2
3
public static const FILE_SELECTED:String = 'fileSelected';
[Event(name="fileSelected", type="com.calevans.Events.FileSelected")]
<controls :filepicker="" buttonlabel="Select File" width="90%" fileselected="doMe(event);"></controls>

In all three of these lines above, the word “fileSelected” has to match. The first one is the constant in the Event class, you have to define this. The second one is where you tell Flex that this control will dispatch a custom event, the name of it has to be the same as one of the constants in the class. You can define multiple constants in the same class to allow the class to be used multiple times.

The third one is the MXML definition of the use of the class. If you’ve done everything right, Flex Builder will know that your control has a custom event fileSelected and show it in the list of properties, methods and events.

The final piece that I missed was actually dispatching the event. I’m not sure what I was thinking but I got everything working and it still wasn’t dispatching the event and calling my function. The simple piece I missed was that I had to tell my code when to dispatch the event.

dispatchEvent(new FileSelected(FileSelected.FILE_SELECTED,false,false,selectedFile));

Adding that to FilePicker.as in the fileOpenSelected method solved the problem.

Side Note: As far as I can tell, this particular control will only work in AIR apps as Flash doesn’t have direct access to the file system. (I could be wrong on that though, please feel free to correct me)

This is a very simple example of a custom event but it’s a working one and not a contrived example. If you are struggling with them, put this code in your test application and play with it. Break it and fix it and see what is possible. While I’m sad that I couldn’t actually build the tool I wanted to build, it’s always nice to take something away from every project.

Until next time,
I <3 |<
=C=

[DISCLAIMER: I work with Blue Parabola, Adobe is a customer of Blue Parabola. ]

Buffer

Tags: adobe, air, events, flex, flex builder, marco tabini

This entry was posted on Monday, February 15th, 2010 at 7:30 am and is filed under Flex, Programming. You can follow any responses to this entry through the RSS 2.0 feed. Both comments and pings are currently closed.

Logging In...

Comments are closed.

  • 2 Replies
  • 2 Comments
  • 0 Tweets
  • 0 Facebook
  • 0 Pingbacks
Last reply was February 20, 2010
  1. Tim
    View February 16, 2010

    Most of the time the clone method won’t factor in but here’s an explanation for you.

    http://life.neophi.com/danielr/2006/06/events_in_flex_2.html

    When you re-dispatch an event the clone method is used to create a “copy” of the event so you if you don’t have one defined you can run into trouble. It’s a good habit to develop just for this case which might not happen most of the time but could once you make a change in how the event is used later on.

  2. scvinodkumar
    View February 20, 2010

    Nice. could u plz send me zip file of this tutorial. I am also new to flex3.

  • Friends of mine

  • My Latest Book


    Avoiding a Goat Rodeo

  • Follow me on twitter!

  • RSS PHP Podcasts

    • Episode 33: Pol Pot-level Sucks
    • Episode 32: tek13
    • Episode 110: Azure hits 1 billion, RubyFlux compiler, Laracasts and more
    • Episode 7: Web Sockets Are Fast
    • Better Documentation for PHP internals – Lately in PHP podcast episode 35
    • Episode 32: tek13
    • Episode 31: Feline Tooth Extraction
    • Episode #2 – Adam Culp
    • Episode 6: PSR-X and the Mexican Standoff
    • Episode 109: Typescript and a bit more…

  • Me, elsewhere on the Web

    • Best web design company
    • Cal Evans Dot Com
    • Cyrano’s Apprentice
    • Evans Internet Construction Company
    • My Life as a Child
    • PHP Podcasts

  • Categories

    • Apache
    • BlogBling
    • Blogging
    • Book Review
    • codeworks
    • Entertainment
    • Entrepreneurship
    • Flex
    • Humor
    • JavaScript
    • Long Form
    • Management
    • Marketing
    • Me, elsewhere on the Web
    • PHP
    • podcasting
    • Programming
    • SQL
    • Technology
    • Web 2.0
    • wordpress
    • WordPress Plugins
    • writing
    • zend framework


Postcards From My Life is proudly powered by WordPress
Entries (RSS) and Comments (RSS).