Cannot access a property or method of a null object reference - apache-flex

I try to do preloder in Flex for my project written in Flash.
I make this with the help of this site
link text
My Flash project have next source in main class called Game
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDown);
stage.addEventListener(KeyboardEvent.KEY_UP, keyUp);
private function keyDown(event:KeyboardEvent) {
if (event.keyCode == 81 && q_was_push == false) q_was_push = true;
if (event.keyCode == 81) press_q = true;
if (event.keyCode == 65) press_a = true;
if (event.keyCode == 83) press_s = true;
if (event.keyCode == 32) press_space = true;
} ...
When I take new swf file maked by Flex, I have error
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at Game()
if I comment
//stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDown);
//stage.addEventListener(KeyboardEvent.KEY_UP, keyUp);
Flex application work but Flash application does not react to button presses
Please how I can make preloader and work buttons together

The stage property will be null until a display object is added to the display list. Listen to the addedToStage event and add the key listeners from there.
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
function onAddedToStage(e:Event):void
{
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDown);
stage.addEventListener(KeyboardEvent.KEY_UP, keyUp);
}

Anytime you need access to the stage, have the Class listen for it/check for it in the constructor, and have your init function be the handler.
package
{
import flash.display.Sprite;
import flash.events.Event;
/**
* ...
* #author Brian Hodge
*/
public class SomeClass extends Sprite
{
public function SomeClass()
{
if (stage) _init();
else addEventListener(Event.ADDED_TO_STAGE, _init);
}
private function _init(e:Event = null):void
{
//You may now access the stage property of the DisplayObject.
stage.addEventListener(Event.RESIZE);
}
}
}

Related

Connecting flex and weborb?

im a newbie in flex. Im have a question :)
I have
[Bindable]
private var model:AlgorithmModel = new AlgorithmModel();
private var serviceProxy:Algorithm = new Algorithm( model );
In MXML
private function Show():void
{
// now model.Solve_SendResult = null
while(i<model.Solve_SendResult.length) //
{
Draw(); //draw cube
}
}
private function Solve_Click():void
{
//request is a array
Request[0] = 2;
Request[1] = 2;
Request[2] = 3;
serviceProxy.Solve_Send(request);
Show();
}
<s:Button x="386" y="477" label="Solve" click="Solve_Click();"/>
And when i call serviceProxy.Solve_Send(request); with request is array and i want use model.Solve_SendResult in my code flex to draw many cubes use papervison3d but in the first time i received model.Solve_SendResult = null . But when I click again then everything OK.
Anyone help me? Thanks?
The model.Solve_SendResult object contains a result of the executed serviceProxy.Solve_Send(request) method. The Solve_Send will be executed asynchronously and as a result, at the moment when you fire the show method the Solve_SendResult object may be still null.
As a solution, you can use the following:
Create a custom event
package foo
{
import flash.events.Event;
public class DrawEvent extends Event
{
public static const DATA_CHANGED:String = "dataChanged";
public function DrawEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}
}
In your Algorithm class define the following:
[Event(name=DrawEvent.DATA_CHANGED, type="foo.DrawEvent")]
public class Algorithm extends EventDispatcher{
//your code
In the Solve_SendHandler method of the Algorithm class add the following
public virtual function Solve_SendHandler(event:ResultEvent):void
{
dispatchEvent(new DrawEvent(DrawEvent.DATA_CHANGED));
//your code
}
In your MXML class create onLoad method and add an event listener to an instance of the Algorithm class as it shown below:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="onLoad()">
public function onLoad():void
{
serviceProxy.addEventListener(DrawEvent.DATA_CHANGED, onDataChanged);
}
private function onDataChanged(event:DrawEvent):void{
while(i<model.Solve_SendResult.length) //
{
Draw(); //draw cube
}
}
make the following changes in the Solve_Click() method:
private function Solve_Click():void
{
//request is a array
Request[0] = 2;
Request[1] = 2;
Request[2] = 3;
serviceProxy.Solve_Send(request);
}
That is it! So, basically the code above do the following: you added a listener to your service (algorithm class), and the listener is listening for the DrawEvent.DATA_CHANGED event. The DrawEvent.DATA_CHANGED will be dispatched when your client receive a result of the Solve_Send invocation. Thus, the onDataChanged will draw your cube or do whatever you want :)
The approach above is basic and you have to know how events work in flex and how you can deal with it. Additional information is available here:
http://livedocs.adobe.com/flex/3/html/help.html?content=createevents_3.html
http://livedocs.adobe.com/flex/3/html/help.html?content=events_07.html
Regards,
Cyril

Remove by order TitleWindows in Flex

