Flex: invalidateData - apache-flex

I've trouble getting my components to update when the params has changed:
package mycompany
{
import flash.events.Event;
import mx.events.SliderEvent;
import mx.controls.HSlider;
import mx.controls.sliderClasses.Slider;
public class FromToSlider extends HSlider
{
/* from: */
private var _from:int;
[Bindable]
public function get from():int
{
return _from;
}
public function set from(value:int):void
{
this._from = value;
this.values[0] = value;
invalidateProperties();
}
/* //from */
/* to: */
private var _to:int;
[Bindable]
public function get to():int
{
return _to;
}
public function set to(value:int):void
{
this._to = value;
this.values[1] = value;
}
/* //to */
override public function initialize():void
{
super.initialize();
addEventListener(SliderEvent.CHANGE, handleChange, false, 0, true);
}
protected function handleChange(event:SliderEvent):void
{
var ct:Slider=Slider(event.currentTarget);
this.from = ct.values[0];
this.to = ct.values[1];
}
}
}
When I set "from" and "to" the thumbs aren't updating. I've tried invalidateProperties but that didn't work.

Add a call to invalidateDisplayList() after invalidateProperties(). That will ensure that Flex redraws the component on the next keyframe.
You should also add the same to the 'set to()' function.

Related

Upgrading from Flex 3.0 to Flex 3.6 - Custom Combobox getting TypeError in super.commitProperties()

