In ActionScript 3, is conditional if/else compilation of class variables valid? - actionscript-3

I'm working with an AS3 class in Flash Builder 4.6, AIR 3.5.
Can anyone confirm that the following if/else syntax is valid in the class definition. I've tested it and it compiles and runs on Mac, but I can't find documentation that supports it.
package controller
{
import flash.desktop.NativeApplication;
import flash.display.NativeMenu;
import flash.display.NativeMenuItem;
import flash.display.NativeWindow;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;
[Bindable]
public class AppMenu extends EventDispatcher
{
if (Capabilities.os.search("Mac")>-1) {
public var titularMenu:NativeMenu;
public var fileMenu:NativeMenu;
public var editMenu:NativeMenu;
private var optionsMenu:NativeMenu;
private var addOnsMenu:NativeMenu;
private var helpMenu:NativeMenu;
} else {
// Assign same variables as NativeMenuItem, for Windows.
}
// etcetera
}

No, you can't have if/else conditionals outside methods or initializers.
For your purpose, you could juste use define the generic properties/methods inside an interface IAppMenu, and then have one implementation per OS (of course, you will still need to define which one to create using Capabilities.os).

Related

Actionscript3 setting time delay

trying to make a time delay before redirection to a specific web page , I got many errors during the compiling process , sorry new to actionscript :
package
{
import flash.display.*;
import flash.net.*;
import flash.system.*;
import flash.utils.*;
import flash.events.*;
public class test extends flash.display.Sprite
{
public function test()
{
super();
flash.net.navigateToURL(new flash.net.URLRequest("http://youpassed-theexam.com/congrats"), "_self");
return;
}
}
setInterval(test,5000);
}
A couple of issues with your code:
Constructors of classes are immediately called once the class is
instantiated. You should create a separate method and call that with
a delay from within your constructor.
setInterval would fire repeatedly after every set interval. You
should rather use setTimeout.
Classes should have a Sentence caps naming convention, so Test and not test. Just a best practice. Nothing wrong syntactically.
Constructors do not return anything so we do not need the return statement.
Once you have imported a class, you do not need to write the full name of the class to access it's methods.
Try to avoid * based import statements. It does tend to import a lot more classes than just the required class. Again, just a best practice.
So your code should look something like this below:
package
{
import flash.display.Sprite;
import flash.net.URLRequest;
import flash.net.navigateToURL;
import flash.utils.setInterval;
import flash.utils.setTimeout;
public class Test extends flash.display.Sprite
{
public function Test()
{
super();
setTimeout(gotoURL, 5000);
}
protected function gotoURL():void
{
navigateToURL(new URLRequest("http://youpassed-theexam.com/congrats"), "_self");
}
}
}
Hope this helps. Cheers.

AS3 can't find the load method on a Loader

I'm trying to load an image from the internet with AS3 following this tutorial. When I try to compile the application I get the following error:
Call a possibly undefined method load through a reference with static type Loader.
my_loader.load(where, loaderContext);
^
Here is the code I'm using:
package {
import flash.system.ApplicationDomain;
import flash.system.SecurityDomain;
import flash.net.URLRequest;
import flash.system.LoaderContext;
import flash.display.Loader;
import flash.events.*;
import flash.external.ExternalInterface;
import flash.display.Sprite;
public class Loader extends Sprite {
public function Loader() {
var where:URLRequest = new URLRequest("image_from_web.png");
var loaderContext:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain, null);
var my_loader:Loader = new Loader();
my_loader.load(where, loaderContext);
addChild(my_loader);
}
}
}
In this page compilerErrors(ErrorCode = 1061) says that this occurs when I try to call a method that does not exist.
I'm using Ubuntu 14.10 and compiling with ProjectSprout that uses the flex compiler.
Your issue is namespace clashing (ambiguous class names). The class you've posted is called Loader, yet you try to import another Loader class. AS3 doesn't know what you refer to when you reference Loader now. So it is looking for a load method on your custom Loader class (which doesn't exist).
To resolve the issue, either rename your custom class to something less ambiguous (MyImageLoader maybe, or whatever) - or use the fully qualified class path when referring to the display package Loader. eg.
var my_loader:flash.display.Loader = new flash.display.Loader();

How to access parent or wrapper variables from an AS3 Worker Class

I am using Flash Builder 4.7 and have created a Worker Class. Below is the code:
package co.fuix.mobile.system.model
{
import flash.display.DisplayObjectContainer;
import flash.display.Sprite;
import flash.events.Event;
import flash.system.MessageChannel;
import flash.system.Worker;
import flash.utils.getDefinitionByName;
import mx.managers.SystemManager;
public class InstantMessengerWorker extends Sprite
{
private var bm:MessageChannel;
private var mb:MessageChannel;
public function InstantMessengerWorker()
{
super();
bm = Worker.current.getSharedProperty("BACK_TO_MAIN_CHANNEL");
mb = Worker.current.getSharedProperty("MAIN_TO_BACK_CHANNEL");
mb.addEventListener(Event.CHANNEL_MESSAGE, onMainToBack);
}
protected function onMainToBack(event:Event):void
{
if(mb.messageAvailable){
var s:SystemManager;
trace('*'+mb.receive());
trace('**'+mb.receive());
trace('***'+mb.receive());
trace(mx.core.FlexGlobals.topLevelApplication.myVariable);
}
}
}
}
How do I reference a variable in the main mxml file. I know how to use message channels but I want to get that variable straight.
When I run the above code, this part
trace(mx.core.FlexGlobals.topLevelApplication.myVariable);
is giving me an error.
Any help will be regreatly appreciated
You can't access a variable from the main app like that. They are running separately. What you need to do is:
Link to Adobe docs

How to import class from user actionscript file

I just want to create a class with two Numbers and a Bitmap. You can't have nested classes in a Timeline script so I figured I'd make .as file, namely "node.as". But I cannot for the life of me figure out how to import this class into the Timeline script so that I can use the class in my Timeline script.
Please help!
You should be able to create a package to accomplish this. The basic format is:
// folder specifies the relative folder of the package
package myfolder {
// whatever other classes you need
import flash.display.*;
import flash.events.*;
// base this on whatever class you need (in this case MovieClip)
public class myclass extends MovieClip {
private var myvariable: String;
// constructor
public function myclass() {
}
// functions only for use within the class
private function myprivatefunction() {
}
// functions for use by the rest of the world
public function mypublicfunction() {
}
}
}
The constructor is called when you create a new instance of the Class-- this is where you would do your initialization. Then, in your timeline, just add something like:
import myclass;
var myclassinstance = new myclass();
myclassinstance.mypublicfunction(); // call a function in the class
See adobe's help for more details.
So I tried this:
package {
import flash.display.*;
public class Node {
public var fX:Number;
public var fY:Number;
public var bmp:Bitmap;
public function Node() { }
}
}
And put it in a file called Node.as (note I needed to add the flash.display import, and the capital "N" in the filename). In a FLA file in the same directory, I added this to the first frame script:
import Node;
var node = new Node();
trace("node="+node);
It compiled and ran without error. There must be something else going on? What version of Flash and of ActionScript are you using?

Why put import statements in package?

In AS3, why do we put our import statements in the package statement, and not inside the Class declaration?
This is a typical (but rather pointless) AS3 class:
package my.foo.package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.utils.Timer;
public class FooClass extends MovieClip
{
public static const EVENT_TIME_UP:String = 'timeUpEvent';
public function FooClass()
{
var timer:Timer = new Timer(2000, 1);
timer.addEventListener(TimerEvent.TIMER, timerHandler);
timer.start();
}
private function timerHandler(e:TimerEvent):void
{
dispatchEvent(new Event(FooClass.EVENT_TIME_UP));
}
}
}
But why are all the import statements meant to go all the way up there, outside on the Class? The class works perfectly fine when I move the imports to inside the class declaration like below.
package my.foo.package
{
import flash.display.MovieClip;
public class FooClass extends MovieClip
{
import flash.events.Event;
import flash.events.TimerEvent;
import flash.utils.Timer;
public static const EVENT_TIME_UP:String = 'timeUpEvent';
public function FooClass()
{
var timer:Timer = new Timer(2000, 1);
timer.addEventListener(TimerEvent.TIMER, timerHandler);
timer.start();
}
private function timerHandler(e:TimerEvent):void
{
dispatchEvent(new Event(FooClass.EVENT_TIME_UP));
}
}
}
It's only the MovieClip import that needs to be in package, because my class is extending it.
There is nothing helpful about this in the Adobe AS3 coding conventions.
So why do we put the imports in the package and not the class that's actually using them. The package is not using the imported classes is it? And why does it still work if I move the imports into the Class?
This is simply a convention that's in use so there is one central place to view all of the imports. Let's say we take your logic to the next extreme and place an import statement on the line just before every variable we declare (which compiles just fine by the way). We'd wind up needlessly duplicating import statements whether on purpose or by accident. Also, someone wanting to see what dependencies a given file has would have to scan the whole file rather than looking at just the top of the file. Your point of putting the imports within the class declaration isn't as crazy, but you'd still wind up with the problem of imports scattered throughout a file if your file declares more than one class (as in the case of internally used classes, for example).