flex dynamically changing values between functions - apache-flex

I have a main mxml and 2 AS classes.In the main mxml I have a slider.I want to get the slider values in AS classes as I move the slider.
Main.MXML
import First;
import Second;
private var my:First;
privaate var scd:Second;
public var sd:Date;
public function init():void {
my = new First();
Canvas.addChild(my.getUIComponent());
}
public function dateChange():Date {
startDate.selectedDate = new Date(slider.values[0]);
endDate.selectedDate = new Date(slider.values[1]);
sd = new Date(slider.values[0]);
scd.calsldr(sd);
return sd;
}
<mx:HBox width="100%" height="100%" horizontalAlign="center" verticalAlign="top">
<mx:Canvas id="Canvas" backgroundColor="#ffffff" height="600" width="100%"
horizontalScrollPolicy="off" verticalScrollPolicy="off">
</mx:Canvas>
</mx:HBox>
<flexlib:HSlider id="slider" width="100%" height="50" thumbCount="2" lockRegionsWhileDragging="true" allowTrackClick="true" maintainProjectionCenter="true"
change="dateChange();" liveDragging="true"
thumbSkin="mx.skins.spark.SliderThumbSkin"
trackSkin="mx.skins.spark.SliderTrackSkin"
trackHighlightSkin="mx.skins.spark.SliderTrackHighlightSkin" />
<mx:HBox x="300" y="300" height="50">
<mx:Label text="Start Date :"/> <mx:DateField id="startDate"/>
<mx:Label text="End Date"/> <mx:DateField id="endDate"/>
</mx:HBox>
My first AS which is first.AS
calls Second.AS
addChild(new Second(str) as Sprite);
str is a String value
i want to use the slider values in Second.AS
I tried using this:
public function calsldr(dat:Date):void {
trace(dat);
}
private function visualization():void{ }
I could get the values from trace(dat)....I mean the date's as the slider changes.
How could I use this changing values in function visualization()
PLease help.

