InfoQ

InfoQ

Article

My Bookmarks

Login or Register to enable bookmarks for unlimited time.

The content has been bookmarked!

There was an error bookmarking this content! Please retry.

ActionScript 3 for Java Programmers

Posted by Jack Herrington on Aug 25, 2008

Sections
Development
Topics
Rich Internet Apps ,
Rich Client / Desktop ,
Java
Tags
Flex ,
ActionScript

Let’s face it: The client has not been a friendly place for Java programmers. Java technology on the client with applets, Swing, and JavaFX has had limited success. JavaScript, despite its name, is almost nothing like the Java language. And Adobe Flash—well, it’s just like JavaScript. Or is it? It might have been the case that Flash was like JavaScript a couple of years ago, but with the advent of ActionScript 3, a lot has changed. And I think you’ll find a lot to like.

First, ActionScript—the programming language for Adobe Flex and Flash—is now strongly typed. It also has first-class object orientation, including classes and interfaces. It has extras that you won’t find in Java—notably, get and set functions for properties and a language extension called ECMAScript for XML (E4X), which turns any XML document into objects that you can reference with dot operators, just like regular objects.

This article takes you through the basics of ActionScript 3 and shows how it compares with the Java environment you’re used to. By the end, you should have given up any preconceptions you may have had about ActionScript and have some interest in playing with it. One of the great things about Flex, Flash, and ActionScript is that they’re available at no cost. Simply download Adobe Flex Builder 3 to get started. Flex Builder, which is a sophisticated integrated development environment (IDE), is not a free application, but the Flex Software Development Kit (SDK) that it uses to build Flash applications is.

A word of warning to language purists out there reading this article: I’m not a language guru, so I might gloss over some language details. I’m also not trying to present everything in ActionScript 3 in this article. If that’s what you’re after, many good books on ActionScript 3 are available. What I can do is give you a feel for the language. Here goes.

Classes and interfaces

Just as with Java, everything is really an object in ActionScript 3. There are a few primitive types like integers, but beyond that everything is an object. Similarly, like Java, there are namespaces and packages, like com.jherrington.animals, which would mean company / jack herrington / animal classes, in this case. You can put classes into the default namespace, but it’s better to control your namespace.

To define a class, you use the class keyword, just as with Java. Here’s an example:

package com.jherrington.animals
{
	public class Animal
	{
		public function Animal()
		{
		}
	}
}

In this case, I'm defining an Animal class with a constructor that currently does nothing.

I can add a few member variables and refine the constructor quite easily, as shown here:

package com.jherrington.animals
{
	public class Animal
	{
		public var name:String = "";

		private var age:int = 0;

		private function Animal( _name:String, _age:int = 30 )
		{
			name = _name;
			age = _age;
		}
	}
}

Here, I'm defining that an Animal object has two member variables; name, which is a public string, and age, which is a private integer. (Apparently, animals are shy about their age.) The constructor takes one or two values: either the name alone or the name and an age. You can provide default values for arguments by adding them in the function declaration.

What you notice about this code is that the typing is inverted from Java. In Java, the type comes first; in ActionScript, it comes second. This is because strong typing is an add-on to ActionScript. So to support older, non-typed code, the type comes after the variable name.

Let's extend the example by adding a few methods:

package com.jherrington.animals
{
	import flash.geom.Point;

	public class Animal
	{
		public var name:String = "";

		private var age:int = 0;

		private var location:Point = new Point(0,0);

		public function Animal( _name:String, _age:int = 30 )
		{
			name = _name;
			age = _age;
		}

		public function moveTo( x:int, y:int ) : void {
			location.x = x;
			location.y = y;
		}

		public function getLocation( ) : Point {
			return location;
		}
	}
}

As you can see here, I've added another private member variable, location, of type Point, which I've imported from Flash's geometry package. And I've added two methods that work with the location: moveTo, which moves the animal, and getLocation, which returns the current location.

Now, that's kind of the Java way to get and set a value. The ActionScript way to do it is a lot cleaner, as you can see in this code:

package com.jherrington.animals
{
	import flash.geom.Point;

	public class Animal
	{
		public var name:String = "";

		private var age:int = 0;

		private var myLocation:Point = new Point(0,0);

		public function Animal( _name:String, _age:int = 30 )
		{
			name = _name;
			age = _age;
		}

		public function set location( pt:Point ) : void {
			myLocation = pt;
		}

		public function get location( ) : Point {
			return myLocation;
		}
	}
}

Here, I'm using get and set functions that are invoked when the client code gets or sets the value of the member variable location. To the client, the location variable looks just like a regular member variable. But you can set whatever code you like to respond to the member variable setting and handle the get of the variable, as well.