I am working on upgrading Flex 3.0 application to Flex 3.6 SDK. The application has custom controls for input text, combo-boxes, etc. When I click on the combo-box I get exception when super.commitProperties() is called. This works fine with Flex 3.0 SDK.
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at mx.controls::ComboBox/destroyDropdown()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\controls\ComboBox.as:1681]
at mx.controls::ComboBox/styleChanged()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\controls\ComboBox.as:1177]
at mx.core::UIComponent/setBorderColorForErrorString()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\core\UIComponent.as:5048]
at mx.core::UIComponent/commitProperties()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\core\UIComponent.as:6033]
at mx.controls::ComboBase/commitProperties()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\controls\ComboBase.as:993]
at mx.controls::ComboBox/commitProperties()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\controls\ComboBox.as:1291]
at com.hanover.utility.controls.autotestcontrols::AutotestComboBox/commitProperties()[C:\App\Control\PLCustomComboBox.as:59]
at mx.core::UIComponent/validateProperties()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\core\UIComponent.as:5966]
at mx.managers::LayoutManager/validateProperties()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\managers\LayoutManager.as:539]
at mx.managers::LayoutManager/doPhasedInstantiation()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\managers\LayoutManager.as:689]
at mx.managers::LayoutManager/validateNow()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\managers\LayoutManager.as:748]
at mx.controls::ComboBox/displayDropdown()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\controls\ComboBox.as:1638]
at mx.controls::ComboBox/downArrowButton_buttonDownHandler()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\controls\ComboBox.as:1796]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.core::UIComponent/dispatchEvent()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\core\UIComponent.as:9590]
at mx.controls::Button/http://www.adobe.com/2006/flex/mx/internal::buttonPressed()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\controls\Button.as:2504]
at mx.controls::Button/mouseDownHandler()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\controls\Button.as:2750]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.core::UIComponent/dispatchEvent()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\core\UIComponent.as:9590]
at mx.controls::ComboBase/textInput_mouseEventHandler()[C:\autobuild\3.x\frameworks\projects\framework\src\mx\controls\ComboBase.as:1384]
PLCustomCombobox.as pseudo-source with line # 59 indicated below
package com
{
import com.name.utility.events.PLControlEvent;
import com.name.utility.managers.ComboToolTipManager;
import flash.events.Event;
import mx.controls.ComboBox;
import mx.events.FlexEvent;
[Event(name="controlInitComplete", type="com.events.PLControlEvent")]
[Event(name="plusControlValueChanged", type="com.name.utility.events.PLControlEvent")]
public class PLControlComboBox extends ComboBox
implements IPLControlControl
{
/**
* A flag that indicates whether the control need to refresh.
*/
protected var isNeedRefresh:Boolean = false;
/**
* A flag that indicates whether the value of control is changed.
*/
protected var isValueChanged:Boolean = false;
/**
* Constructor.
*/
public function PLControlComboBox()
{
super();
this.addEventListener(FlexEvent.CREATION_COMPLETE, onCreationComplete);
}
/**
* #private
* override commitProperties for avoid dispatch event many times.
*/
override protected function commitProperties():void
{
super.commitProperties(); // <---- line # 59 is here
if(isNeedRefresh)
{
this.dispatchEvent(new PLControlEvent(PLControlEvent.VALUE_CHANGED));
isNeedRefresh = false;
}
if(isValueChanged)
{
this.dispatchEvent(new Event("PLControlComboboxChanged"));
isValueChanged = false;
}
}
/**
* Add item's tooltip.
* #private
*/
override public function set measuredWidth(value:Number):void
{
super.measuredWidth = value;
if(collection && collection.length > 0)
{
ComboToolTipManager.showItemToolTip(this);
}
}
protected function onCreationComplete(event:FlexEvent):void
{
this.removeEventListener(FlexEvent.CREATION_COMPLETE, onCreationComplete);
this.dispatchEvent(new PLControlEvent(PLControlEvent.INIT_COMPLETE));
}
public function checkValidity():void
{
if(_required && dataProvider && dataProvider.length > 0 && _defaultItemIndex == selectedIndex)
{
_validity = false;
errorString = "please select one";
}
else
{
_validity = true;
errorString = "";
}
}
// ======================================
// public function
// ======================================
private function itemChanged():void
{
isNeedRefresh = true;
isValueChanged = true;
checkValidity();
}
// ======================================
// properties
// ======================================
private var _required:Boolean = false;
private var _validity:Boolean = false;
private var _defaultItemIndex:int = 0;
public function get required():Boolean
{
return _required;
}
[Inspectable(defaultValue=false, category="Other")]
public function set required(value:Boolean):void
{
_required = value;
isNeedRefresh = true;
checkValidity();
}
[Bindable("PLControlComboboxChanged")]
public function get controlValue():Object
{
return this.selectedIndex;
}
public function set controlValue(value:Object):void
{
if(value is Number)
{
this.selectedIndex = int(value);
itemChanged();
}
}
/**
* #copy IPLControlControl#validity
*/
public function get validity():Boolean
{
return _validity;
}
/**
* #copy IPLControlControl#type
*/
public function get type():String
{
return PLControlTypeList.CONTROL_TYPE_COMBOBOX;
}
/**
* If required is true, the default Item can not be selected.
*/
public function get defaultItemIndex():int
{
return _defaultItemIndex;
}
[Inspectable(defaultValue=0, type="Number", category="Other")]
public function set defaultItemIndex(index:int):void
{
_defaultItemIndex = index;
isNeedRefresh = true;
checkValidity();
}
/**
* Override for check validity.
*/
override public function set selectedIndex(value:int):void
{
super.selectedIndex = value;
itemChanged();
}
/**
* Override for check validity.
*/
override public function set selectedItem(value:Object):void
{
super.selectedItem = value;
itemChanged();
}
}
}
Its coming from mx.controls.Comboxbox line # 1681 because tween is null.
private function destroyDropdown():void
{
if (inTween)
tween.endTween();//<---- exception on this line
displayDropdown(false, null, false);
}
Any suggestions of why this could be happening?
Issue fixed in Apache Flex 4.10 and above, see https://issues.apache.org/jira/browse/FLEX-33382.
If using an older SDK you could monkey patch mx:ComboBox like so adding the "&& tween" check:
private function destroyDropdown():void
{
if (inTween && tween)
tween.endTween();
displayDropdown(false, null, false);
}

how to call an external function from inside a class?