#J_A_X
The Second AS is:
public function Second(str:String){
name = "Second"; }
public function calsldr(dat:Date){
trace(dat+"fu in maaka"); // As I change the slider the value is changed here }
protected override function init():void
{
var ldr:URLLoader = new URLLoader(new URLRequest(url));
_bar.loadURL(ldr, function():void {
var obj:Array = JSON.decode(ldr.data as String) as Array;
//Sorted the values based on 'str'
var data:Data = buildData(newarr);
visualize(data);
_bar = null; });
}
public function visualize(data:Data):void{
// I want to get the dat values here when ever the slider moves
}

Related

How is an mx:Canvas measured when inside a renderer in Flex 3?

I'm having a sizing issue with a canvases located inside an HBox. It seems "_graphic", "_border" and "_fill" canvases (in com.example.ThingRenderer.mxml) do not get measured at the same time as all the other measurements inside the renderer. However, this problem is only observed on the first pass-through. Refer to the images for a visual... 1st image shows the state of the app after it finished loading. 2nd image represents what the screen looks like after the Populate button is clicked. 3rd image shows what happens when the stepper is incremented. The question is how come the drawing in the 3rd image doesn't get rendered once the data is populated into the table?
RendererTest.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
creationComplete="handleCreationComplete(event)"
>
<mx:Script>
<![CDATA[
import com.example.Thing;
import mx.collections.ArrayCollection;
import mx.events.FlexEvent;
import mx.events.NumericStepperEvent;
private const _thingProvider:ArrayCollection = new ArrayCollection();
private var _thing1:Thing;
protected function handleCreationComplete(event:FlexEvent):void {
_thing1 = new Thing("thingy", 0xff0000, 0.3);
_stepper.value = _thing1.ratio;
}
protected function handlePopulateClick(event:MouseEvent):void {
_thingProvider.addItem(_thing1);
}
protected function handleStepperChange(event:NumericStepperEvent):void {
_thing1.ratio = event.value;
}
]]>
</mx:Script>
<mx:VBox>
<mx:Button label="Populate" click="handlePopulateClick(event)" />
<mx:NumericStepper id="_stepper" minimum="0" maximum="1" stepSize="0.01" change="handleStepperChange(event)" />
<mx:AdvancedDataGrid dataProvider="{_thingProvider}" variableRowHeight="true" width="100%" height="100%">
<mx:columns>
<mx:AdvancedDataGridColumn headerText="Name" dataField="name" />
<mx:AdvancedDataGridColumn headerText="Display"
width="150" sortable="false"
itemRenderer="com.example.ThingRenderer"
/>
</mx:columns>
</mx:AdvancedDataGrid>
</mx:VBox>
</mx:Application>
com.exampleThingRenderer.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas
xmlns:mx="http://www.adobe.com/2006/mxml"
width="100%"
horizontalScrollPolicy="off" verticalScrollPolicy="off"
>
<mx:Script>
<![CDATA[
import mx.binding.utils.ChangeWatcher;
private var _thing:Thing;
private var _ratioWatcher:ChangeWatcher;
private var _doClearContent:Boolean;
private var _doDrawBorder:Boolean;
private var _doUpdateFill:Boolean;
override public function set data(value:Object):void {
if(value && value is Thing) {
_thing = Thing(value);
if(_ratioWatcher) {
_ratioWatcher.unwatch();
}
_ratioWatcher = ChangeWatcher.watch(_thing, "ratio", handleRatioChanged);
_doClearContent = false;
_doDrawBorder = true;
_doUpdateFill = true;
_graphic.invalidateSize();
_border.invalidateSize();
}
else {
_doClearContent = true;
_doDrawBorder = false;
_doUpdateFill = false;
}
super.data = value;
}
private function handleRatioChanged(event:Event):void {
_doUpdateFill = true;
invalidateDisplayList();
}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
if(_doClearContent) {
_container.visible = false;
_container.includeInLayout = false;
_doClearContent = false;
}
super.updateDisplayList(unscaledWidth, unscaledHeight);
if(_doDrawBorder) {
trace("_thingContainer.width="+_container.width, "_thingGraphic.width="+_graphic.width, "_thingBorder.width="+_border.width);
_border.graphics.clear();
_border.graphics.moveTo(0, 0);
_border.graphics.lineStyle(1, _thing.color);
_border.graphics.lineTo(_border.width, 0);
_border.graphics.lineTo(_border.width, _border.height);
_border.graphics.lineTo(0, _border.height);
_border.graphics.lineTo(0, 0);
_doDrawBorder = false;
}
if(_doUpdateFill) {
_percentage.text = Math.round(_thing.ratio * 100.0) + "%";
_fill.graphics.clear();
_fill.graphics.beginFill(_thing.color);
_fill.graphics.drawRect(0, 0, _fill.width * _thing.ratio, _fill.height);
_doUpdateFill = false;
}
}
]]>
</mx:Script>
<mx:HBox id="_container" width="100%" paddingLeft="5" paddingTop="5" paddingRight="5" paddingBottom="5">
<mx:Label id="_percentage" width="45" />
<mx:Canvas id="_graphic" width="100%" height="15">
<mx:Canvas id="_border" x="0" y="0" width="100%" height="100%" />
<mx:Canvas id="_fill" x="0" y="0" width="100%" height="100%" />
</mx:Canvas>
</mx:HBox>
</mx:Canvas>
com.example.Thing.as
package com.example {
public class Thing {
[Bindable] public var name:String;
[Bindable] public var color:uint;
[Bindable] public var ratio:Number;
public function Thing(name:String, color:uint, ratio:Number) {
this.name = name;
this.color = color;
this.ratio = ratio;
}
}
}
All this happens because you can't use width and height properties in updateDisplayList, they are not updated yet. Make separate component (e.g. ThingProgressBar) and put drawing logick inside it, that will solve everything:
package
{
import mx.core.UIComponent;
public class ThingProgressBar extends UIComponent
{
private var _ratio:Number;
public function get ratio():Number
{
return _ratio;
}
public function set ratio(value:Number):void
{
_ratio = value;
invalidateDisplayList();
}
override protected function updateDisplayList(
unscaledWidth:Number, unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
graphics.clear();
if (unscaledWidth > 0 && unscaledHeight > 0)
{
graphics.lineStyle(1, 0xFF0000);
graphics.drawRect(0, 0, unscaledWidth, unscaledHeight);
graphics.beginFill(0xFF0000);
graphics.drawRect(0, 0, unscaledWidth * ratio, unscaledHeight);
graphics.endFill();
}
}
}
}
So your renderer might look like this:
<mx:HBox
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
horizontalScrollPolicy="off" verticalScrollPolicy="off" xmlns:local="*"
>
<fx:Script>
<![CDATA[
[Bindable] private var _thing:Thing;
override public function set data(value:Object):void
{
_thing = value as Thing;
super.data = value;
}
]]>
</fx:Script>
<mx:HBox width="100%"
paddingLeft="5" paddingTop="5"
paddingRight="5" paddingBottom="5">
<mx:Label text="{_thing.name}" width="45" />
<local:ThingProgressBar width="100%" height="15"
ratio="{_thing.ratio}"/>
</mx:HBox>
</mx:HBox>
I removed watcher. Binding by watcher is considered a bad practice, use mxml binding or events instead.
I removed two Canvases with separated border and fill - they can be cobined together.
I used UIComponent instead of Canvas. Don't use containers unless you need layout, they are heavy.
I used HBox instead of Canvas in renderer because I like boxes more :) But you can't avoid using second container in renderer if you need custom styles since List overwrites renderer's stylesheet.

