I thought i should be smart and made/copy a removeAllChildren function which worked nice. But now I get "Error #2069: The Loader class does not implement this method" If i understanded it correctly so is it because I have a loaded picture in a Sprite. (But I'm almost sure it worked with the same type of pictures when I build the function as now.) I cant figure out how to go around it. Think catch error should work somehow, but havn't succeded with it. Or is something else I doing wrong?
This is the picture in R class
public static var picture:Class;
[Embed(source="picture.png")]
The child:
private var bg:Sprite=new R.picture;
canvas.addchild(bg);
My removechildrenfunction:
public static function removeAllChildren(doc:*):void {
while(doc.numChildren){
if (doc.getChildAt(0) is DisplayObjectContainer)
removeAllChildren(doc.getChildAt(0));
doc.removeChildAt(0);
}
}
you are sending removeAllChildren function parameter typed as Loader
from Loader Reference
The Loader class overrides the following methods that it inherits,
because a Loader object can only have one child display object—the
display object that it loads. Calling the following methods throws an
exception: addChild(), addChildAt(), removeChild(), removeChildAt(),
and setChildIndex(). To remove a loaded display object, you must
remove the Loader object from its parent DisplayObjectContainer child
array.
public static function removeAllChildren(doc:*):void {
if(doc is Loader && doc.parent != null)
{
doc.parent.removeChild(doc);
return;
}
while(doc.numChildren){
if (doc.getChildAt(0) is DisplayObjectContainer){
removeAllChildren(doc.getChildAt(0));
}
doc.removeChildAt(0);
}
}
Related
I have two files,
FloorplansMaster and Floorplans.
In my FloorplansMaster I have this method inside my script tags:
public function changeView(): void
{
var floorplans:Floorplans = new Floorplans();
floorplans.changeView();
}
and I am trying to call the method changeView in the Floorplans file, which looks like this:
public function changeView():void
{
trace("Here");
}
But I keep getting this error:
Cannot access a property or method of a null object reference.
What am I doing wrong?
In Flex developers often try to access view elements before they're created.
Try calling the method in a creationComplete handler instead.
My goal is:
define a subClass of Sprite called Ship
use an event at runtime to call a function within this new class
It seems that I've figured out how to create my Ship class using a package in a linked .as file. But I can't seem to access the function within that class. Can anyone see what I'm doing wrong?
var ShipMc:Ship = new Ship();
addChild(ShipMc);// This successfully adds an instance, so I know the class is working.
addEventListener(MouseEvent.CLICK, ShipMc.addShip);//But this doesn't seem to run the function
This code works fine for instantiating a Sprite, but the code in the Ship.as file, specifically the function, is not working. No runtime errors, but nothing traced to the output window, either.
package
{
import flash.display.Sprite
public class Ship extends Sprite
{
public function addShip():void
{
trace("running addShip function")
}
}
}
The last time a coded anything in flash it was AS2!
I'll just mention that I've tried using addShip():void and just addShip(). Same response with both. It should be with :void, right? Anyway, the fact that neither one throws, tells me that this section of code isn't even getting read, I think.
Any help is much appreciated! Pulling my hair out.
Your code is not working because it contains some problems, so let's see that.
You should know that you are attaching the MouseEvent.CLICK event listener to the main timeline which didn't contain any clickable object yet now (it's empty), so let's start by adding something to your Ship class to avoid that :
public class Ship extends Sprite
{
// the constructor of your class, called when you instantiate this class
public function Ship()
{
// this code will draw an orange square 100*100px at (0, 0)
graphics.beginFill(0xff9900);
graphics.drawRect(0, 0, 100, 100);
graphics.endFill();
}
public function addShip():void
{
trace("addShip function run");
}
}
N.B: You can attach the MouseEvent.CLICK event listener to the stage, which will work even if you have nothing in the stage.
Now, if you test your app, you'll get an clickable orange square at the top left corner of your stage, but the compiler will fire an error (ArgumentError) because it's waiting for a listener function (the Ship.addShip() function here) which accept an MouseEvent object.
So to avoid that error, your Ship.addShip() function can be like this for example :
public function addShip(e:MouseEvent):void
{
trace("addShip function run");
}
Then your code should work.
You can also simplify things by using another listener function in your main code which can call the Ship.addShip() function, like this for example :
var ShipMc:Ship = new Ship();
addChild(ShipMc);
addEventListener(MouseEvent.CLICK, onMouseClick);
function onMouseClick(e:MouseEvent): void
{
ShipMc.addShip();
}
For more about all that, you can take a look on AS3 fundamentals where you can find all what you need to know about AS3.
Hope that can help.
I have a MovieClip inside library, linkaged to MyObject and it contains a textField.
I don't know how I can access this textField without using the getChildByName method.
Apparently, the 3rd section works when object is on stage (without using addChild). But when using addChild I think there has to be some kind of casting; which I don't know how.
var childElement: MyObject = new MyObject();
childElement.name = "theChildElement";
container.addChild(childElement);
btn.addEventListener(MouseEvent.CLICK, changeText);
function changeText(event: MouseEvent): void
{
var targetBox:MovieClip = container.getChildByName(childElement.name) as MovieClip;
targetBox.textField.text = "hello"; // THIS WORKS
// This works too:
// MovieClip(container.getChildByName("theChildElement"))["textField"].text = "hello"; // THIS WORKS TOO.
// THIS DOESN'T WORK. why?
// container["theChildElement"]["textField"].text = "hello";
}
As confusing as it may seem, instance name, and name are not the same. From your code you should always be able to get to your MC by it's variable name. To get your last like to work you could just use this.
childElement["textField"].text = "hello";
There is a difference between Symbols created by the Flash IDE, which aggregate other DisplayObjects and programmatically created DisplayObjects.
When a DisplayObject is created in the Flash IDE, it's instance name can be used to resolve the instance as a property - which means it can be accessed via []. The [] can be used to access properties or keys of dynamic declared classes - like MovieClip. This necessary because you'll most likely down cast to MovieClip instead of using the symbol class created by Flash. That is not possible when simply using addChild, addChildAt or setChildAt from the DisplayObjectContainer API.
It is always the save way to access it via getChildByNameand check for null because otherwise your app, website or whatever is doomed for 1009 errors as soon as someone is changing the symbols.
I'd create a bunch of helper methods, like
// not tested
function getChildIn(parent:DisplayObjectContainer, names:Array):DisplayObject {
var child:DisplayObject, name:String;
while (names.length > 0) {
name = names.shift();
child = parent.getChildByName(name);
if (!child) {
// log it
return null;
}
if (names.length == 0) {
return child;
}
}
// log it
return null;
}
function getTextFieldIn(parent:DisplayObjectContainer, names:Array):TextField {
return getChildIn(parent, names) as TextField;
}
function getMovieClipIn(parent:DisplayObjectContainer, names:Array):MovieClip {
return getChildIn(parent, names) as MovieClip;
}
Your third method doesn't work because you are trying to call the ChildElement by it's name
without using getChildByName method. On the other hand, you shouldn't call your textField textField, because that's already an actionScript property.
Your should rather call it 'displayText' for example.
For a textField called 'displayText' contained in childElement :
function changeText(event:MouseEvent): void
{
childElement.displayText.text = "hello";
}
I have a movie clip with an external class attached.
here is the MC code (I've shorten it only for the relevant part...)
package {
//all the imports here...
public class mc_masterChapter extends MovieClip {
public function mc_masterChapter() {
trace (picFile,strChapTitle);
}
//Properties
public var picFile:String;
public var strChapTitle:String;
}
}
In the main class file I'm adding this object to stage using addChild:
var masterChapter:mc_masterChapter = new mc_masterChapter;
masterChapter.picFile = "pic_Chap1.jpg";
masterChapter.strChapTitle = "ABCD:
addChildAt(masterChapter,1);
now, the trace in the MC class code gives nulls to both parametes but if i put a trace inside the MC timeline (instead of the attached class code), it gives the right value!
how can I access the values from the MC class itself without getting nuls?
Thank you.
It works! Let me explain:
var masterChapter:mc_masterChapter = new mc_masterChapter; // Calls class constuctor
// so calls trace() too!
// You will get null null
masterChapter.picFile = "pic_Chap1.jpg"; // Assign the variables
masterChapter.strChapTitle = "ABCD"; // so they can be read
trace(masterChapter.picFile, masterChapter.strChapTitle); // Should trace pic_Chap1.jpg ABCD
If you add the following method to your class:
public function test():void {
trace(picFile, strChapTitle);
}
Then call masterChapter.test() it will successfully trace those two properties. So yes, the class can read its properties.
Make the var you use in your main class public static vars.
OK!
I solved the mystery.
I put two traces. one in the main MC class saying "hey, I'm inside the MC - the picFile="
and one in the put Function saying "I'm putting this file into picFile:"
well this is what I've got:
hey, I'm inside the MC - the picFile=null
I'm putting this file into picFile:image.jpg
got it!?! at the moment I asked him to give birth to an instance of the MC (even before putting it on stage - just defining the object (with this line:)
var masterChapter:mc_masterChapter = new mc_masterChapter;
it allready run the class, so of course that in this stage the parameters were not defined allready and were null.
the definition code came right after that line (in the main.as)
masterChapter.pic="pic_Chap1.jpg";
so what I did, was to move all the code from the main class of the MC object to a public function inside the same package called init(). Then I called this function manually from the parent main class.
By that I can decide when to call it (after I declare all the parameters of course).
That's it.
god is hiding in the small details : )
tnx for all the helpers.
Possibly a better solution would be to use a getter/setter pair, so you can know at the exact moment the properties are set:
protected var _picFile:String:
public function get picFile():String {
return _picFile;
}
public function set picFile(value:String):void {
if (value != _picFile) {
_picFile=value;
trace('picFile set to', _picFile);
}
}
I'am a beginner of ActionScript3
I wanna get swf's url.
but I develop swc lib.
swf(Main) develop other developer.
I have to get from Main loaderinfo, I / F is already fixed.
Do you have a good idea?
public function doSomething( arg1:String,arg2:String ):String
{
/* some thing */
return result;
}
Get the other developer to pass in the Main class or the Stage (in fact any DisplayObject) and return the loaderInfo.loaderURL from that. Something like:
public function getSWFURL( dObj:Sprite ):String
{
return dObj.root.loaderInfo.loaderURL;
}
the .root will return the root DisplayObject, so any DisplayObject that's attached to the stage will return this.