How can you make use of this? You can add an event that is triggered when the location changes. Check that out in this code:

package com.jherrington.animals
{

	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.geom.Point;

	public class Animal extends EventDispatcher
	{
		public var name:String = "";

		private var age:int = 0;

		private var myLocation:Point = new Point(0,0);

		public function Animal( _name:String, _age:int = 30 )

			name = _name;
			age = _age;
		}

		public function set location ( pt:Point ) : void {
			myLocation = pt;
			dispatchEvent( new Event( Event.CHANGE ) );
		}

		public function get location( ) : Point {
			return myLocation;
		}
	}
}

Now, I'm specifying that the Animal class is an event dispatcher- that is, an object from which clients can listen for events. I then dispatch a new event when the location changes.

Here is the client code that creates an animal, sets itself up to watch for change events, then changes its location:

	var a:Animal = new Animal();
	a.addEventListener(Event.CHANGE, function( event:Event ) : void {
		trace( "The animal has moved!" );
	} );
	a.location = new Point( 10, 20 );

This code brings up a trace message when the animal has moved. You can define any type of messages you want in ActionScript. Most of the classes are EventDispatchers and have events for which you can add listeners.

Interfaces

Just like Java, the ActionScript 3 language supports builder interfaces and implementing them with classes. The interface shown below is an example of what we might make from the Animal class:

package com.jherrington.animals
{
	import flash.geom.Point;

	public interface IAnimal
	{
		function get name() : String;
		function set name( n:String ) : void;

		function get location() : Point;
		function set location( pt:Point ) : void;
	}
}

In this case, I'm defining two member variables for the interface that I can both set and get. Yes, you can define methods and member variables in ActionScript interfaces. How cool is that?

To implement the interface, I've made some changes to the Animal class. You can see that in the code below:

package com.jherrington.animals
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.geom.Point;

	public class Animal extends EventDispatcher implements IAnimal
	{
		private var myName:String = "";

		public function get name() : String
		{
			return myName;
		}
		public function set name( n:String ) : void
		{
			myName = n;
			dispatchEvent( new Event( Event.CHANGE ) );
		}
		private var myLocation:Point = new Point(0,0);

		public function set location ( pt:Point ) : void {
			myLocation = pt;
			dispatchEvent( new Event( Event.CHANGE ) );
		}

		public function get location( ) : Point {
			return myLocation;
		}

		public function Animal( _name:String )
		{
			name = _name;
		}
	}
}

Of course, I can add variables and methods specific to this class or implement other interfaces in addition to the IAnimal interface. As with Java, however, I can only inherit from one base class.

Statics and constants

ActionScript 3 supports both constants and static member variables as well as static methods. Constants are easy to define, as you can see in the code below:

		public const MINIMUM_AGE:int = 0;

		public const MAXIMUM_AGE:int = 2000;

Constants can be of any type you like, but they have to be defined at compile time. They can also be protected or private if you want to scope them that way.

To demonstrate a static function, I show a factory method in the Animal class:

		public static function buildAnimal( n:String ) : IAnimal {
			return new Animal( n );
		}

Another way to use static method is in a Singleton pattern. Below is an example of a Singleton factory class for the Animal class:

package com.jherrington.animals
{
	public class AnimalFactory
	{
		private static var _factory:AnimalFactory = new AnimalFactory();

		public static function get instance() : AnimalFactory {
			return _factory;
		}

		public function build( n:String ) : Animal {
			return new Animal( n );
		}
	}
}

To invoke it, I use the instance member variable to get the single factory object:

private var b:Animal = AnimalFactory.instance.build( "Russell" );

This uses the Singleton factory object to create a new animal with the name Russell.

Inheritance

To demonstrate inheritance, I show three interfaces and classes. The first interface is the IAnimal class I showed before. The second is the Animal class, and the third is a derived class called Dog that overrides a method.

The interface, IAnimal, is shown below:

	public interface IAnimal
	{
		function get name() : String;
		function set name( n:String ) : void;

		function move( x:int, y:int ) : void;
	}

I've simplified it a bit by taking it back to just a name member variable and a move() method. The first implementation of the interface is the Animal class:

public class Animal extends EventDispatcher implements IAnimal
{
	private var myName:String = "";

	public function get name() : String
	{
		return myName;
	}
	public function set name( n:String ) : void
	{
		myName = n;
		dispatchEvent( new Event( Event.CHANGE ) );
	}

	public function Animal( _name:String )
	{
		name = _name;
	}