Flex 4. Is it possible to get canvas.captureimage from scrolling position and not from the top?

I'm making small image editor which crops/resize an image. Everything worked perfectly until very last moment. Canvas don't want to be captured from scrolling position: only from left top corner.
Question is: how can I use .captureimage of a canvas from scrolling position?
Thanks a lot in advance
import mx.controls.Image;
import mx.events.FlexEvent;
import mx.graphics.ImageSnapshot;
import mx.graphics.codec.JPEGEncoder;
import spark.events.TextOperationEvent;
public var aspectRatio:Number=new Number();
private var loader:Loader;
private var request:URLRequest;
private var loadBD:BitmapData;
public var cropBD:BitmapData= new BitmapData(732,144,false,0x00000000);
private function saveImageToFileSystem():void
{
var oldWidthSize:int;
var oldHeightSize:int;
imgCanvas.verticalScrollBar.alpha=0;
imgCanvas.horizontalScrollBar.alpha=0;
var posPoint:Point = new Point(0,0);
var jPEGEncoder:JPEGEncoder = new JPEGEncoder(500);
oldWidthSize=imgCanvas.width;
oldHeightSize=imgCanvas.height;
imgCanvas.height=144;
imgCanvas.width=732;
tracer.text=imgCanvas.verticalScrollPosition.toString();
var imageSnapshot:ImageSnapshot = ImageSnapshot.captureImage(imgCanvas, 0, jPEGEncoder, true);
var fileReference:FileReference = new FileReference();
fileReference.save(imageSnapshot.data, "img123.jpg");
imgCanvas.verticalScrollBar.alpha=1;
imgCanvas.horizontalScrollBar.alpha=1;
imgCanvas.height=oldHeightSize;
imgCanvas.width=oldWidthSize;
}
protected function hslider1_changeHandler(event:Event):void
{
WidthEditor.text=myImage.width.toString(); //put image width into TextInput
myImage.width=WidthChanger.value; //resize picture
}
protected function windowedapplication1_initializeHandler(event:FlexEvent):void
{
// TODO Auto-generated method stub
}
protected function OpenBtn_clickHandler(event:MouseEvent):void
{
// TODO Auto-generated method stub
//WidthChanger.maximum=myImage.width;
//imgCanvas.height=myImage.height;
var file:File = new File();
file.addEventListener(Event.SELECT, dirSelected);
file.browseForOpen("Select image");
function dirSelected(e:Event):void {
ImgAddress.text=(file.nativePath);
myImage.source=(file.nativePath);
WidthEditor.text="732";
myImage.width=int(WidthEditor.text);
WidthChanger.value=myImage.width;
}
}
protected function WidthEditor_changeHandler(event:TextOperationEvent):void
{
// TODO Auto-generated method stub
myImage.width=int(WidthEditor.text);
WidthChanger.value=myImage.width;
}
protected function OpenBtn_buttonDownHandler(event:FlexEvent):void
{
// TODO Auto-generated method stub
}
protected function ProgressBar_completeHandler(event:Event):void
{
// TODO Auto-generated method stub
}
protected function ResizeBtn_clickHandler(event:MouseEvent):void
{
// TODO Auto-generated method stub
}
]]>
</fx:Script>
<mx:ProgressBar width="200" source="myImage" x="555.2" y="40" id="ProgressBar" complete="ProgressBar_completeHandler(event)"/>
<mx:Canvas id="imgCanvas" autoLayout="false" x="112.95" y="128.9" width="732" height="417" borderVisible="false" verticalScrollPolicy="auto" >
<mx:Image id="myImage" x="0" y="0" scaleContent="true"/>
</mx:Canvas>
<s:Button click="saveImageToFileSystem()" label="Save Image" x="116.2" y="10"/>
<s:HSlider change="hslider1_changeHandler(event)" id="WidthChanger" stepSize="1" minimum="1" maximum="3000" x="114.2" y="89" width="189"/>
<s:Button x="259.2" y="10" label="Open" id="OpenBtn" click="OpenBtn_clickHandler(event)" buttonDown="OpenBtn_buttonDownHandler(event)"/>
<s:TextInput x="337.2" y="10" id="ImgAddress" width="418"/>
<s:Label x="262.2" y="48" text="Label" id="tracer"/>
<s:Label x="116.2" y="69" text="Width:" fontFamily="Georgia" fontStyle="italic"/>
<s:TextInput x="312.2" y="82" width="64" id="WidthEditor" change="WidthEditor_changeHandler(event)"/>
<s:Label x="367.2" y="48" text="Label" id="tracer2"/>
<mx:Image width="732" height="144" id="CaptureSection" x="112.95" y="264.9"/>
<s:BorderContainer x="112.2" y="129.65" width="718" height="136" backgroundColor="#C7C8CA" backgroundAlpha="0.7" borderVisible="false">
</s:BorderContainer>
<s:BorderContainer x="112.2" y="408.65" width="718" height="124" backgroundColor="#C7C8CA" backgroundAlpha="0.7" borderVisible="false">
</s:BorderContainer>
</s:WindowedApplication>
Maybe you can use
var imageBitmapData:BitmapData = ImageSnapshot.captureBitmapData(yourcanvas);
var x:Number = yourcanvas.horizontalScrollPosition;
var y:Number = yourcanvas.verticalScrollPosition;
var w:Number = yourcanvas.width;
var h:Number = yourcanvas.height;
And then use imageBitmapData.copyPixel to get the part of the picture you want.

