Actionscript, objects and event listeners - actionscript

Say I have an object
var my_obj = new Object();
my_obj['key'] = value;
Is there a way to add an event listener to the value, like
my_obj['key'].addEventListener(Blah Blah);
I have a long(ish) list of buttons on the timeline (the layout is so different from section to section that just makes more sense to do on the timeline rather than trying to build the layouts via actionscript).
button1 = plays "frame label 1"
button2 = plays "frame label 2"
and so on....so I was just thinking of storing everything in an array
obj["button1"] = "framelabel1"
arr.push(obj);
Then I could just have one event handler for all of the buttons and use target to get the frame label value...

Yes, you can do exactly what you're asking in the exact way you've mentioned, here's an example:
var value:Sprite = new Sprite();
var my_obj = new Object();
my_obj['key'] = value;
So calling:
my_obj['key'].addEventListener(Event.ENTER_FRAME, _onEnterFrameHandler);
is exactly the same as calling:
value.addEventListener(Event.ENTER_FRAME, _onEnterFrameHandler);

If the value is an IEventDispatcher or extends EventDispatcher you can add a listener to it.

The question is rather obscure to me. My guess is that you need something triggered every time a value is set. If this is the case, then you have to create a custom class, and declare a getter-setter property there.
For instance:
package
{
import flash.display.Sprite;
public class TestAccessor extends Sprite
{
private var someVarValue:uint = 0;
public function TestAccessor()
{
super();
}
public function get someVar():uint
{
return someVarValue;
}
public function set someVar(value:uint):*
{
someVarValue = value;
// this is the place where someVar is set.
// do whatever else you like here,
// you may choose to dispatch an event from here if you need.
}
}
}
Back in AS1-AS2 era we had watch() and addProperty() for that purpose, but these times are long since gone. For good. :)

Related

Passing values between classes in Vaadin

This might be more of a Java question, but how would you access values (say from a textfield) of a given view/class from a different class? For example if there was a TextField t1 that is in the MainView, and I wanted to get its current value for a computation in a different class. And is there a more Vaadin-specific approach here?
That can depend on the use case specifically. Since you mentioned a TextField value I assume the value is not yet stored in the DB, it's just on the UI yet -> I rule out singleton spring services.
A few ideas:
If the MainView and the different class are nested components and it's viable and not really complicated across a lot of classes... then probably passing it down the way when creating the sub-component. This is a naive solution - it can get pretty messy.
MainView() {
var t1 = new TextField();
var d = new Different(t1);
}
Fire and listen to Vaadin Component events. If you want really loose coupling, the most universal would be to use the UI instance as the event bus.
// listen in different class
ComponentUtil.addListener(attachEvent.getUI(), CloseMenuEvent.class, e -> closeMenu());
// fire change in MainView
ComponentUtil.fireEvent(ui, new CloseMenuEvent(ui))
A more specific version of number 2. is to pass the ValueChangeListener of the MainView's t1 to the different class.
MainView() {
var t1 = new TextField();
var d = new DifferentClass();
t1.addValueChangeListener(d::t1Changed)
add(t1, d);
}
Extract the common field to a third party, to a third class. Use a #UIScoped spring bean (#SpringComponent, #Service, ...) that will hold that field, and inject it to both MainView and the different class.
#Route
public class MainView extends VerticalLayout {
public MainView(Model m, Different d) {
add(m.t1, d);
}
}
#Scope(SCOPE_PROTOTYPE)
public class Different extends Component {
public Different(Model m) {
// something with m.t1
}
}
#UIScoped
public class Model {
public final TextField t1 = new TextField(); // TODO use getter
}
You could change the 4th approach by keeping String in Model and having a value change listener that updates it.

Can't receive value from another class on XNA Framework C#

I have several classes on my project: Game1(main class(default)), Animation and Enemy:
public class Animation
{
public int currentFrameHit;
public Animation ()
{
}
public void Update(GameTime gameTime)
{
timeElapsedHit += gameTime.ElapsedGameTime.Milliseconds;
if (timeElapsedHit > 100)
{
timeElapsedHit = 0;
currentFrameHit = (currentFrameHit + 1) % 9;
}
}
}
How can i get value from variable in Animation class?
In Enemy class i can't receive this value from Animation. I tried that:
Animation animation = new Animation();
Console.WriteLine(animation.currentFrameHit);
But i'm getting null, however in main class Game1 i receive right values with same code.
The problem is that you're making a new Animation() without assigning it to anything. so it'll keep returning it's default value.
So far there isn't enough information given on what the number should be though. Do you have the Animation() class inside the Enemy Class, or do you find the Enemy Class within Animation()?
You need to reference to an existing animation value.
Create an instance in your desire class (here it is Game1) and don't forget to make it public.
public static Animation animationGame1 = new Animation();
Then in your second class:
In LoadContent(): reference it to Game1's variable:
Animation animationNewClass = Game1.animationGame1;
In Update(): do what you want to achieve:
Console.WriteLine(animationNewClass.currentFrameHit);
Hope this helps.

