Packages cannot be nested an error in flash cs6 - actionscript-3

It's my first time coding in flash, I am creating a login form wherein when user login in flash the record will automatically stored in the database.
I am currently testing the button submit, but there was an error saying "packages cannot be nested". Hope you could help me.
package actions {
import flash.display.MovieClip;
import flash.events.*;
public class main extends MovieClip {
public function main ():void {
submit_button.buttonMode = true;
submit_button.addEventListener(MouseEvent.MOUSE_DOWN, checkLogin);
username.text = "";
password.text = "";
}
public function checkLogin (e:MouseEvent):void {
trace("submission success");
}
}
}

"Packages cannot be nested" means that you have an AS file that literally includes two blocks marked package. An example of nesting:
package a {
...
package b {
....
}
}
You need to revise your code so that no file contains nested package blocks. This isn't an error in programming, but rather a markup error (that potentially hides a lot of uneven braces or other types of copy&paste mixups).
UPDATE: A timeline code is declared as being inside a package, so if you are trying to add a package ...{...} block to a timeline, you will get this very error.

Related

linking fla files together in actionscript using document classes

I am working in actionscript3, and since I'm self-taught, I think I've developed some bad habits, including coding on the timeline and using multiple scenes.
I am hoping to rectify this now that I'm working on a larger project.
Based on what I've read, linking multiple .fla files together is a better practice, each with their own document class. Is that correct?
If so, how do I load one .fla with its document class and then link that into the subsequent .fla file (instead of using scenes)? Or am I misinterpreting what was recommended?
Thanks!
There's no point to split your application in several loadable modules unless you have any of the following preconditions:
you have smart resource management to load and unload content
if you put everything into one file it gets just too big and hard to work with in design time or it takes far too long to compile
Regular AS3 alternative to working with scenes is creating/destroying content instances and using the main document class as their manager. You design content in the library and create behavior AS3 classes for them. Lets say, you have two content classes A and B. At the start the manager should show one of them and wait for the signal to show next one:
private var APage:A;
private var BPage:B;
gotoA();
function gotoA():void
{
if (BPage)
{
BPage.destroy();
removeChild(BPage);
BPage.removeEventListener(Event.CLOSE, gotoA);
}
APage = new A;
APage.addEventListener(Event.CLOSE, gotoB);
addChild(APage);
}
function gotoB():void
{
if (APage)
{
APage.destroy();
removeChild(APage);
APage.removeEventListener(Event.CLOSE, gotoB);
}
BPage = new B;
BPage.addEventListener(Event.CLOSE, gotoA);
addChild(BPage);
}
So, both A and B should have respective methods .destroy() that release used resources, unsubscribes methods from events, remove display objects, and so on, and they both should fire Event.CLOSE when they're done.
If you have many pages like that, you need to go for more algorithmic approach. For example, to create class BasicPage which will interact with manager and have the methods needed in all pages already declared:
package
{
import flash.display.Sprite;
class BasicPage extends Sprite
{
// A reference to the page manager instance.
public var Manager:PageManager;
public function destroy():void
{
while (numChildren > 0) removeChildAt(0);
Manager = null;
}
// Subclasses will have an access to this method to tell manager to show another page.
protected function showOtherPage(pageClass:Class):void
{
Manager.showPage(pageClass);
}
// A method that is called by manager when everything is ready.
// If page should take any actions on start it is a good idea to override this method.
public function startEngine():void
{
}
}
}
Then, example page A:
package
{
import flash.events.MouseEvent;
public class A extends BasicPage
{
// Lets say, class A in library have a designed button named Click.
public var Click:SimpleButton;
// We have things to undo here.
override public function destroy():void
{
Click.removeEventListener(MouseEvent.CLICK, onClick);
Click = null;
// Pass the destruction to superclass so it wraps its existence either.
super.destroy();
}
override public function startEngine():void
{
Click.addEventListener(MouseEvent.CLICK, onClick);
}
private function onClick(e:MouseEvent):void
{
// Lets use inherited method to show other page.
showOtherPage(B);
}
}
}
So, PageManager will be like:
package
{
public class PageManager extends Sprite
{
private var Page:BasicPage;
// constructor
function PageManager()
{
super();
showPage(A);
}
function showPage(pageClass:Class):void
{
if (Page)
{
Page.destroy();
removeChild(Page);
Page = null;
}
Page = new pageClass;
Page.Manager = this;
addChild(Page);
Page.startEngine();
}
}
}
This all could look scary at first, but it really isn't. PageManager will always have a current page, once there's a need to show another page, the current will be destroyed on a regular basis. Each page class will tend to its own content, which makes coding simpler, for you don't need to see the whole picture. If you need any persistent data, keep it in the PageManager so each page will have access to the data with no need for the pages to communicate with each other.

Display check boxes inside flash list control CS6

