Solved

Flex: Changing property of inactive state

Posted on 2009-04-14
6
2,434 Views
Last Modified: 2013-11-11
I have a decision tree wizard where the first states in the workflow determine what is shown in the last states.  

I ran into a bug where if I change the enabled state of an element in a state which has not yet been viewed - I get the following error:

TypeError: Error #1009: Cannot access a property or method of a null object reference.
      at stateChangeExample/check2Handler()[/.../src/stateChangeExample.mxml:25]
      at stateChangeExample/___stateChangeExample_CheckBox2_click()[/.../src/stateChangeExample.mxml:49]

I have included code for an example.  You'll notice that if you select the checkbox on the right before you hit the change state button, you'll get the error.  If you then change the state and then change it back you will no longer get the error.

I have a couple workarounds... namely run through all the states onLoad or buffer all the changes until the state is set to currentState... but I prefer to figure this out.  Maybe there is a way I need to activate the state without showing it?

HELP!!!
<?xml version="1.0" encoding="utf-8"?>

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">

	<mx:states>

		<mx:State name="state2">

			<mx:AddChild position="lastChild">

				<mx:TextInput id="input2" x="203" y="41"/>

			</mx:AddChild>

		</mx:State>

	</mx:states>

	<mx:Script>

		<![CDATA[

			public function check1Handler():void

			{

				if(input1.enabled == true)

				{

					input1.enabled = false;

				} 

				else

				{

					input1.enabled = true;	

				} 	

			}

			public function check2Handler():void

			{

				if(input2.enabled == true)

				{

					input2.enabled = false;

				} 

				else

				{

					input2.enabled = true;	

				} 					

			}

			public function changeState():void

			{

				if(currentState == "state2")

				{

					currentState = "";

				} 

				else

				{

					currentState = "state2";	

				} 	

			}

		]]>

	</mx:Script>

	<mx:CheckBox click="check1Handler()" x="10" y="11" label="disable/enable in base state"/>

	<mx:TextInput id="input1" x="10" y="41"/>

	<mx:CheckBox click="check2Handler()" x="203" y="11" label="disable/enable in state2"/>

	

	<mx:Button click="changeState()" x="10" y="71" label="Change State"/>

	

	

	

</mx:Application>

Open in new window

0
Comment
Question by:bittermonk
  • 3
  • 3
6 Comments
 
LVL 2

Accepted Solution

by:
hockeyragazzo earned 500 total points
ID: 24140868
This has likely got something to do with the fact that input2 hasn't yet been instantiated in the display. I often run into problems like these when I have a custom component with a bunch of textinputs and I want to insert data into those inputs directly (input2.text = "Blah blah") before they've been added to the display. The solution I use in this case is to bind variables to the text inputs and simply set the variables. Absent other solutions that help you better understand the nature of the accessibility of display objects when they're not in the stage, how about this:

Set the enabled property equal to some Boolean variable called Input2EnabledBool which starts at whatever state you like (true or false). This way you can set the value of Input2EnabledBool = false when you want to disable the TextInput and = true when you want to enable it. As far as I know, this will solve your problem.

Be sure to put a [Bindable] tag before your variable:

[Bindable] private var Input2EnabledBool = true;

and then:



<mx:State name="state2">

                        <mx:AddChild position="lastChild">

                                <mx:TextInput id="input2" x="203" y="41" enabled={Input2EnabledBool}/>

                        </mx:AddChild>

                </mx:State>

Open in new window

0
 
LVL 2

Expert Comment

by:hockeyragazzo
ID: 24140967
An alternative, yet more bloated (especially if you have many TextInputs on which you want to perform these operations), option is to put your input2 with visible=false in the main portion of the Application instead of creating it in the new state. Then, instead of adding a TextInput in your new state, simply set the visible property = true. This will ensure that it exists at every point after creationComplete and all you will be changing when you go into a new state is the visibility of input2.

I personally like the variable binding option better because states are an extremely efficient way to add components in a way that doesn't add much to the size of the Application/component you're building.
0
 

Author Comment

by:bittermonk
ID: 24140968
hockeyragazzo: Your answer is better than what I went with...

So to be clear... if I change the currentState and then change it back...

the element in state2 is not on the stage until state2 is set to currentState
and
when I return to the base state the element in state2 remains on the stage although it is no longer visible.

Is there a way to add all the states to the stage onLoad without making them visible?
0
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 

Author Comment

by:bittermonk
ID: 24140985
I definitely like the binding option better than removing the states...
0
 
LVL 2

Expert Comment

by:hockeyragazzo
ID: 24141017
According to my understanding, that is correct. You can test this out by entering some text into your TextInput and switching states back and forth. If the text remains in the box after going to the base state and back to state2, then I think that is a correct interpretation.

As far as I know, adding all the states to the stage, i.e. adding all the components in a state to the stage, would defeat the purpose of having states. The only way to accomplish this would be to set a creationComplete function to just run through all the states you want to load and then back to your base state. I suspect that in a larger application, and possibly even in smaller ones like yours, this would start looking pretty clunky to the user. The same effect can be achieved by adding your component in the main part of the Application (as if it were in the base state), but setting the visibility = false, then using states to manipulate the visible property. This does come at a cost as every component in the main portion of the Application adds to the size of the .swf you produce on export, while adding components with states is a low-cost alternative to this.

But considering this is the only scenario I can really think of where states kind of screw with what the programmer expects to occur, binding variables to your state-added components is probably the best solution.

Lemme know what you end up going with and how it works out for you....or if you need any more clarification :-)
0
 

Author Closing Comment

by:bittermonk
ID: 31570000
Thanks for the clarification... I'll go with this :)
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

This is a very simple example to help those of you who are still migrating from AS2 to AS3 understand the redesigned event model in AS3. In AS2.0, event functions (that is, the function to be performed when an event is fired) were stored as a pro…
Sometimes you know that one object has a specific child in it, but you can't find the child. This happened to me when I was trying to code some actionScript to make a toolbar work with its embedded buttons.  My partner had created the toolbar usi…
In this tutorial viewers will learn how to create a basic shape tween animation in Flash including shape hints for smooth animation Open a new document in Flash: Draw a shape: Select another frame (how long you want the tween to be): Right click and…
The goal of the tutorial is to teach the user how to how to record live broadcast.

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now