Cannot figure out why List won't display data from ArrayCollection

I'm working on a flash cards application and am using an ArrayCollection of Objects to store each cards individual data. When the user click the 'save' button, the text from the two textAreas and the 'title' textinput are stored in the AC as one object with .title, .side1 and .side2 properties that contain the text from the flash card.
I have made a List in a separate class I want to have display the title of each card the user has created, but after days of researching and looking around, I still cannot get the display to list the titles.
If anyone could point me in the right direction it would very appreciated.
Part of my NewCard.mxml:
<?xml version="1.0" encoding="utf-8"?>
<fx:Script>
<![CDATA[
import flash.events.EventDispatcher;
import mx.collections.ArrayCollection;
import spark.effects.SlideViewTransition;
import views.MyCards;
protected function button1_clickHandler(event:MouseEvent):void // back button
{
{
navigator.pushView(views.MyFlashCardsHome, event.relatedObject);
}
}
protected function button2_clickHandler(event:MouseEvent):void // save button
{
var myc:MyCards = new MyCards();
var card:Object = new Object();
myc.add();
titleCard.text = "Card Added!";
}
protected function button3_clickHandler(event:MouseEvent):void // flip button
{
rotateEffect.play();
if(rotateEffect.isPlaying)
{
if(mtext1.visible)
{
mtext2.visible = true;
mtext1.visible = false;
//mtext2.text = "two";
groupt.layoutDirection = "rtl";
}
else
{
mtext2.visible = false;
mtext1.visible = true;
//mtext1.text = "one";
groupt.layoutDirection = "rtl";
}
}
}
protected function button4_clickHandler(event:MouseEvent):void // push home button
{
var slideViewTransition:SlideViewTransition = new SlideViewTransition( 300, SlideViewTransition.SLIDE_RIGHT);
navigator.pushView(views.HomePage, event.relatedObject, slideViewTransition);
}
]]>
</fx:Script>
<fx:Declarations>
<s:Rotate3D id="rotateEffect" duration="300" target="{groupt}"
angleYFrom="0" angleYTo="180"
autoCenterTransform="true"
effectStart="flipButton.enabled=false;"
effectEnd="flipButton.enabled=true;"/>
</fx:Declarations>
<s:actionContent>
<s:Button height="50" label="Study" click="button1_clickHandler(event)" cornerRadius="0"
fontFamily="_sans"/>
<s:Button height="62" click="button4_clickHandler(event)" cornerRadius="0" skinClass="skins.homeButtonSkin"/>
</s:actionContent>
<s:Image x="0" y="-80" width="1024" height="600" source="#Embed('mainapp1.jpg')"/>
<s:TextInput id="titleCard" x="240" y="10" height="62" chromeColor="#515851" color="#060606"
contentBackgroundAlpha="1.0" contentBackgroundColor="#FFFFFF" text="Title"/>
<s:SkinnableContainer
id = "groupt" x="161" y="88" width="703" height="357" >
<s:TextArea id="mtext2" visible="false" x="0" y="0" width="703" height="357"
color="#000000" contentBackgroundAlpha="1.0"
contentBackgroundColor="#FFFFFF" editable="true" enabled="true"
paddingTop="70" text="Enter Text Here: (Side Two)" textAlign="center"/>
<s:TextArea id="mtext1" x="0" y="0" width="703" height="357" color="#030303"
contentBackgroundAlpha="1.0" contentBackgroundColor="#FFFFFF" editable="true"
enabled="true" fontFamily="Arial" fontStyle="normal" fontWeight="normal"
lineThrough="false" paddingTop="70" text="Enter Text Here: (Side One)"
textAlign="center" textDecoration="none" verticalAlign="middle"/>
</s:SkinnableContainer>
<s:Button x="763" y="10" height="62" label="Save" click="button2_clickHandler(event)"
cornerRadius="0" fontFamily="_sans"/>
<s:Label x="5" y="34" color="#49A6D6" fontFamily="Georgia" fontStyle="italic" fontWeight="bold"
paddingLeft="25" text="My"/>
<s:Label x="68" y="34" width="73" color="#E0B338" fontFamily="Georgia" fontStyle="italic"
fontWeight="bold" paddingLeft="0" text="Flash"/>
<s:Label x="138" y="34" color="#49A6D6" fontFamily="Georgia" fontStyle="italic" fontWeight="bold"
text="Cards!"/>
<s:Button id="flipButton" x="468" y="460" height="50" label="Flip" chromeColor="#2428D8"
click="button3_clickHandler(event)" fontFamily="_sans"/>
Part of my MyCards.mxml:
<?xml version="1.0" encoding="utf-8"?>
<fx:Script>
<![CDATA[
import flash.events.IOErrorEvent;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import mx.collections.ArrayCollection;
import mx.collections.ArrayList;
import mx.events.CollectionEvent;
import mx.events.FlexEvent;
import spark.effects.SlideViewTransition;
import spark.events.IndexChangeEvent;
import views.NewCard;
public var file:File;
public var fileStream:FileStream;
public var fileName:String = "Initial String";
private var directory:String = "SimpleSaveFromAIR";
public var nc:NewCard = new NewCard();
public var card:Object = new Object();
[Bindable]
public var cards:ArrayCollection = new ArrayCollection();
protected function button1_clickHandler(event:MouseEvent):void // pushed home button
{
var svt:SlideViewTransition = new SlideViewTransition(300, SlideViewTransition.SLIDE_RIGHT);
navigator.pushView(views.HomePage, event.relatedObject, svt);
}
public function add():void
{
var nc:NewCard = new NewCard();
var card:Object = new Object();
card.fTitle = nc.titleCard.text; //adding text to object from NewCard.mxml class
cards.addItem(card);
}
/* public function save():void
{
file = File.documentsDirectory.resolvePath(directory + "/" + fileName);
fileStream = new FileStream();
fileStream.open(file, FileMode.WRITE);
fileStream.writeObject(cards);
fileStream.close();
} */
public function myCardsList_creationCompleteHandler(event:FlexEvent):void
{
cards.addEventListener(CollectionEvent.COLLECTION_CHANGE, refreshList);
trace(cards.list); // no data at all shows up here
}
private function refreshList(event:CollectionEvent):void
{
trace("cards refreshed "+ cards.list);
}
public function testButton_clickHandler(event:MouseEvent):void
{
card.fTitle = nc.titleCard.text;
cards.addItem(card);
//trace(cards.list); // add data that has been added shows up here
}
]]>
</fx:Script>
<s:actionContent>
<s:Button id="testButton" label="Button" click="testButton_clickHandler(event)" />
<s:Button label="Delete"/>
<s:Button label="Home" click="button1_clickHandler(event)" skinClass="skins.homeButtonSkin"/>
</s:actionContent>
<s:Image x="0" y="-80" height="603" source="mainapp1.jpg"/>
<s:List id="myCardsList" x="10" y="10" left="0" right="0" top="0" bottom="0" width="1004"
height="500" dataProvider="{cards}" labelField="fTitle"
enabled="true" >
</s:List>
Again any help is greatly appreciated.
CardVO class:
package
{
public class CardVO
{
private var _title:String; //values returned from getter/setter functions
private var _side1:String;
private var _side2:String;
//get the "Title", "Side1" and "Side2" values from textAreas (later) and set them
// above variables
public function get Title():String {return _title;}
public function set Title(value:String):void { _title = value; }
public function get Side1():String {return _side1;}
public function set Side1(value:String):void {_side1 = value;}
public function get Side2():String {return _side2;}
public function set Side2(value:String):void {_side2 = value;}
}
}
** NewCard snippet:**
[Bindable]
public var myCard:CardVO = new CardVO(); // create new instance of CardVO
....
<!-- text property of mtext1 and mtext2 is bound and returned to the get/set functions in CardVO in the 'change' event-->
<!-- change sets setter values to those retrieved from textAreas-->
<s:TextArea id="mtext2" visible="false" x="0" y="0" width="703" height="357"
color="#000000" contentBackgroundAlpha="1.0"
contentBackgroundColor="#FFFFFF" editable="true" enabled="true"
paddingTop="70" text="{myCard.Side2}" change = "{myCard.Side2 = mtext2.text}"
textAlign="center"/>
<s:TextArea id="mtext1" x="0" y="0" width="703" height="357" color="#030303"
contentBackgroundAlpha="1.0" contentBackgroundColor="#FFFFFF" editable="true"
enabled="true" fontFamily="Arial" fontStyle="normal" fontWeight="normal"
lineThrough="false" paddingTop="70" text="{myCard.Side1}" change="{myCard.Side1 = mtext1.text}"
textAlign="center" textDecoration="none" verticalAlign="middle"/>
</s:SkinnableContainer>
MyCards snippet:
public function add():void
{
var nc:NewCard = new NewCard(); // create new instance of NewCard
cards.addItem(nc.myCard); // add new Item to ArrayCollection 'cards'
trace(cards.list);
}
Mycards List code
<s:List id="myCardsList" x="10" y="10" left="0" right="0" top="0" bottom="0" width="1004"
height="500" change="myCardsList_changeHandler(event)" dataProvider="{cards}"
enabled="true" >
<s:itemRenderer>
<fx:Component>
<s:MobileItemRenderer label="{data.title}"/>
</fx:Component>
</s:itemRenderer>
</s:List>
Assuming you're using the List component you should be able to specify the field you want to show using the labelField property.
<s:List id="myFlashCardList" dataProvider="{cards}" labelField="fTitle"/>
EDIT 2:
It seems like what you're trying to do here (and correct me if I'm wrong), is to have the user create a new instance of the NewCard object and then add it to your cards ArrayCollection. Your list then displays the titles of the cards the user has created.
Assuming this is the case, I think you're making it a little complicated than it needs to be. ArrayCollections can hold any type of class or object so you don't have to create a new Object and add it to the ArrayCollection every time they add a new card.
What I would do is create a Card class and populate it using your NewCard component. When you're done, you add that Card class to the ArrayCollection. Something like this:
The CardVO class:
package
{
public class CardVO
{
private var _title:String;
private var _side1:String;
private var _side2:String;
public function get Title():String { return _title; }
public function set Title(value:String):void { _title = value; }
public function get Side1():String { return _side1; }
public function set Side1(value:String):void { _side1 = value; }
public function get Side2():String { return _side2; }
public function set Side2(value:String):void { _side2 = value; }
}
}
Then in your NewCard.mxml file you use a CardVO to store the data:
<fx:Script>
<![CDATA[
...
[Bindable] public var myCard:CardVO = new CardVO();
...
]]>
</fx:Script>
<s:SkinnableContainer id = "groupt">
<s:TextArea id="mtext2" text="{myCard.Side2}" change="{myCard.Side2 = mtext2.text}"/>
<s:TextArea id="mtext1" text="{myCard.Side1}" change="{myCard.Side1 = mtext1.text}" />
</s:SkinnableContainer>
Then after the user has created their card, you pass the CardVO object to your ArrayCollection.
...
public function add():void
{
var nc:NewCard = new NewCard();
cards.addItem(nc.myCard);
}
...
This is a very abbreviated example so feel free to ask any questions that don't make sense. You should also look into Data Binding if you haven't already done so. It will save you a lot of time and make your apps more efficient once you get the hang of it. :)

Flex: Saving mx:image with applied effects

I load image to control than I applie some effects, and when I save image it's saving without effects. What should i do?
Here is the code:
private var byteArr2:ByteArray;
private var fileRef:FileReference = new FileReference();
public function process():void
{
var ct:ColorTransform = new ColorTransform();
ct.redOffset = 99;
ct.blueOffset = 11;
ct.greenOffset = 22;
currImg.transform.colorTransform = ct;
callLater(toByteArray);
}
public function toByteArray():void
{
var data:BitmapData = new BitmapData(currImg.width, currImg.width);
data.draw(currImg);
var encod:JPEGEncoder = new JPEGEncoder(100);
byteArr2 = encod.encode(data);
}
public function saveFile():void
{
fileRef.save(byteArr2,"NewFileName1.jpg");
}
<mx:HBox>
<mx:VBox>
<s:Button x="69" y="98" label="open" click="open()()"/>
<s:Button label="show" click="show()"/>
<s:Button label="process" click="process()"/>
<s:Button label="save" click="saveFile()"/>
</mx:VBox>
<mx:Image id="currImg" width="200" height="300"/>
</mx:HBox>
UPDATE Appears new problem as I am using var data:BitmapData = new BitmapData(currImg.width, currImg.width); saved image is small(size like image control) but I need to save image with original size.
With var data:BitmapData = Bitmap(currImg.content).bitmapData; it worked
I would draw the component into a new BitmapData object rather than use the content of the currImg. This should give you what's drawn on the screen rather than the unmodified content. Something like so:
var data:BitmapData = new BitmapData(currImg.width, currImg.width);
data.draw(currImg);
Hope that helps.
Alright this isn't a great solution cause I don't know why it works but if you put a container around the image then save the results of drawing that it seems to work.
<?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:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.graphics.codec.JPEGEncoder;
private var byteArr2:ByteArray;
private var fileRef:FileReference = new FileReference();
public function process():void
{
var ct:ColorTransform = new ColorTransform();
ct.redOffset = 99;
ct.blueOffset = 11;
ct.greenOffset = 22;
currImg.transform.colorTransform = ct;
callLater(toByteArray);
}
public function toByteArray():void
{
var data:BitmapData = new BitmapData(everything.width, everything.width);
data.draw(everything);
var encod:JPEGEncoder = new JPEGEncoder(100);
byteArr2 = encod.encode(data);
}
public function saveFile():void
{
fileRef.save(byteArr2,"NewFileName1.jpg");
}
]]>
</fx:Script>
<mx:HBox>
<mx:VBox>
<!--<s:Button x="69" y="98" label="open" click="open()"/>-->
<!--<s:Button label="show" click="show()"/> -->
<s:Button label="process" click="process()"/>
<s:Button label="save" click="saveFile()"/>
</mx:VBox>
<mx:Box id="everything">
<mx:Image id="currImg" width="200" height="300" source="http://www.google.com/images/logos/ps_logo2.png"/>
</mx:Box>
</mx:HBox>
</s:Application>
Shaun