I would like to implement check boxes inside flash list control using Flash Pro CS6. I literally follow example provided by Adobe at Work with a CellRenderer. The only code in my .fla file is:
myList.setStyle("cellRenderer", CustomCellRenderer);
myList.addItem({label:"Burger -- $5.95"});
myList.addItem({label:"Fries -- $1.95"});
and the only code in the CustomCellRenderer.as file is (copy-paste from the Adobe example):
package
{
import fl.controls.CheckBox;
import fl.controls.listClasses.ICellRenderer;
import fl.controls.listClasses.ListData;
public class CustomCellRenderer extends CheckBox implements ICellRenderer {
private var _listData:ListData;
private var _data:Object;
public function CustomCellRenderer() {
}
public function set data(d:Object):void {
_data = d;
label = d.label;
}
public function get data():Object {
return _data;
}
public function set listData(ld:ListData):void {
_listData = ld;
}
public function get listData():ListData {
return _listData;
}
}
}
When I test movie I get the following error:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at fl.controls::CheckBox/drawLayout()
at fl.controls::LabelButton/draw()
at fl.core::UIComponent/drawNow()
at fl.controls::List/drawList()
at fl.controls::List/draw()
at fl.core::UIComponent/callLaterDispatcher()
Any help would be greatly appreciated.
P.S. The author of similar question Display checkbox inside Flash List Control ? (Similar to item rendering in Flex) does not seem to have this problem - his problem is just in multiple selection functionality.
ANSWER (can not post answers for another 8 hour but eager to close the issue) Figured out myself: CheckBox component must be present in the library. Go to menu Window->Components-> Double click CheckBox. Check box will appear on the stage and in the library. Remove check box from the stage. Test movie.
Drag an instance of CheckBox component onto the stage then delete off the stage.

MovieClip button In Class