BeanItem not updating associated Field more than one, when changing property by hand

I'm scratching my head, trying to work out why a BeanItem's property isn't updating the component Field's value - more than once :(.
class MyComponent extends CustomComponent {
TextField firstNames
BeanItem<MyObject> bean = new BeanItem<MyObject>(new MyObject())
MyComponent() {
Layout layout = new FormLayout()
setCompositionRoot(layout)
firstNames = new TextField("First Names")
layout.addComponent(firstNames)
FieldGroup binder = new FieldGroup(bean)
binder.bindMemberFields(this)
}
void setFromAccount(MyObject newObject) {
bean.getItemProperty("firstNames").setValue(newObject.firstNames)
}
}
The first time I call setFromAccount the value of the firstNames text field is updated on screen. The second time it isn't, and the first value persists.
Does anyone know what's going on? I thought that whenever I set the value on the underlying property everything was updated through internal listeners. Why is it only happening the first time?

Actionscript 2 Proper way to define function on MovieClip

I'm trying to write a function on a MovieClip, and call it from the root clip. What works fine in ActionScript 3 doesn't seem to be working properly in ActionScript 2.
Frame 1 of the _root MovieClip:
var newMovieClip:MovieClip = _root.attachMovie('Notification', id, 0);
newMovieClip.SetNotificationText("Test text");
Frame 1 of the Notification MovieClip:
function SetNotificationText(inputText : String){
notificationText.text = inputText;
}
The result is that the MovieClip is created but the text is not changed.
Am I doing this wrong?
To add functions to a MovieClip in AS2, you need to use one of these methods:
Add the method to the prototype of MovieClip:
MovieClip.prototype.SetNotificationText = function(inputText:String):Void
{
if(this["notificationText"] !== undefined)
{
// If we're going to use the prototype, at least do some checks
// to make sure the caller MovieClip has the text field we expect.
this.notificationText.text = inputText;
}
}
newMovieClip.SetNotificationText("Test text");
Make the MovieClip and argument of the function:
function SetNotificationText(mc:MovieClip, inputText:String):Void
{
mc.notificationText.text = inputText;
}
SetNotificationText(newMovieClip, "Test text");
Add the method directly to the newly created MovieClip:
var newMovieClip:MovieClip = _root.attachMovie('Notification', id, 0);
newMovieClip.SetNotificationText(inputText:String):Void
{
notificationText.text = inputText;
}
newMovieClip.SetNotificationText("Test text");
Option 2 is best overall - it's the cleanest and avoids overhead of creating a new function for every new MovieClip. It also avoids messing around with the prototype, which at best should be used to add generic methods, like a removeItem() method on Array.

How do you pass statements through an addEventListener?

Iv been trying to pass arguments through an addEventListener event in actionscript such as...
target.addEventListener("pComp", rakeSoil(target));
but i get errors.
Iv tried to google but no luck :/
Thanks for replying if you do :)
The target is already passed as part of the event, either event.currentTarget or event.target will be what you want.
If you want something else passed, create a custom event. Add the property to the custom event.
Try adding an additional method as your event listener:
target.addEventListener ("pComp", targetListener);
...
private function targetListener (event:Event):void {
rakeSoil (event.currentTarget);
}
How this is what you want:
{
var target:EventDispatcher = ...;
Function rakeSoil = function (e:Event):void
{
// handle target
}
target.addEventListener("pComp", rakeSoil);
}
rakeSoil is a first class function(or closure), when event is dispatched, it will be invoked, and you can access 'target' in it.
EDIT:
Have a look at Closure (computer science)
I have always found anonymous functions to be more trouble than they are worth. I would simply follow the standard event handler code layout. It's more formal and takes a little more effort up front, but there is no ambiguity and it is far more readable when you return to it a year from now (reduces head-scratching duration):
// Target extends EventDispatcher
private var target:Target;
public function listenToTarget();
{
target = new Target();
target.addEventListener("pComp", pCompHandler);
}
private function pCompHandler(event:Event):void
{
target.rakeSoil();
}
Although, now that I look at it more closely, why are you having this object do something that Target should be capable of handling internally on its own?

Resources