	public virtual  function move( x:int, y:int ) : void
	{
	}
}

Then, the Dog class builds on the Animal class by having its own constructor and an override of the move() method:

public class Dog extends Animal
{
	public function Dog(_name:String)
	{
		super(_name);
	}

	public override function move( x:int, y:int ) : void
	{
		trace( 'Moving to '+x+', '+y );
	}
}

This is a lot like Java code, so you should feel really at home in implementing your object-oriented designs in ActionScript.

Operators and conditionals

Operators in ActionScript are exactly the same as what you find in Java. Similarly, math and Boolean operators are the same:

	var a:int = 5;
	var b:int = 6;
	var c:int = a * b;
	c *= 10;
	var d:Boolean = ( c > 10 );
	var e:int = d ? 10 : 20;

These examples show a few of the different operators. The only difference in these examples between ActionScript and Java is the syntax for defining the variables.

Like operators, conditionals work exactly the same between the two languages-for example:

	if ( a > 10 ) {
		trace( 'low' );
	}
	else if ( a > 20 ) {
		trace( 'high' );
	}
	else {
		threw new Exception( "Strange value" );
	}

shows both the conditional syntax and how you can throw exceptions. Exception handling is exactly the same in Java. You can define your own exception types or just use the standard Exception class.

The try, catch, and finally syntax is shown in the example below:

	try
	{
		location = new Point( -10, 10 );
	}
	catch( Exception e )
	{
		trace( e.toString() );
	}
	finally
	{
		location = null;
	}

This code tries to set the location and traces out the error if a problem occurs. In any case, the location will be set to null at the end.

Iterators

ActionScript 3 doesn't have strongly typed containers, but it's still easy to work with arrays and hash tables. Here is an example of using a for loop to iterate an array:

	var values:Array = new [ 1, 2, 5 ];
	for( var i:int = 0; i < values.length; i++ )
		trace( values[i] );

But this isn't really the way you want to iterate an array in ActionScript. The best way is to use the for each syntax, as shown in the next sample:

	var values:Array = new [ 1, 2, 5 ];
	for each ( var i:int in values )
		trace( i );

This code iterates through each element in the array and sets the value of i to each element along the way.

To create a hash table, you use the basic Object type in ActionScript:

	var params:Object = { first:'Jack', last:'Herrington' };
	for( var key:String in params )
		trace( key+' = '+params[key] );

ActionScript's origins in JavaScript mean that the base object type is a slots-based container that you can easily use as a hash table.

Regular expressions

Regular expressions are baked right into the base syntax for ActionScript. For example, this code:

	if ( name.search( /jack/i ) )
	{
		trace('hello jack');
	}

performs a simple check on a string.

This code uses a regular expression to perform a split operation:

	var values:String = "1,2,3";
	for each( var val:String in values.split(/,/) ) {
		trace( val );
	}

Whether you should have regular expressions embedded in the core syntax is debatable. The architects of Java obviously thought these expressions should go in an external library. But I think that they are useful enough that they should be integrated as they are in ActionScript.

E4X

XML is used widely enough that ActionScript has support for it built right into the language syntax. If you're an XML junkie, you are going to love this. Check it out:

var myData:XML = <names>
	<name>Jack</name>
	<name>Oso</name>
	<name>Sadie</name>
</names>;
	for each ( var name:XML in myData..name ) {
		trace( name.toString() );
}

This code defines an XML document, then searches it and prints out all the tags.

This next bit of code also gets <name> tags but only tags that are specified with a type of dog.

var myData:XML = <names>
	<name type="person">Jack</name>
	<name type="dog">Oso</name>
	<name type="dog">Sadie</name>
</names>;
	for each ( var name:XML in myData..name.(@type='dog') ) {
		trace( name.toString() );
}

The @ syntax is similar to XPath and XSLT. It's used to specify that we are looking at attributes and not XML elements.

E4X is a fantastic addition to the language. It turns XML parsing from a chore into a delight. Web services can even be returned in E4X format for easy parsing.

Conclusion

Adobe has made some extraordinary strides with ActionScript. It's a far more sophisticated language than most people give it credit for. I think you'll find that what Adobe has done is taken some of the lessons learned from what is right and wrong about Java and incorporated them into their development of the ActionScript 3 language. You'll be very happy with the result.

For more information

  • For more on the similarities between ActionScript and Java syntax, read Yakov Fain's article, "Comparing the syntax of Java 5 and ActionScript 3" (JDJ, November 12, 2006).
  • A Java-to-ActionScript converter is available for download from Open Source Flash that allows you to use Java rather than ActionScript to create Flash content.
  • For a list of resources to help you migrate between ActionScript, Flex, Java, and JavaScript development, see RIAdobe's comparison list.
  • Flex.org is your source for all things Adobe Flex.
