I try to create a function to change border property of border container.
To do that I create a function for each border container on my MXML.
But I'd to code better and to do a generic function.
Today my function is:
protected function bcContact_mouseOverHandler(event:MouseEvent):void
{
// TODO Auto-generated method stub
bcContact.setStyle("borderVisible",true);
bcContact.setStyle("borderWeight",2);
bcContact.setStyle("borderColor",'#000099');
}
bcContact is one border container Id.
I try to replace bcContact by this but it doesn't work.
Can you help me to solve this beginner mistake.
Thanks
U can use event.CurrentTraget and then use the compare functions, compare with ids and do the settings.
You could extend the BorderContainer class (in Flash Builder, put in BorderContainer in the "Super class" text field)
Your class will look something like this:
import flash.events.MouseEvent;
import spark.components.BorderContainer;
package com.extensions.containers {
class MyBorderContainer {
function MyBorderContainer() {
this.addEventListener(MouseEvent.MOUSE_OVER, changeStyle);
this.addEventListener(MouseEvent.MOUSE_OUT, undoStyle);
}
private function changeStyle(e:MouseEvent):void {
this.setStyle("borderVisible",true);
this.setStyle("borderWeight",2);
this.setStyle("borderColor",'#000099');
}
private function undoStyle(e:MouseEvent):void {
this.setStyle("borderVisible",false);
this.setStyle("borderWeight",0);
this.setStyle("borderColor",'#000000');
}
}
}
This class will need to be in the file src/com/extensions/containers/MyBorderContainer.as
Then use this in your mxml as
<containers:MyBorderContainer>
</containers:MyBorderContainer>
where the namespace containers is set to point to com/extensions/containers
Related
I have been struggling with the following for a couple of hours now, how do you call a custom class from another class if you do not extend that class for example.
I have on my main Base class a timer event, Base.myTimer.addEventListener(TimerEvent.TIMER, processTime) - Base class
Then I remove the method later in the code Base.mytimer.removeEventListener(TimerEvent.TIMER, processTime. - Base class
I have a button (Btn class) that when its done processing I want to call that method again, but I can't get it to work because the method does not exist in the button class but on the Base class so flash obviously gives me the error processTime is not defined.
For example now I want to re-instantiate the event listener from within the button, so I have
Base.myTimer.addEventListener(TimerEvent.TIMER, processTime);
or this.parent.parent["myTimer"].addEventListener()
myTimer is a static Timer in Base class.
I can make a normal dispatchEvent if its not a custom method for example Base.myTimer.dispatchEvent(new TimerEvent(TimerEvent.TIMER)).
The examples I have seen so far have not resolved my issue. Any help would be appreciated.
Looks like the button class is part of the child tree of the Base class. In this case, you can just do a dispatchEvent from the button class when it is clicked
dispatchEvent(new Event("AddListenerAgain", true));
In the Base class, you must be having access to the button class already, hence you can say:
button.addEventListener("AddListenerAgain", addListener);
Then in the Base class
private function addListener(e:Event) : void {
myTimer.addEventListener(TimerEvent.TIMER, processTime);
}
In this example, I have dispatched and listened for raw strings. This is not a recommended practice. You must read on how to dispatch custom events to do it correctly.
You could pass a reference to an instance of Base class into your Button instance.
// Button class
package {
import Base;
// Other imports...
public class Button {
public function Button(base:Base):void {
// processTime and myTimer must be public.
// I put this line in the constructor for brevity, but if you stored base
// in an instance variable, you could put this anywhere in the button
// class.
Base.myTimer.addEventListener(TimerEvent.TIMER, base.processTime)
}
}
}
// Create button like this.
var button:Button = new Button(base);
// Or if button is created inside of Base
var button:Button = new Button(this);
Even better would be to create two methods in the Base class, for adding and removing the listeners, and make myTimer and processTime private:
public class Base {
public function addTimerListeners():void {
myTimer.addEventListener(TimerEvent.TIMER, processTime)
}
public function removeTimerListeners():void {
myTimer.removeEventListener(TimerEvent.TIMER, processTime)
}
}
Then you can call these two methods from outside of the class. This keeps the inner workings of your class more hidden. If you decided you wanted to change myTimer to a instance variable instead of static, you wouldn't have to make any changes to code outside of your Base class. This is called encapsulation and is a good practice.
I have a custom Flex Toggleswitch component that changes the text values of the switch.
package skins
{
import spark.skins.mobile.ToggleSwitchSkin;
public class MyToggleSwitchSkin extends ToggleSwitchSkin
{
public function MyToggleSwitchSkin()
{
super();
selectedLabel="Serviceable";
unselectedLabel="Fault";
}
}
}
If I add the control using the MXML tag, it works fine. However, when I add the component using action script, it does not.
import skins.MyToggleSwitchSkin;
public function addToggle():void {
var myCustomToggle:MyToggleSwitchSkin = new MyToggleSwitchSkin();
hgroup.addElement(myCustomToggle);
}
The control dsiplays but will not activate.
Any ideas what I have missed?
Without seeing your MXML Code, it's tough to compare your two approaches, but I believe #al_Birdy addressed the problem. You've created a custom ToggleSwitchSkin; not a custom ToggleSwitch.
Modify your addToggle() method like this:
public function addToggle():void {
var myCustomToggle:MyToggleSwitch = new MyToggleSwitch();
myCustomToggle.setStyle('skinClass',skins.MyToggleSwitchSkin);
hgroup.addElement(myCustomToggle);
}
I suspect you'll have better luck.
When adding event listeners and defining their corresponding functions I find myself defining the function in the code of a constructor a lot. Something like this:
package
{
public class stuff extends Sprite
{
public function stuff()
{
minimizeBtn.addEventListener(MouseEvent.CLICK, minimizeOnClick);
function minimizeOnClick(e:MouseEvent):void
{
//do minimization stuff here
}
}
}
}
However, there is clearly another option to define it like any other method of the class. Something like this:
package
{
public class stuff extends Sprite
{
public function stuff()
{
minimizeBtn.addEventListener(MouseEvent.CLICK, minimizeOnClick);
}
internal function minimizeOnClick(e:MouseEvent):void
{
//do minimization stuff here
}
}
}
The second option may not really make sense because the function isn't really a method of the class. But my concern is that the first method will use up extra memory for each instance of the class. Which is the most efficient and correct way to do this and also does the first method take up extra memory or CPU time for each instance of the class?
Thanks!
The latter example is the correct way, and it's true that you should try encapsulate your addEventListener() and listening function within the relevant class. In your case, you may want to consider making a class for your minimizeBtn:
public class MinimizeButton extends SimpleButton
{
public function MinimizeButton()
{
addEventListener(MouseEvent.CLICK, _onClick);
}
private function _onClick(e:MouseEvent):void
{
// do minimization stuff here
}
}
MinimizeButton's _onClick() should then target the relevant instance of your class stuff and run whatever stuff needs to do from there.
This example's process is more like:
MinimizeButton: "I've been clicked, I should inform stuff so it can do something relevant."
Rather than:
stuff: "I'm going to sit and wait for MinimizeButton to get clicked, then I'll do what's required."
I'm having a slight issue with ActionScript 3 and I have come here to ask for some help.
I have two classes. One called Sledge and one called Sock, there is also the document class called Main.
My issues are as follows:
Inside of Sledge, I call a function that is defined inside of the Main document class. How would I go about telling the class to go to the document class and run that function? Would this also be the same for other classes or just for the document class?
Inside Sledge, I have the following statement: if(hitTestObject(sock.myHitArea)) { /* somecode*/ }
sock is an instance of another seperate class, and by this point has already been created. However when I try and run this I am told it is not defined. How would i go about solving this?
There's some ambiguity issues with how you expressed your question. It would help if you posted a short form of the code for the problem.
However, I'll try to answer the first question:
Inside of Sledge, I call a function that is defined inside of the Main document class. How would I go about telling the class to go to the document class and run that function?
You would want to pass the Main class to the Sledge class or use events which is preferable. If pass the class it will look like this...
class Sledge {
private var main:Main;
function Sledge(main:Main) {
this.main = main;
}
function doSomething():void {
main.runSomeFunction();
}
}
Or if using events:
class Main {
private var sledge:Sledge;
function Main() {
sledge = new Sledge();
sledge.addEventListener("mainDoSomething", doSomething);
}
private function doSomething(e:Event):void {
// .... do stuff
}
}
class Sledge extends EventDispacter {
function Sledge() {
}
public function doSomething():void {
dispatchEvent(new Event("mainDoSomething"));
}
}
I've got a AS3 program with a Main.as custom class.
In this class I load an instance of a 'menu' movieclip which has simpleButton instances inside... How do I access the Main class public functions by the menu movieclip buttons?
I.e. Menu button -> gotoPage(5); (which is a Main public function)
If I try to access the Main function with the above statement, it gives
"1180: Call to a possibly undefined method gotoPage.
Create a static method called GetMain() on the Main class that would return the instance of Main (Main should be a singleton).
package whatever
{
public class Main
{
private static var _instance:Main = null;
public static function getMain():Main
{
return _instance;
}
// Main constructor
function Main(..):void
{
_instance = this;
}
}
}
To refer to the instance of Main() from your Menu class, you could use:
Main.getMain().gotoPage(5);
You want to do this with events. If your menu movieclip is a child of Main.as as you say, name the instance buttons inside of the menu movieclip, and set up the listeners in Main.as:
1) Put the below code in the constructor: public function Main(){...
menu.button_a.addEventListener(MouseEvent.CLICK, onButtonClick);
menu.button_b.addEventListener(MouseEvent.CLICK, onButtonClick);
2) and then write the onButtonClick function in Main.as
private function onButtonClick(e:MouseEvent):void{
switch(e.currentTarget.name){
case "button_a":
//call the Main.as function you want here
break;
case "button_b":
//call a different Main.as function
break;
}
ruedaminute's answer on dispatching events from the buttons and having main process those events is by far the best way to handle this, but there are many ways to do this in as3 - but try to use the aforementioned technique. Some of the other techniques.
Make a function in Main such as public function GotoPage(iPageNum:int):void{}
from a button - try this._parent.GotoPage(1);
but this._parent might not be main, do a trace(this._parent), and keep trying
it might end up being
this._parent._parent._parent.GotoPage(1) depending on your display tree hierachry.
Again, this is REALLY bad OOP practices, but well, it will work.
Another tecnique - use a singleton for main- looks like u already are - add that same public method, then from the button click, you could do Main.getMain().GotoPage(1);
That is a bit better, in that you can change the display tree and not have to figure out where the heck Main is in the display tree, but singletons also are discouraged for a variety of reasons, but in this case I would say it makes since.
Good Luck!
~ JT