I create 3 TitleWindow:
PopUpManager.addPopUp( TitleWindow1, root, false);
PopUpManager.addPopUp( TitleWindow2, root, false);
PopUpManager.addPopUp( TitleWindow3, root, false );
And then I manage those position and depth using mouse. Now I want to delete them by depth.
In my TitleWindow add listener:
root.addEventListener( KeyboardEvent.KEY_DOWN, onKeyDown );
private function onKeyDown(event:KeyboardEvent = null):void {
if ( event.keyCode == Keyboard.ESCAPE && this. ) { //!!!! how to detect this window depth, that it at first plan??
event.preventDefault();
event.stopImmediatePropagation();
closeHandler();
}
}
}
How does me solve this issue?
Now, I can offer one idea, I use state inactive:
private function onKeyDown(event:KeyboardEvent = null):void {
if ( event.keyCode == Keyboard.ESCAPE
&& this.getCurrentSkinState() != "inactive" ) {
event.preventDefault();
event.stopImmediatePropagation();
closeHandler();
}
}
override protected function stateChanged (oldState:String, newState:String, recursive:Boolean) : void {
super.stateChanged( oldState, newState, recursive );
if ( oldState == "inactive" && newState == "normal" ) {
PopUpManager.bringToFront( this );
}
}
You'll need to keep track of this when you add the pop ups. Here is an example class that extends the pop up manager:
package
{
import flash.display.DisplayObject;
import mx.collections.ArrayCollection;
import mx.core.IFlexDisplayObject;
import mx.core.IFlexModuleFactory;
import mx.core.UIComponent;
import mx.managers.PopUpManager;
public class PopManagerDepth extends PopUpManager
{
public function PopManagerDepth() { super(); }
public static var popUpsByDepth :ArrayCollection = new ArrayCollection();
public static function addPopUpWithDepth(window:IFlexDisplayObject,
parent:DisplayObject,
modal:Boolean = false,
childList:String = null,
moduleFactory:IFlexModuleFactory = null):void
{
PopUpManager.addPopUp(window, parent, modal, childList, moduleFactory);
PopManagerDepth.popUpsByDepth.addItem( window );
}
public static function removeLastPopUp():void{
PopManagerDepth.removePopUpByIndex(PopManagerDepth.popUpsByDepth.length);
}
public static function removePopUpByIndex( idx :uint ):void{
if( PopManagerDepth.popUpsByDepth.length > idx){
PopUpManager.removePopUp( popUpsByDepth.getItemAt( idx ) as IFlexDisplayObject );
}
}
}
}
You'd use this class to add your popups, just like popupmanager but with this method:
PopManagerDepth.addPopUpWithDepth( .... );
The difference is there is a new method you'd use to remove them :
PopManagerDepth.removeLastPopUp();
or
PopManagerDepth.removePopUpByIndex();
Should do the trick, sorry I cant test it right now, but should work or close to it. I'll help ya debug if needed :)
By Windows depth do you mean the z-index ? If so you might want to try the getChildIndex and removeChildAt methods on the DisplayObject class. However, since PopUps exists in a different heirarchy than the rest of the general components, I am unsure if this will work but it is a start ?
Here's what I would do:
Create an Array to keep track of each TitleWindow instance you pop up. You can use the Array index as a z-index indicator.
In your closeHandler() method, iterate through each member of the Array and close that TitleWindow instance.

How to disable the icon on a Flex3 Button

I have a button which I use for sending a message. When the message text is empty, it should not be possible to click the button.
This is all fine and not an issue. The only thing that is bugging me is the fact that I can disable the send button but the image does not get disabled (like I would expect).
Is there a way to do this elegantly because I don't want to provide a sendicon_disabled.png and change it myself (I don't think this should be my job).
You can use the following button for that:
package
{
import mx.controls.Button;
import mx.core.mx_internal;
use namespace mx_internal;
public class IconButton extends Button
{
private var enabledChanged:Boolean = false;
override public function set enabled(value:Boolean):void
{
if (super.enabled == value)
{
return;
}
super.enabled = value;
enabledChanged = true;
invalidateDisplayList();
}
override protected function updateDisplayList(unscaledWidth:Number,
unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
if (enabledChanged)
{
if (!enabled && currentIcon)
{
currentIcon.alpha = 0.5;
}
enabledChanged = false;
}
}
}
}
You can use your custom alpha value or move it to separate style.

Problem in Flash TextField

I want to design a calculator by Flash cs5 , I use appendText Method to write the data in the textfield by the Keyboard . My problem is when I start the application I have to Click on the TextField first then type the numbers . How i can solve it .
Cheers,
Maged
What type of TextField are you using?!
Provided that you have created a dynamic TextField with the instance name of textfield, the following should work.
textfield.restrict = "0-9";
textfield.text = "";
function onKeyBoardEvent( event:KeyboardEvent ):void
{
var str:String = String.fromCharCode(event.charCode );
textfield.appendText( str);
}
you can set focus to the text field as soon as it's added to stage.
frame script:
stage.focus = textFieldInstance;
package:
package
{
import flash.display.Sprite;
import flash.events.Event;
public class DocumentClass extends Sprite
{
public function DocumentClass()
{
addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(evt:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
stage.focus = textFieldInstance;
}
}
}

Why is the Sprite's graphics object not drawing to the screen?

When I debug my code nothing appears on screen. I've rechecked the code and consulted with others yet nothing appears. My html template is fine.
package {
import flash.display.Sprite;
import flash.events.*;
public class asgnv2 extends Sprite
{
var lineY = 0;
public function asgnv2()
{
stage.addEventListener(Event.ENTER_FRAME, update);
graphics.lineStyle(1);
}
function update(e){
graphics.clear();
graphics.moveTo(0 ,lineY);
graphics.lineTo(100, lineY);
lineY+=0.5;
}
}
}
unless asgnv2 is Document class, it is not going to work, as you are registering ENTER_FRAME event on the stage inside the constructor of asgnv2. A DisplayObject can not access stage property until it is added to Stage Display List. So try the following. public function asgnv2(){
this.addEventListener(Event.ADDED_TO_STAGE, onAdded);
graphics.lineStyle(1);
}
private function onAdded(e:Event):void {
stage.addEventListener(Event.ENTER_FRAME, update);
this.removeEventListener(Event.ADDED_TO_STAGE, onAdded);
}
private function update(e:Event):void{
//do the stuff
}

Resources