We saw how to
declare a Document Class to the FLA .
We studied what is a
Document Class .
We saw how
the timeline and Document Class interact between them.
It is time to affront the problem of using double Document Class.
The idea to write this article came to me while answering to a thread on the
Flash CS3 Forum of FlepStudio .
The user needed help with a problem on how to load an external SWF which itself had a Document Class. In this case, we found ourselves with a main FLA and its proper Document Class that loads an external SWF which FLA is associated to a second Document Class. As the external SWF Document Class is loaded externally, the root and all path included in it would change. Left as it is, it would be useless and would only generate one error after another.
Let us see how to resolve this problem" In a Object Oriented application, the main class is only one. In flash it has been called Document Class while in Java it remained the Main Class.
We can not have two Document Classes in a Flash application. Following the logic, only the one class starts the application calling a method which itself will create other class instances or call methods and properties of other classes.
Also, keeping in mind that our main FLA is an instance of its Document Class, we cannot load an external SWF with its own Document Class into a main SWF.
We need to work using the one Document Class and through it, access the loaded SWF.
In this tutorial, we will see that using the Document Class, we are privileged. In any point of our application, we can retrieve, assign or call a script easily as everything is kept together and every classes of the application itself are tightly joined together.
The files used in this tutorial are the following:
- main.fla (the main FLA of the application)
- Main.as (the Document Class associated to main.fla)
- Loading.as (a class instantiate by the Document Class which will load the external SWF)
- my_swf.fla (the FLA of the external SWF)
- my_swf.swf (the external SWF loaded in main.swf)
- Main2.as (the class which will interact with the external SWF and the main SWF, a bit like if it was the Document Class of my_swf.fla)
main.fla
I create in library a MovieClip named "mc_prova" and place an instance on stage with an instance name "prova_mc".
I assign to this FLA the Document Class "Main.as"
my_swf.fla
I create in library a MovieClip named "mc_test" and place on stage an instance with an instance name "test_mc" I create a shape motion a more frames and in the first frame, add a stop();. Next we will see how to call the play() of that MovieClip from the Main2 Class once the swf is loaded.
Main.as
The Document Class of the full application, implemented the following way:
Code:
package
{
import flash.display.MovieClip;
public class Main extends MovieClip
{
private var loading:Loading;
public var trovami:Number=10;
public function Main()
{
stage.frameRate=31;
loadSWF();
}
private function loadSWF():void
{
loading=new Loading(this);
}
}
}
Properties
An instance of the Loading.as class which will load the external swf
private var loading:Loading;
a numerical variable equal to 10, used to see, later on, how to retrieve a value at any point of our application. Using the words "at any point", I mean that this variable can be retrieved from any part of our application if itself follows the good rules of OOP.
public var trovami:Number=10;
Methods
Constructor function:
public function Main()
{
I impost the frame rate
stage.frameRate=31;
I call the method loadSWF
loadSWF();
}
loadSWF();
I create an instance of the Loading Class and pass to it the value of the main root (root of main.fla)
loading=new Loading(this);
Loading.as
The class which will load the external SWF (my_swf.swf)
Code:
package
{
import flash.display.MovieClip;
import flash.display.SimpleButton;
import flash.text.TextField;
import flash.display.Loader;
import flash.events.*;
import flash.net.URLRequest;
public class Loading extends MovieClip
{
private var _fla:MovieClip;
private var url:String;
private var loader:Loader;
public function Loading(fla:MovieClip)
{
_fla=fla;
init();
}
private function init():void
{
url='my_swf.swf';
var request:URLRequest=new URLRequest(url);
loader=new Loader();
initListeners(loader.contentLoaderInfo);
loader.load(request);
}
private function initListeners(dispatcher:IEventDispatcher):void
{
dispatcher.addEventListener(Event.COMPLETE,completato);
}
private function completato(event:Event):void
{
_fla.addChild(loader);
loader.y=_fla.prova_mc.y+_fla.prova_mc.height+10;
loader.y=10;
var main2:Main2;
main2=new Main2(_fla,MovieClip(loader.content));
}
}
}
Properties
a MovieClip variable to which I assign the root passed by Main.as (the Document Class)
private var _fla:MovieClip;
a string variable which will contain the URL of the external SWF to load (my_swf.swf)
private var url:String;
an instance of the Loader Class to load my_swf.swf
private var loader:Loader;
Constructor Function
public function Loading(fla:MovieClip)
{
I assign to the variable "_fla" the root passed by Main.as (the document Class)
_fla=fla;
I call the method init
init();
}
Methods
init();
I assign the variable "url" the url of the SWF to be loaded
url='my_swf.swf';
I do an URL request to Flash
var request:URLRequest=new URLRequest(url);
I create an instance of Loader
loader=new Loader();
I call the method initListeners
initListeners(loader.contentLoaderInfo);
I load the SWF
loader.load(request);
initListeners();
I add a listener to the event COMPLETE so to know when the external swf is completely loaded. On load complete, the method "completato" will be called
dispatcher.addEventListener(Event.COMPLETE,complet ato);
completato();
The crucial part of this tutorial.
I do an addChild of loader so it is visible
_fla.addChild(loader);
I position the loader
loader.y=10;
I create an instance of Main2 Class and pass as a first parameter the root retrieved from the Document Class. As a second parameter, I pass the value of loader (the loaded SWF)
var main2:Main2;
main2=new Main2(_fla,MovieClip(loader.content));
PS: in the above line, I used a trick seen already in
Tips and Tricks– Loader.content
Main2.as
Code:
package
{
import flash.display.MovieClip;
public class Main2 extends MovieClip
{
private var _fla:MovieClip;
private var mia_root:MovieClip;
public function Main2(fla:MovieClip,m:MovieClip)
{
_fla=fla;
mia_root=m;
callClip();
}
private function callClip():void
{
mia_root.test_mc.play();
trace(_fla.prova_mc.name);
trace(_fla.trovami);
}
}
}
Properties
A MovieClip variable to which I assign the root passed by loading.as which itself retrieved it from the Document Class (Main.as)
private var _fla:MovieClip;
a MovieClip variable to which I assign the root of the loaded SWF passed by the Loading.as from loader.content. We can now refer to the external SWF when needed.
private var mia_root:MovieClip;
Methods
Constructor function
public function Main2(fla:MovieClip,m:MovieClip)
{
I assign to the variable _fla, the value of the application"s main root
_fla=fla;
I assign to the variable "mia_root", the value of the loaded SWF"s root
mia_root=m;
I call the method callClip
callClip();
}
callClip();
I action a play on test_mc paced in my_swf.fla. Keep an eye on the path.
mia_root.test_mc.play();
I trace the name property of prova_mc, the main SWF MovieClip. Keep an eye on the path.
trace(_fla.prova_mc.name);
I retrieve also the value of the Document Class property (the variable "trovami")
trace(_fla.trovami);
We now have everything under control. If we wanted to interact with the main timeline, we could do it from the Document Class, Loading.as or Main2.as.
If we wanted to interact with the loaded SWF, we could do it from Loading.as or main2.as.
Source files: