I have an ItemRenderer with a data that has some flags. I need to change the ItemRenderer color depending on these flags. How can I achieve that? This is my IR:
<?xml version="1.0" encoding="utf-8"?>
<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="false"
x="{data.x}" y="{data.y}">
<s:states>
<s:State name="node"/>
<s:State name="nodeIn"/>
<s:State name="nodeOut"/>
<s:State name="nodeTrafficLight"/>
<s:State name="nodeIntersection"/>
<s:State name="nodeBlocked"/>
</s:states>
<s:Ellipse width="16" height="16" x="-8" y="-8">
<s:stroke>
<s:SolidColorStroke weight="2"
color="#FFFF00"
color.nodeTrafficLight="#FF00FF"
color.nodeIntersection="#FF9900"
color.nodeBlocked="#000000"
color.nodeIn="#00FF00"
color.nodeOut="#FF0000"/>
</s:stroke>
<s:fill>
<s:SolidColor alpha=".5"
color="#FFFF00"
color.nodeTrafficLight="#FF00FF"
color.nodeIntersection="#FF9900"
color.nodeBlocked="#000000"
color.nodeIn="#00FF00"
color.nodeOut="#FF0000"/>
</s:fill>
</s:Ellipse>
<fx:Script>
<![CDATA[
override protected function getCurrentRendererState():String
{
if (data.isBlocked)
return "nodeBlocked";
if (data.isIn)
return "nodeIn";
if (data.isOut)
return "nodeOut";
if (data.isIntersection)
return "nodeIntersection";
return "node";
}
]]>
</fx:Script>
</s:ItemRenderer>
But I don't get these states updated when some of these flags (eg. data.isIn) change. My model has [Bindable] tag.
First off; I don't think the x and y values have an affect inside a renderer. The list class will handle the positioning of the renderer.
That said, you're renderer does not respond to the dataChange event; so the renderer will not update itself when the data changes. Add a dataChange event handler:
<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="false"
dataChange="onDataChange(event)">
<fx:Script>
<![CDATA[
protected function onDataChange(event:Event):void{
invalidateRendererState();
}
]]>
</fx:Script>
The invalidateRendererState() method should force commitProperties() to re-run; which will in turn force getCurrentRendererState() to execute.
If for some reason the onDataChange() event is not firing when you change the data in your dataProvider; you'll have to use the itemUpdated() or refresh() function on your dataProvider to 'announce' that you changed data.
Related
I used my app's resize handler to resize my component but it is throwing this error :
TypeError: Error #1009: Cannot access a property or method of a null object reference
Here is my code :
<?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" minWidth="955" minHeight="600"
resize="application2_resizeHandler(event)" >
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
import mx.events.ResizeEvent;
private var employeeName:String = 'ravi';
protected function application2_resizeHandler(event:ResizeEvent):void
{
mainGroup.width = stage.width - 10;
mainGroup.x = 5;
}
]]>
</fx:Script>
<s:Group width="100%" height="100%">
<s:VGroup id="mainGroup" >
<s:Label id="employeeNameLabel" text="{employeeName}" />
<s:Label id="departmentLabel" />
</s:VGroup>
<s:Button id="getData" />
</s:Group>
</s:Application>
You got the #1009 error because your resize event is fired before the creation of your objects. So, you should wait for that and that your app is added to the stage to be able to use the stage object.
For that, I think that the best event is the applicationComplete event, then you can add a resize event to resize your component ...
So you can do like this for example :
<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" minWidth="955" minHeight="600"
applicationComplete="application2_applicationCompleteHandler(event)" >
then
protected function application2_applicationCompleteHandler(event:FlexEvent):void
{
// if you want you can resize your component for the 1st time
// by calling the application2_resizeHandler() function
application2_resizeHandler(new ResizeEvent(ResizeEvent.RESIZE));
// add the resize event listener to your app
event.target.addEventListener(ResizeEvent.RESIZE, application2_resizeHandler);
}
Hope that can help.
In flex application how to get the ID of specific display component using mouse event. For example if I want to get the ID of a button it should be displayed when I click the button
do it with event.currentTarget.id like this :
<?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" minWidth="955" minHeight="600">
<fx:Script>
<![CDATA[
import mx.controls.Alert;
protected function niceButton_clickHandler(event:MouseEvent):void
{
Alert.show(" the button id is: "+event.currentTarget.id)
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:HGroup width="100%" height="100%" verticalAlign="middle" horizontalAlign="center">
<s:Button id="niceButton" label="click me" click="niceButton_clickHandler(event)" />
</s:HGroup>
</s:Application>
(another of my never ending questions...)
I need an image component with states which behaves like a ToggleButton. Rather than build from scratch I thought I would try subclassing ToggleButton and defining a custom Flex skin. I don't have much experience with skinning and have cobbled together the code below.
It seems to work well – binding BitmapImages in the skin to BitmapData loading in the button instance: <s:BitmapImage source="{hostComponent.upImageData}"
Am I on the right track with this approach? Is there a more standard approach to this sort of thing?
ToggleButton Skin
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
minWidth="21" minHeight="21"
alpha.disabledStates="0.5">
<fx:Metadata>[HostComponent("components.EventButton")]</fx:Metadata>
<!-- host component -->
<!-- states -->
<s:states>
<s:State name="up" />
<s:State name="over" stateGroups="overStates" />
<s:State name="down" stateGroups="downStates" />
<s:State name="disabled" stateGroups="disabledStates" />
<s:State name="upAndSelected" stateGroups="selectedStates, selectedUpStates" />
<s:State name="overAndSelected" stateGroups="overStates, selectedStates" />
<s:State name="downAndSelected" stateGroups="downStates, selectedStates" />
<s:State name="disabledAndSelected" stateGroups="selectedUpStates, disabledStates, selectedStates" />
</s:states>
<s:BitmapImage source="{hostComponent.upImageData}"
includeIn="up, disabled"
left="0" right="0" top="0" bottom="0" />
<s:BitmapImage source="{hostComponent.overImageData}"
left="0" right="0" top="0" bottom="0"
includeIn="over"/>
<s:BitmapImage source="{hostComponent.downImageData}"
left="0" right="0" top="0" bottom="0"
includeIn="down, upAndSelected, overAndSelected, downAndSelected"/>
</s:Skin>
ToggleButton
<?xml version="1.0" encoding="utf-8"?>
<s:ToggleButton xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:skins = "skins.*"
skinClass="skins.EventSkin"
creationComplete="creationCompleteHandler(event)">
<fx:Script>
<![CDATA[
[Bindable]
public var upImageData:BitmapData;
[Bindable]
public var overImageData:BitmapData;
[Bindable]
public var downImageData:BitmapData;
[Bindable]
public var disabledImageData:BitmapData;
// image loading code removed
]]>
</fx:Script>
</s:ToggleButton>
Yep, you are going in right way. The "Skin mechanism" is really powerful and flexible tool. I had similar task about year ago and I solved it in the same way (just with standard ToggleButton and custom skin). All changes in visual representation of spark component might to be in skin class.
As another option, you should be able to use the state variable syntax:
<s:ToggleButton icon.up="{upIcon}"
icon.over="{overIcon}"
icon.down="{downIcon}"
icon.disabled="{disabledIcon}"
icon.upAndSelected="{upAndSelectedIcon}"
icon.overAndSelected="{overAndSelectedIcon}"
icon.downAndSelected="{downAndSelectedIcon}"
icon.disabledAndSelected="{disabledAndSelectedIcon}" />
See this Apache mailing list thread for more discussion on this.
It seems like there is a bug in flex's RichTextEditor that on change of view(view state change) the RTE loses its formatting. Has anyone encountered this issue before and know how to solve it. Any help is much appreciated.
<?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"
minWidth="955" minHeight="600" xmlns:base="ui.components.base.*" xmlns:ui="ui.*" xmlns:local="*">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
protected function click_clickHandler(event:MouseEvent):void
{
trace(this.rte.htmlText);
this.currentState = "other";
}
protected function clickother_clickHandler(event:MouseEvent):void
{
this.currentState = "normal"
}
]]>
</fx:Script>
<s:states>
<s:State name="normal"/>
<s:State name="other"/>
</s:states>
<s:VGroup includeIn="normal">
<mx:RichTextEditor id="rte">
</mx:RichTextEditor>
<s:Button id="click" x = "500" y = "500" click="click_clickHandler(event)">
</s:Button>
</s:VGroup>
<s:VGroup includeIn="other" >
<s:Label>
test
</s:Label>
<s:Button id="clickother" click="clickother_clickHandler(event)">
</s:Button>
</s:VGroup>
</s:Application>
i have faced that issue and solution is applying style external.
means when view is changed apply that css to rte.
Have a nice day....
using flex, is it possible to make a square, drawn using s:rect , clickable?
I am trying to draw a series of coloured boxes and allow them to be clicked on to perform an action.
I wasn't able to target it directly so I wrapped it in a BorderContainer and that did the trick. Or you could just use a BorderContainer if all you want is a box you can color and target.
<?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" minWidth="955" minHeight="600" creationComplete="init()">
<fx:Script>
<![CDATA[
import mx.controls.Alert;
public function init():void{
myBox.addEventListener(MouseEvent.MOUSE_OVER, changeColor);
}
public function changeColor(e:MouseEvent):void
{
myFill.color = 0xFFFF00;
}
]]>
</fx:Script>
<s:states>
</s:states>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
<s:SolidColor id="myFill" color="0xFF0000" />
<s:SolidColorStroke id="myStroke" color="0x000000" weight="2" />
</fx:Declarations>
<s:BorderContainer id="myBox" >
<s:Rect width="200" height="200" fill="{myFill}" stroke="{myStroke}" id="box1" />
</s:BorderContainer>
</s:Application>