Flex 3 Binding problem

I have a custom ActionScript class:
package EntityClasses
{
import mx.collections.ArrayCollection;
[RemoteClass(alias="tkatva.tt.entities.CompanyInfo")]
[Bindable]
public class CompanyInfo
{
public var companyInfoId:int;
public var companyName:String;
public var streetAddress:String;
public var postNumber:String;
public var city:String;
public var country:String;
public var email:String;
public var businessIdentityCode:String;
public var intBic:String;
public var homepageUrl:String;
public var lastUpdatedBy:String;
public var lastUpdateDate:Date;
public var version:int;
public var settingGroupList:ArrayCollection;
public var bankAccountList:ArrayCollection;
public var personList:ArrayCollection;
}
}
And I want to bind these values to textBoxes, so that when user types information to the textBoxes it is populated in the class too. Is Flex 3 bidirectional so that marking the class with [Bindable] I can bind the values to a textbox for example?
This is my mxml file in which I try to bind the class:
import mx.rpc.events.ResultEvent;
import EntityClasses.CompanyInfo;
[Bindable]
public var company:CompanyInfo;
public var uuid:String;
private function init():void {
company = new CompanyInfo();
}
private function getCompanyInfo():void {
try {
company = TtRo.getCompanyInfo(uuid);
} catch (Exception) {
}
}
private function handleClick():void {
this.txtInfo.text = "COMPANY:" + company.companyName;
TtRo.addCompanyInfo(company,uuid);
}
private function handleAdding(e:ResultEvent):void {
var res:Boolean;
res = e.result as Boolean;
if (res) {
this.txtInfo.text = "OK";
} else {
this.txtInfo.text = "NOTOK";
}
}
]]>
</mx:Script>
<mx:TextInput x="194" y="10" id="txtCname" text="{company.companyName}"/>
<mx:TextInput x="194" y="40" id="txtStreet" text="{company.streetAddress}"/>
<mx:TextInput x="194" y="70" id="txtPostnumber" text="{company.postNumber}"/>
<mx:TextInput x="194" y="100" id="txtCity" text="{company.city}"/>
<mx:TextInput x="194" y="130" id="txtCountry" text="{company.country}"/>
<mx:TextInput x="194" y="160" id="txtEmail" text="{company.email}"/>
<mx:TextInput x="194" y="190" id="txtBic" text="{company.businessIdentityCode}"/>
<mx:TextInput x="194" y="220" id="txtIntBic" text="{company.intBic}"/>
<mx:TextInput x="194" y="250" id="txtUrl" text="{company.homepageUrl}"/>
Whats wrong with this? The flex compiler shows me this kind of warnings: Data binding will not be able to detect assignments to "company".
Im new to Flex and any help would be appriciated... Thanks...
No, Flex data binding is not bidirectional. You have to explicitly bind the text property of text fields back to the corresponding properties of the company object using BindingUtils.bindProperty()
private function init():void
{
company = new CompanyInfo();
BindingUtils.bindProperty(company, "companyName", this ["txtCname", "text"]);
}
If you're using it in MXML components it might be more readable if you add the reverse binding in one place using the mx:Bindable tag
eg.
<mx:Binding destination="company.companyName" source="txtCname.text" />
<mx:Binding destination="company.streetAddress" source="txtStreet.text" />
...
etc.
Flex 3 Cookbook has a lot of recipes for this sort of work in chapter 11.9 & ch 14
You need to mark the variables themselves as bindable:
[Bindable]public var companyInfoId:int;
Welcome to Flex data binding, its lovely :)

Resources