Tried this,
package {
import flash.display.MovieClip;
import flash.events.*;
public class test extends MovieClip {
public function test() {
addEventListener(Event.ADDED_TO_STAGE, registerBtn);
}
private function registerBtn(e:Event):void {
this.parent["Homebtn"].addEventListener(MouseEvent.CLICK, myButtonClick);
}
private function myButtonClick(e:MouseEvent):void {
trace("CLICKED");
}
}
}
Image
And the same code on frame 1, And there's a MovieClip Button on stage having Instance name "Homebtn".
Imports
import flash.events.*;
Importing all classes from a package that originates in flash has zero impact on compile size because they're already present in the Flash Player runtime environment. It's pure monotony that you're required to explicitly declare these imports, but good practice when dealing with third party packages.
Stage Relationship
Document code (i.e., code in the Flash IDE timelines) have a direct relationship to MainTimeline, whereas class files do not. If you want to add button1.addEventListener(MouseEvent.CLICK, myButtonClick); to your class, you're not going to be able to do so unless you:
A: Pass a pointer to the button/stage/root to the class when instantiating your test class:
var myObj:test = new test(root)
B: Wait to add the event listener until after you've given the test object a parent relationship to the stage from which to traverse to the button:
addChild(test);
inside your class...
public function test() {
// constructor code
addEventListener(Event.ADDED_TO_STAGE, registerBtn)
}
private function registerBtn():void {
this.parent.button1.addEventListener(MouseEvent.CLICK, myButtonClick);
}
Turn on Debugging
To find the cause of your bugs, you need to debug your code. If you're using Flash IDE CS6, then you can enable this by going to your publish settings and enabling "Permit Debugging". This will take your ambiguous error...
null object reference at myDocument/doSomething()
...to a much clearer...
null object reference at myDocument/doSomething() package\myClass.as:20
...which now denotes which line in your code to look for your issue.
Use the Debug Console
Use the debugging compile mode to bring up the Debug Console. This will provide you with an immediate look at the line of code in question, as well as the Call Stack, and the state of all available Variables. No programmer should be without it.
Run by going to the menu "Debug > Debug Movie > Debug", or use the keyboard combo CONTROL+SHIFT+ENTER.
Now that you're armed with the know-how to do this on your own, I'll cover what you'd encounter, and how you'd fix it (since you're new).
First, it's flash.events with an "s". So we'll change that.
Next, compiling it we get the following errors:
So we see on line 7 of our test.as class: you've placed the timeline code into the class.
var myObj:test = new test(root);
addChild(test);
You don't want to instantiate you class from within itself as it'll never get instantiated. Think of your code as a railroad. The train starts with your timeline code, and only runs on the rails set before it. Your class is floating off to the side, ready with all its interesting turns and zigzags, but you have to add it to the rails for it to be actually run. That's instantiation; we're copying that path onto the current track, and the train runs on it.
So, we get rid of lines 6 & 7, and we're left with Access of possibly undefined property Homebtn. Calling this.parent is actually a getter function, and it returns a DisplayObjectContainer. Because AS3 is a strongly datatyped language, the compiler will know that there is no such property "Homebtn" on DisplayObjectContainers (silly compiler). But of course, you know it's there (or at least it will be by the time this code runs). A simple way of getting around that is by making it evaluate the reference at run-time.
this.parent["Homebtn"].addEventListener(MouseEvent.CLICK, myButtonClick);
By encapsulating the button name as a string and within brackets, we've done that.
Now we recompile again, and get the following:
This is because all event listeners receive one argument: an event object. You may not use it, but not having a variable to hold it is a no-no.
private function registerBtn(e:Event):void {
As a final point. All class functions need to be denoted as to what namespace they exist in. myButtonClick needs one, so we'll add it as private since no external (ie., non-class based) functions need access to it.
Here's your revised code:
test.as
package {
import flash.display.MovieClip;
import flash.events.*;
public class test extends MovieClip {
public function test() {
addEventListener(Event.ADDED_TO_STAGE, registerBtn);
}
private function registerBtn(e:Event):void {
this.parent["Homebtn"].addEventListener(MouseEvent.CLICK, myButtonClick);
}
private function myButtonClick(e:MouseEvent):void {
trace("CLICKED");
}
}
}
test.fla (timeline code on frame 1)
import test;
var Homebtn:MovieClip = new MovieClip();
Homebtn.graphics.beginFill(0xFF0000, 1);
Homebtn.graphics.drawRect(0, 0, 150, 25);
Homebtn.graphics.endFill();
addChild(Homebtn);
var testObj:test = new test();
addChild(testObj);

keyboard input with actionscript

I'm writing in pure actionscript in notepad with flex as a compiler. Here's the code I have
package
{
import flash.display.*;
import mx.core.*;
import flash.events.*;
import mx.collections.*;
import flash.geom.*;
import mx.controls.*;
import flash.text.*;
import mx.events.*;
import mx.styles.*;
import mx.containers.*;
public class MAIN extends Sprite
{
public var APPLICATION:Application = Application(Application.application);
public var FRAME:int = 0;
public function MAIN()
{
addEventListener(KeyboardEvent.KEY_DOWN,keyDownHandler);
STEP();
}
public function STEP():void
{
FRAME ++;
STEP();
}
public function keyDownHandler(event:KeyboardEvent):void
{
var keyDownText:TextField = new TextField();
keyDownText.text = "Key code: " + event.keyCode;
this.addChild(keyDownText);
}
}
}
What I want is for whatever key I happen to press to be drawn on the screen (though actually I think it would only be the ascii number it corresponds to but that doesn't matter). Right now though everything's just blank. Another thing is because I'm not using any mxml I don't know if i've established the game loop correctly so let me know if that needs to be fixed.
Try
stage.addEventListener(KeyboardEvent.KEY_DOWN,keyDownHandler);
instead of
addEventListener(KeyboardEvent.KEY_DOWN,keyDownHandler);
Since your Sprite doesn't have a visible area, it will not receive keyboard or mouse input.
Also the STEP() function will cause a stackoverflow because it's infitely recursive.
If you want a main loop that gets called periodically, try using an ENTER_FRAME handler or a Timer.
Something like this:
public function MAIN()
{
addEventListener(KeyboardEvent.KEY_DOWN,keyDownHandler);
addEventListener(Event.ENTER_FRAME,STEP);
}
private function STEP(e:Event):void {
FRAME++;
}
To stop it, do this:
removeEventListener(Event.ENTER_FRAME,STEP);
Not sure why you are using ALL CAPS for some methods and variables. Although it's not a language requirement, all caps are generally reserved for constants. Method names use camelCase. And types use PascalCase (like camelCase, but the first letter is capitalized). So your class would be Main, FRAME would be fram, STEP would be step, etc. You're better off sticking to these common naming schemes, I think.
And another thing. You probably shouldn't be creating a new TextField instance everytime you want to output some text. One textfield will do it in your case, I think. So create and addChild the textfield on some kind of init method that you call when you start your class and then just use the text property of this textfield to write your messages.

AS3: Accesing function on the maintime line from a extended movieclip class

I have some movieclips on my main timeline with a class to extend these movieclips
ClickableMovieClip.as:
package {
import flash.display.MovieClip;
import flash.events.*;
public class ClickableMovieClip extends MovieClip {
public function ClickableMovieClip():void {
this.buttonMode = true;
this.addEventListener(MouseEvent.MOUSE_UP, onReleaseHandler);
}
public function onReleaseHandler(myEvent:MouseEvent) {
//trace(" > "+this.name);
testing();
}
}
}
And on my maintime line I have this function testing();
function testing(){
trace("hello world!");
}
But the I can't 'reach' the testing function. I get this error:
"1061: Call to a possibly undefined method testing through a reference with static type flash.display:DisplayObjectContainer."
What am I doing wrong?
First of all, how are you connecting your AS3 class to the stage? Importing it in a frame or using it as the Document Class?
This may have to do with inheritance.
Second, you may need to call it using (root As MovieClip).testing() or something like that. The idea is that you need to call it as a method of the stage or root. I don't remember exactly how it works.
EDIT:
As you said MovieClip(parent).testing(); is the answer. I forgot the exact syntax before...