bug by yuan scott Posted
java to as3 converter on AIR by Mansour Raad Posted
Error. by Rodrigo Pereira Fraga Posted
Still a long way to go! by Shrihari SC Posted
Singleton issues and Dictionary class by Simon Groenewolt Posted
Simple and clear article by Cyril Gambis Posted
new [] ? by Renaud Denis Posted
Re: new [] ? by Steven Libonati Posted
  1. Back to top

    bug

    by yuan scott

    for each ( var name:XML in myData..name.(@type='dog') )
    change to
    for each ( var name:XML in myData..name.(@type=='dog') )

  2. Back to top

    java to as3 converter on AIR

    by Mansour Raad

  3. Back to top

    Error.

    by Rodrigo Pereira Fraga

    Exception == Erros in AS3.

    So...



    ...

    throw new Error( "Strange value" );

    ...


    And:


    ..

    catch( e:Error )

    ..


    You didn't test this code.

  4. Back to top

    Still a long way to go!

    by Shrihari SC

    I guess looking at the commonly-used syntax, Actionscript 3 has tried to bridge Java 6 with Javascript. Riding on the success of Adobe Flex, I think this will definitely improvise, and carve a different niche.

  5. Back to top

    Singleton issues and Dictionary class

    by Simon Groenewolt

    I think you should have mentioned the problems you run into when trying to implement a singleton pattern in as3 -- since as3 has no private constructors you have to perform all kinds of tricks to make sure noone accidentally instances your singleton object.




    And something else: If you want to use a Map-like collection and you don't want to use Strings as keys (If you use Object you can only use strings) you can use the flash.utils.Dictionary class - that one can take objects as keys.

  6. Back to top

    Simple and clear article

    by Cyril Gambis

    In think the provided topics are interesting and a good starter for new Flex developers.

    It shows how a modern language can improve the programming experience, productivity and clarity over verbose languages (even if Java is quite modern itself).

  7. Back to top

    new [] ?

    by Renaud Denis

    Hi,


    At first sight, I've thought that the new keyword is not relevant when using the particular array syntax:


    var values:Array = new [ 1, 2, 5 ];



    could be


    var values:Array = [ 1, 2, 5 ];



    But apparently, using new right before the bracket syntax is valid as well.


    Is there any added value by using new?

  8. Back to top

    Re: new [] ?

    by Steven Libonati

    Hi, At first sight, I've thought that the new keyword is not relevant when using the particular array syntax:

    var values:Array = new [ 1, 2, 5 ];
    could be
    var values:Array = [ 1, 2, 5 ];
    But apparently, using new right before the bracket syntax is valid as well. Is there any added value by using new?


    The behavior is identical. If you run in it in the Flex Debugger, you'll see each instantiates an Array object. It is also mentioned in the Flex 3 Language Reference under the [] array access Operator.

Educational Content

10 tips on how to prevent business value risk

One category of risk that project teams need to ensure they address is business value failure – delivering a product that fails to provide value for the business investor.

Interview: Software Systems Architecture: Working With Stakeholders Using Viewpoints and Perspectives

InfoQ spoke to the authors of Software Systems Architecture on a couple of new topics, the System Context viewpoint and Agile, which have been added to the second edition.

Beauty Is in the Eye of the Beholder

Alex Papadimoulis discusses ugly code, where it comes from, how to avoid it, and how to get rid of it.

Architecting Visa for Massive Scale and Continuous Innovation

John Davies examines Visa’s architecture and shows how enterprises have architected complex integrations incorporating Hadoop, memcached, Ruby on Rails, and others to deliver innovative solutions.

Max Protect: Scalability and Caching at ESPN.com

Sean Comerford unveils ESPN.com’s architecture, what components are used and why, and the current changes the website goes through.

The Seven Deadly Sins of Enterprise Agile Adoption

Are there repeated patterns of failure on Enterprise Agile Enablement efforts? Sanjiv and Arlen discuss Seven Deadly Sins to avoid when adopting Agile in an enterprise.

Questions for an Enterprise Architect

Erik Dörnenburg answers: What is Enterprise and Evolutionary Architecture?, discussing 4 issues: Turning strategy into execution, Ensuring conformance, Where do the architects sit? Buying or building?

Wrap Your SQL Head Around Riak MapReduce

Sean Cribbs explains what Map-Reduce and Riak are, why and how to use Map-Reduce with Riak, and how to convert SQL queries into their Map-Reduce equivalents.