i want to call an external function inside a class. thats the code;
in checkConnectionStatus function,
this[_funcNameForSucceededCon].apply(); doesnt work because "this" is the class, not the Application. How can i reach Application at this time or what can i do?
any help will be greatly appreciated.
best regards,
mira.
package myLibrary
{
import air.net.URLMonitor;
import flash.events.Event;
import flash.events.StatusEvent;
import flash.net.URLRequest;
public class connectionControl
{
private var _urlReq:URLRequest;
private var _urlMonitor:URLMonitor;
private var _funcNameForSucceededCon:String;
private var _funcNameForFailedCon:String;
public function connectionControl(targetURL:String, funcNameForSucceededCon:String, funcNameForFailedCon:String)
{
_urlReq = new URLRequest(targetURL);
_urlMonitor = new URLMoniotor(_urlReq);
_urlMonitor.addEventListener(StatusEvent.STATUS, checkConnectionStatus);
_funcNameForSucceededCon = funcNameForSucceededCon;
_funcNameForFailedCon = funcNameForFailedCon;
if(_urlMonitor.running == false)
{
_urlMonitor.start();
}
else
{
_urlMonitor.stop();
_urlMonitor.start();
}
}
private function checkConnectionStatus(e:Event):void
{
_urlMonitor.removeEventListener(StatusEvent.STATUS, checkConnectionStatus);
if(_urlMonitor.available)
{
this[_funcNameForSucceededCon].apply();
}
else
{
this[_funcNameForFailedCon].apply();
}
}
}
}
You have passed the name of the function to be serving as a callback. Use instead the function itself and pass it to connectionControl.
public class connectionControl
{
private var _funcSucceededCon:Function;
private var _funcFailedCon:Function;
public function connectionControl(targetURL:String, funcSucceededCon:Function, funcFailedCon:Function)
{
_urlReq = new URLRequest(targetURL);
_urlMonitor = new URLMoniotor(_urlReq);
_urlMonitor.addEventListener(StatusEvent.STATUS, checkConnectionStatus);
_funcSucceededCon= funcSucceededCon;
_funcFailedCon= funcFailedCon;
...
And:
if(_urlMonitor.available)
{
_funcSucceededCon();
}

Declaring buttons in Action script code

How to declare the buttons in the following AS code What is the library that needs to be included
package
{
public class caml extends Sprite
{
public function buttons()
{
saveButton.visible = false;
discardButton.visible = false;
}
private function captureImage(e:MouseEvent):void
{
capture.visible = false;
saveButton.visible = true;
discardButton.visible = true;
}
}
}
If you mean buttons as in the Flash IDE and not the component one, these are SimpleButton
package {
import flash.display.SimpleButton;
public class caml extends Sprite {
public var saveButton:SimpleButton;
//...
}
}

can not access MovieClip properties in flashDevelop

I know there is something I am doing wrong. In my controls I have keydown events that control my hero. As of right now, I am trying to rotate my hero but he refuses to turn . Below is my Hero Class, my control class, and gameobject class. pretty much all the classes associate with the controls class.
package com.Objects
{
import com.Objects.GameObject;
/**
* ...
* #author Anthony Gordon
*/
[Embed(source='../../../bin/Assets.swf', symbol='OuterRim')]
public class Hero extends GameObject
{
public function Hero()
{
}
}
}
Here is my Controls class. This is the class where I am trying to rotate my hero but he doesnt. The keydown event does work cause I trace it.
package com.Objects
{
import com.Objects.Hero;
import flash.events.*;
import flash.display.MovieClip;
/**
* ...
* #author Anthony Gordon
*/
public class Controls extends GameObject
{
private var aKeyPress:Array;
public var ship:Hero;
public function Controls(ship:Hero)
{
this.ship = ship;
IsDisplay = false;
aKeyPress = new Array();
engine.sr.addEventListener(KeyboardEvent.KEY_DOWN, keyDownListener);
engine.sr.addEventListener(KeyboardEvent.KEY_UP,keyUpListener);
}
private function keyDownListener(e:KeyboardEvent):void {
//trace("down e.keyCode=" + e.keyCode);
aKeyPress[e.keyCode] = true;
trace(e.keyCode);
}
private function keyUpListener(e:KeyboardEvent):void {
//trace("up e.keyCode=" + e.keyCode);
aKeyPress[e.keyCode]=false;
}
override public function UpdateObject():void
{
Update();
}
private function Update():void
{
if (aKeyPress[37])//Key press left
ship.rotation += 3,trace(ship.rotation ); ///DOESNT ROtate
}//End Controls
}
}
Here is GameObject Class
package com.Objects
{
import com.Objects.Engine;
import com.Objects.IGameObject;
import flash.display.MovieClip;
/**
* ...
* #author Anthony Gordon
*/
public class GameObject extends MovieClip implements IGameObject
{
private var isdisplay:Boolean = true;
private var garbage:Boolean;
public static var engine:Engine;
public var layer:Number = 0;
public function GameObject()
{
}
public function UpdateObject():void
{
}
public function GarbageCollection():void
{
}
public function set Garbage(garb:Boolean):void
{
garbage = garb;
}
public function get Garbage():Boolean
{
return garbage
}
public function get IsDisplay():Boolean
{
return isdisplay;
}
public function set IsDisplay(display:Boolean):void
{
isdisplay = display;
}
public function set Layer(l:Number):void
{
layer = l;
}
public function get Layer():Number
{
return layer
}
}
}
Looks like your keyUpListener and keyDownListener methods aren't calling the UpdateObject function.
Try listening for your KeyboardEvent on stage instead of engine.sr (not sure what that is)
If you put them on anything other than the stage you will need to click that specific thing first to give it focus for the events to work.
Also, the line:
ship.rotation += 3,trace(ship.rotation );
in your Control class looks a bit broken.

Arraycollection not capturing the thrown event?

I have a collection of objects and each object throws an event every time its value gets updated. Im trying to capture that event by adding a listener to the arraycollection that holds it (see main class) but its not working. Honestly I'm not sure this is the correct approach.
I'm avoiding using Collection.CHANGE because it fells into an infinite recursion ultimately ends in a stack overflow. Any ideas?
[Bindable]
public class NamesVO {
public var steveList:ArrayCollection; // array of SteveVO objects
public function NamesVO() {
steveList = new ArrayCollection();
}
public function rename():void {
for each(var steve:SteveVO in steveList) {
steve.rename();
}
}
}
[Bindable]
public class SteveVO extends EventDispatcher {
public static const VALUE_CHANGED:String = "VALUE_CHANGED";
public var code:String;
public var name:String;
public var _quantity:Number;
public function SteveVO() {
this.code = "";
this.name = "";
_quantity = 0;
}
public function get quantity():Number {
return _quantity;
}
public function set quantity(quantity:Number):void {
_quantity = quantity;
dispatchEvent(new Event(VALUE_CHANGED));
}
public function rename():void {
name = code + " - " + _quantity;
}
}
Main class:
names = new NamesVO();
names.steveList.addEventListener(SteveVO.VALUE_CHANGED, function():void {
names.rename(); // this anon function is not being executed!!
});
var steve:SteveVO = new SteveVO();
names.steveList.addItem(steve);
// names is bound on a datagrid and uses itemeditor for each SteveVO object
The VALUE_CHANGED event is not dispatched by the steveList array Collection so won't be detected by your listener. You could encapsulate the functionality you want inside the NamesVO class by detecting when an item is added to the array collection and adding a listener to the new steveVO object that dispatches the same event from NamesVO. Then just listen for that event in your main class.
Is there a reason to change all the names when one quantity is changed. Would it be better simply to call rename inside the set function of the steveVO class?
To implement the change:
import flash.events.Event;
import mx.collections.ArrayCollection;
import mx.events.CollectionEvent;
import mx.events.CollectionEventKind;
[Bindable]
public class namesVO
{
public var steveList:ArrayCollection; // array of SteveVO objects
public function namesVO()
{
steveList = new ArrayCollection();
steveList.addEventListener(CollectionEvent.COLLECTION_CHANGE,collChanged);
}
private function collChanged(e:CollectionEvent):void
{
if (e.kind == CollectionEventKind.ADD)
e.items[0].addEventListener(steveVO.VALUE_CHANGED,valueChanged);
}
private function valueChanged(e:Event):void
{
dispatchEvent(new Event(steveVO.VALUE_CHANGED));
}
public function rename():void
{
for each(var steve:steveVO in steveList)
{
steve.rename();
}
}
}
In the main class use:
names = new namesVO();
names.addEventListener(steveVO.VALUE_CHANGED, function():void
{
names.rename();
});
steve = new steveVO();
names.steveList.addItem(steve);
steve.quantity = 12;
Of course this is only an example and only includes the case where one item is added at a time.

Resources