SkinnablePopUpContainer not destroyed - actionscript-3

I am monitoring my internet connection. When there is no service available I get an Event from my URLMonitor. I am listening to this event and calling a function that opens a SkinnablePopUpContainer. It is a very simple Component I have no listeners attached to it and it is defined only inside the function. When the user clicks the button inside the SkinnablePopUpContainer I close the component and try to destroy it using all possible ways I know of. When I check the Profiler Tool from Flash Builder the SkinnablePopUpContainer is still there. How do I destroy this component freeing the memory it is using.
Here is the listener function:
protected function onNoServiceAvailable(e:*):void
{
var noserviceWindow:NoInternetError = new NoInternetError();
noserviceWindow.open(this,false);
noserviceWindow.x= 0;
noserviceWindow.y= 0;
noserviceWindow.width = SharedObject.getLocal('localObj').data.appMeasures.appWidth;
noserviceWindow.height = SharedObject.getLocal('localObj').data.appMeasures.appHeight+200;
}
and here is my SkinnablePopUpContainer
<?xml version="1.0" encoding="utf-8"?>
<s:SkinnablePopUpContainer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:nxTextInput="nx.components.extended.nxTextInput.*"
xmlns:nxButton="nx.components.extended.nxButton.*"
backgroundAlpha="0.4"
horizontalCenter="0" verticalCenter="0" width="100%" height="100%">
<fx:Script>
<![CDATA[
protected function loginButton_clickHandler(event:Event):void
{
loginButton.removeEventListener(MouseEvent.CLICK,loginButton_clickHandler);
this.close();
var ob = this;
ob = null;
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:Panel title="Fehler"
horizontalCenter="0" verticalCenter="0" color="white">
<s:VGroup horizontalAlign="center" verticalAlign="middle" gap="20"
height="100%" width="100%">
<s:BitmapImage source="#Embed('assets/nxInspect/mobile/assetsCI/redAssets/alert_80x80.png')" id="iconBitmpapDownOnline" verticalCenter="0" />
<s:Label id="serviceFailure" text="Keine internetverbindung." width="90%" styleName="interactable" textAlign="center" color="white"/>
<nxButton:NxButton id="loginButton" label="OK" width="100%" height="100" click="loginButton_clickHandler(event)" styleName="alert"/>
</s:VGroup>
</s:Panel>

First off, the line var ob = this; just creates a reference variable to "this". Setting this variable to null will not make it delete itself. It will just re-reference the variable you just created to null again, so those 2 lines are useless.
Because you've contained your local variable noserviceWindow within the scope of the function onNoServiceAvailable, it should automatically be marked for Garbage Collection when there are no more references to it. If your profiler is recognizing it's existence, then there is probably another reference to it somewhere in your code.

Related

Actionscript 3 setStyle is not a function

I am trying to style a Flex 4 GridItem using actionscript, I have tried the following:
<mx:VBox
height="878" width="1920"
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:s="library://ns.adobe.com/flex/spark" xmlns:local="*" creationComplete="addStyles()">
<mx:Script>
<![CDATA[
public var selectedLot:String = "";
private function addStyles():void
{
testBorder.setStyle("borderThickness", "3");
}
but I get the following error:
setStyle is not a function.
Am I missing something?
The GridItem is inside a repeater.
Here is my GridItem:
<mx:GridItem id="testBorder" width="101" height="52.25" horizontalAlign="center" verticalAlign="middle" borderStyle="solid" borderColor="gray">
<mx:Image source="assets/ruler-icon.png" />
<s:Label text="{r.currentItem.sqft}" fontSize="10" color="#808080" fontFamily="Helvetica" />
</mx:GridItem>
When using a repeater the GridItem's id will not be the same. To access any item inside a repeater you have to specify an index which is correspondent to the repeated item.
Example: Array consists of ["Audi", "BMW"], we set this array to your repeater's dataProvider, then to access "Audi"'s grid item and set its style, we have to use:
testBorder[0].setStyle("borderThickness", "3");
Additionally, an important point to consider, the VBox "creationComplete" can be executed before the repeater is fully built, therefore, the best place to call your function "addStyles" is in the repeater's "repeatEnd" event i.e (repeatEnd="setTransactionPropertyType()").
Hope this helps,
Goodluck.

Exception of null object reference when click on Text area in popup in Flash Builder 4.6

Here is my code.
<?xml version="1.0" encoding="utf-8"?>
<fx:Script>
<![CDATA[
import comps.sampleTextArea;
import mx.managers.PopUpManager;
protected function button1_clickHandler(event:MouseEvent):void
{
var pop:sampleTextArea = new sampleTextArea();
PopUpManager.createPopUp(this, sampleTextArea, false);
PopUpManager.centerPopUp(pop);
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:Button click="button1_clickHandler(event)" label="open popup"/>
and here is code of popup
<?xml version="1.0" encoding="utf-8"?>
<fx:Script>
<![CDATA[
import mx.managers.PopUpManager;
protected function button1_clickHandler(event:MouseEvent):void
{
ta.text = '';
PopUpManager.removePopUp(this);
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:layout>
<s:VerticalLayout horizontalAlign="center" verticalAlign="top" />
</s:layout>
<s:TextArea id="ta" width="100%" height="90%">
</s:TextArea>
<s:Button label="Submit" click="button1_clickHandler(event)" />
when i click on text area following error through by the application.
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at spark.components::Scroller/focusInHandler()[E:\dev\4.y\frameworks\projects\spark\src\spark\components\Scroller.as:2139]
at flash.display::Stage/set focus()
at flashx.textLayout.container::ContainerController/http://ns.adobe.com/textLayout/internal/2008::setFocus()[C:\Vellum\branches\v2\2.0\dev\output\openSource\textLayout\src\flashx\textLayout\container\ContainerController.as:2265]
at flashx.textLayout.container::ContainerController/mouseDownHandler()[C:\Vellum\branches\v2\2.0\dev\output\openSource\textLayout\src\flashx\textLayout\container\ContainerController.as:2067]
at flashx.textLayout.container::TextContainerManager/mouseDownHandler()[C:\Vellum\branches\v2\2.0\dev\output\openSource\textLayout\src\flashx\textLayout\container\TextContainerManager.as:1939]
at spark.components.supportClasses::RichEditableTextContainerManager/mouseDownHandler()[E:\dev\4.y\frameworks\projects\spark\src\spark\components\supportClasses\RichEditableTextContainerManager.as:666]
at flashx.textLayout.container::ContainerController/http://ns.adobe.com/textLayout/internal/2008::requiredMouseDownHandler()[C:\Vellum\branches\v2\2.0\dev\output\openSource\textLayout\src\flashx\textLayout\container\ContainerController.as:2088]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.core::UIComponent/dispatchEvent()[E:\dev\4.y\frameworks\projects\framework\src\mx\core\UIComponent.as:13152]
at mx.managers::SystemManager/mouseEventHandler()[E:\dev\4.y\frameworks\projects\framework\src\mx\managers\SystemManager.as:2918]
How i handle this issue
try, because this refer to stage no the clicked element:
PopUpManager.removePopUp(event.target);
You may not be able to popup a focusable component inside a
non-IFocusManagerContainer. If your Group container implements IFocusManagerContainer class, you may use PopUpManager.
<s:Group implements="mx.managers.IFocusManagerContainer"/>
I ran into the same issue, and the root cause was that PopUpManager/PopUpAnchor would not properly set the focusManager if the component being popped up does not implement the IFocusManagerContainer interface. After implementing such interface, the problem goes away.
You may read this blog post that inspired the solution.
After doing many experiments/ways i conclude that problem is due to the popup component parent container.
I use Group/VGroup/HGroup of spark then this issue remains but if i change the parent container with spark Panel/SkinnableContainer then issue solved.
Try yourself and enjoy.

A link inside TextFlow: rollOver/rollOut bubbles, shouldn't bubble, and cannot be avoided

I'm having a weird behavior. I have an HTML link inside a TextFlow. When I set its linkHoverFormat, it starts sending rollOver/rollOut events up the chain. These events say the don't bubble but somehow they do. And I can't seem to stop them from doing so.
Here's an example:
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Declarations>
<s:TextLayoutFormat id="linkNormal" textDecoration="none" color="0x556677"/>
<s:TextLayoutFormat id="linkHover" textDecoration="underline" color="0x0000FF"/>
<s:TextFlow id="textFlow1"
linkActiveFormat="{linkHover}"
linkHoverFormat="{linkHover}"
linkNormalFormat="{linkNormal}">
<s:p> <s:a href="http://projects.nunogodinho.com">hover</s:a> </s:p>
</s:TextFlow>
</fx:Declarations>
<fx:Script>
<![CDATA[
// This pair of handlers is triggered by the panel
protected function rollOverHandler(e:MouseEvent):void {
panel.title = "over";
}
protected function rollOutHandler(e:MouseEvent):void {
panel.title = "out";
}
]]>
</fx:Script>
<s:Panel left="10" top="10" id="panel" mouseOver="rollOverHandler(event)" mouseOut="rollOutHandler(event)">
<s:RichEditableText id="ret1"
top="10"
editable="false"
textFlow="{textFlow1}" />
</s:Panel>
</s:WindowedApplication>
If you run this app and move the mouse over the link several times without moving out of the panel you'll see that it still changes the text.
So I decided to try to stop this strange event from bubbling:
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Declarations>
<s:TextLayoutFormat id="linkNormal" textDecoration="none" color="0x556677"/>
<s:TextLayoutFormat id="linkHover" textDecoration="underline" color="0x0000FF"/>
<s:TextFlow id="textFlow2"
linkActiveFormat="{linkHover}"
linkHoverFormat="{linkHover}"
linkNormalFormat="{linkNormal}">
<s:p> <s:a rollOver="linkelement2_rollOverHandler(event)" rollOut="linkelement2_rollOutHandler(event)" href="http://projects.nunogodinho.com">hover</s:a> </s:p>
</s:TextFlow>
</fx:Declarations>
<fx:Script>
<![CDATA[
import flashx.textLayout.events.FlowElementMouseEvent;
// This pair of handlers is triggered by the panel
protected function rollOverHandler(e:MouseEvent):void {
panel.title = "over";
}
protected function rollOutHandler(e:MouseEvent):void {
panel.title = "out";
}
// This pair of handlers is triggered by the <A> element inside textFlow2
// and I hoped it would stop the event from bubbling up to the panel
protected function linkelement2_rollOverHandler(e:FlowElementMouseEvent):void {
e.preventDefault();
e.stopImmediatePropagation();
e.stopPropagation()
}
protected function linkelement2_rollOutHandler(e:FlowElementMouseEvent):void {
e.preventDefault();
e.stopImmediatePropagation();
e.stopPropagation()
}
// I also tried to intercept the event in the RichEditableText but got the same weird
// behavior: the event triggers the panel's rollOver/rollOut intermittently
]]>
</fx:Script>
<s:Panel left="10" top="10" id="panel" mouseOver="rollOverHandler(event)" mouseOut="rollOutHandler(event)">
<s:RichEditableText top="10" left="55"
editable="false"
textFlow="{textFlow2}" />
</s:Panel>
</s:WindowedApplication>
I tried all combinations of preventDefault, stopImmediatePropagation and stopPropagation. It does change the event's behavior but it also ruins the hovering effect on the link.
Then I tried to intercept the event at the RichEditableText but I got the same kind of results.
Once I had a similar problem but I learned that it was because I was using mouseOver/mouseOut events instead of rollOver/rollOut. Since I switched to rollOver/rollOut it worked fine. Until now.
And now I'm clueless.
Please help.
Thanks.

pass data from popup to parent

I have a parent w/ a popup child. When parent loads, I have to call a function within the popup without showing the popup (thus, I load "pupLove" but don't include it in layout)....I then pass this data to the parent. When the user manually clicks another button to open the popup, the same function is called & data passed to the parent. However, I am not able to pass dg.length to the parent. I believe the root problem is that I am loading "pupLove" & thus the parents are getting confused.....I'm guessing if I get rid of "pupLove" I can pass the data correctly but will need to call the child's function at creationComplete of the parent....how do I do that?
Here's my parent:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
backgroundColor="green" width="50%" height="100%"
xmlns:local="*"
>
<fx:Script>
<![CDATA[
import pup;
import mx.managers.PopUpManager;
public function showPup(evt:MouseEvent):void {
var ttlWndw:pup = PopUpManager.createPopUp(this, pup, true) as pup;
PopUpManager.centerPopUp(ttlWndw);
}
]]>
</fx:Script>
<mx:VBox>
<local:pup id="pupLove" visible="false" includeInLayout="false" />
<s:Button click="showPup(event);" label="launch Pup" />
<mx:Text id="Ptest" color="black" text="from Parent:{pupLove.dg.length}" />
</mx:VBox>
</s:Application>
And a popup child called 'pup.mxml':
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300">
<fx:Script>
<![CDATA[
public function init():void{
// send php call
}
import mx.events.CloseEvent;
import mx.managers.PopUpManager;
private function removePup(evt:Event):void {
PopUpManager.removePopUp(this);
}
]]>
</fx:Script>
<fx:Declarations>
<s:ArrayCollection id="dg">
</s:ArrayCollection>
</fx:Declarations>
<s:TitleWindow width="100%" height="100%" close="removePup(event)">
<mx:VBox>
<mx:Text id="test" color="red" text="from Child:{dg.length}" />
<s:Button label="add Items" click="dg.addItem({id:'cat'})" />
</mx:VBox>
</s:TitleWindow>
</s:Group>
UPDATE: I guess my question can be more easily stated as: "is there a way to call a child's function from the parent without actually loading the child?"
Well, if in your child's function, you don't need to access any of its UI component, then you could instanciate the child in the parent view and call the method.
When you need to display the popup afterwhile, use the PopupManager addPopup method with this existing instance instead of using createPopup

Updating view spark.components.List

I am using a List component inside an itemRenderer. The main user interaction involves dragging an item from the List in one renderer and dropping it in another.
My problem: When the data object is updated I want the Lists' height to be modified according to the number of objects in the dataprovider(dp), which is passed to the List from the data object. Now I have tried to invalidate the display of the List, refresh its dp and have tried putting this line assets.length > 0 ? assetList.percentHeight = 100 : assetList.height = 10; in other event handlers, such as dragdrop handlers, collection event handlers for the dp etc. I have also tried refreshing the dp for the List component that is using this renderer. The view does eventually get updated but only if I resize the list, or use the scroller or when I begin dragging a new List item but never after the drop.
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
autoDrawBackground="true" width="100%" creationComplete="init()" currentState="collapsed">
<fx:Script>
<![CDATA[
[Bindable] private var itemRenderer:ClassFactory;
[Bindable] private var colWidth:Number = 100;
[Bindable] private var assets:ArrayCollection = new ArrayCollection;;
public function init():void{
itemRenderer = new ClassFactory(DefaultRenderer);
this.addEventListener(FlexEvent.DATA_CHANGE, onDataChange);
}
private function onDataChange(e:FlexEvent):void {
assets = data.assets;
trace(data.name, assets.length);
assets.length > 0 ? assetList.percentHeight = 100 : assetList.height = 10;
}
]]>
</fx:Script>
<s:Group width="100%">
<s:layout>
<s:VerticalLayout gap="0" />
</s:layout>
<s:ToggleButton
id="viewToggle"
label="{data.name}"
width="100%"
height="50"
/>
<s:List id="assetList"
width="100%"
dataProvider="{assets}"
height = "10"
top="0" left="0" bottom="0" right="0"
dragEnabled="true"
allowMultipleSelection="true"
dragMoveEnabled="true"
dropEnabled="true"
itemRenderer="{itemRenderer}"
>
<s:layout>
<s:TileLayout requestedColumnCount="2"
horizontalGap="0" verticalGap="0"
columnWidth="{colWidth}" rowHeight="{colWidth}"/>
</s:layout>
</s:List>
</s:Group>
</s:ItemRenderer>
In your onDataChange method try this:
itemRenderer = null;
itemRenderer = new ClassFactory(DefaultRenderer);