4

I'm loading an external SWF (pre-made by an other department of the company I work for) using flash.display.Loader. I then traverse the display list, register all objects and listen for added/removed events to handle future changes to the list.

var obj:DisplayObjectContainer = loadEvent.currentTarget.content as DisplayObjectContainer;
var count:Number = obj.numChildren;
for (var i:Number = 0; i < count; i++)
{
     registerObject(obj.getChildAt(i));
}
obj.addEventListener(Event.ADDED, onChildAdded);
obj.addEventListener(Event.REMOVED, onChildRemoved);

The thing is I wonder what would happen if one of the developers of the original SWFs uses:

.visible = true / false;

Is there a way I can listen for changes to the .visible property? Or any other property (that doesn't fire a built-in event) for that matter?

Leeron
  • 147
  • 1
  • 2
  • 11
  • 2
    Perhaps you should elaborate. It doesn't seem like we're getting the whole picture here. In particular, how is it that you have a ref to an object that you cannot substitute in a subclass of your own, and how does your code depend on the state of this object? Explaining that might reveal the underlying issue and make the solution more obvious. – Dustman Feb 16 '10 at 21:49
  • You are right of course. The bigger picture is this: I'm developing a container SWF, that loads other pre-made SWF files created by other departments of the company I work for. I need to monitor whenever objects are being displayed or hidden. what I currently do is listen for added/removed events. but I wonder what would happen if one of the developers of the loaded SWFs has used .visible = false/true in her code. – Leeron Feb 17 '10 at 19:12
  • 1
    Okay, that's helpful. Now, what's the context in which you are identifying and trapping the objects you want to listen to? What are you currently doing to hook in to the add and remove events? Code! And edit the question please so it's more obvious what's going on. – Dustman Feb 17 '10 at 20:14
  • Original question edited. Thanks for the tip. :) – Leeron Feb 17 '10 at 20:39

4 Answers4

3

Not by default, I don't think. But you could create your own Event class and dispatch it from an override of function set Visible without a lot of hassle.

Edit: Okay, so a_w does have the right idea, and you can attach that right back into the container.

Make a wrapper like so:

public class VisibilityEnabledDisplayObject extends DisplayObject
{
    public function VisibilityEnabledDisplayObject(d:DisplayObject)
    {
        super();
        _d = d;
    }
    public function override get visible(b:Boolean):Boolean
    {
        return this._d.visible;
    }
    public function set visible(b:Boolean):void
    {
        if(this._d.visible != value)
        {
            this._d.visible = value;
            this.dispatchEvent(new Event('visibilityChanged'));
        }
    }
    private var _d:DisplayObject;
}

Then, make your loop look like:

for (var i:int = 0; i < count; i++)
{
    var do:DisplayObject = obj.getChildAt(i);
    registerObject(do);
    obj.removeChildAt(i);
    var vedo:VisibilityEnabledDisplayObject = new VisibilityEnabledDisplayObject(do);
    obj.addChildAt(vedo, i);
    // register whatever listener you like with the vedo here
}

Then the setter method should be polymorphically called. You may have to pass the entire public DisplayObject interface through the VisibilityEnabledDisplayObject decorator, I can't remember right now...

Dustman
  • 5,035
  • 10
  • 32
  • 40
  • The thing is I want to listen to events on an already existing object in a loaded swf. So I'm afraid that won't be possible. – Leeron Feb 16 '10 at 21:03
1

For DisplayObject you want to listen for the addedToStage and removedFromStage events.

For Flex components, listen to show and hide events.

Samuel Neff
  • 73,278
  • 17
  • 138
  • 182
  • 2
    That was my first guess. But will direct changes to .visible will trigger those event? – Leeron Feb 16 '10 at 21:05
  • 2
    Event.ADDED_TO_STAGE and Event.REMOVED_FROM_STAGE have nothing to do with the .visible property of a DisplayObject. These events will only fire when addChild/removeChild is called for the DisplayObject, *and* if that DisplayObject's parent is in the display list (a descendent of the MainTimeline). – geraldalewis Feb 16 '10 at 22:28
1

See Can an Actionscript component listen to its own propertyChange events?

It says yes.

If you use the [Bindable] tag without specifying an event type, then when the property changes its value, an event of type: PropertyChangeEvent.PROPERTY_CHANGE, which is the string 'propertyChange', will be dispatched.

Therefore, to be able to register to listen to that event, you need to say:

this.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, onOnChange);

The reason why your listener function was never called is that the event type was not correct.

Note that the listener method will be called when any of the variables marked as Bindable in your class changes, not only 'on'. This event comes with a property called 'property' that indicates which variable was changed.

To avoid being called on each Bindable variable, you need to specify an event in the [Bindable] tag:

[Bindable(event="myOnChangeEvent")]

and dispatch that event manually when you consider that the property is changing (ie: in the setter), though that didn't seem to be what you wanted to do.

Community
  • 1
  • 1
Todd Moses
  • 10,969
  • 10
  • 47
  • 65
  • The thing is I want to listen for events on an already existing object in a loaded swf. So I'm afraid that won't be possible – Leeron Feb 16 '10 at 21:06
1

Create a mediator class, that will manipulate your display object. through instance of that class you can set and get any properties and monitor changes. for example

public class ExistingDOMediator extends EventDispatcher{
   protected var _view:DisplayObject;
   public function ExistingDOMediator(view:DisplayObject):void{
      super();
      this._view = view;
   }
   public function get visible(value:Boolean):void{
      return this._view.visible;
   }
   public function set visible(value:Boolean):void{
      if(this._view.visible!=value){
         this._view.visible = value;
         this.dispatchEvent(new Event('visibilityChanged'));
      }
   }
}
a_w
  • 11
  • 1