Get ByteArray from external asset image synchronously in Flex - apache-flex

I have a var that holds the String value for the path to an image.
How can I use that to get the ByteArray from that image synchronously?
Thank you.

You can't do it synchronously. But here is how you do it asynchronously.
<?xml version="1.0" encoding="utf-8"?>
<fx:Script>
<![CDATA[
public function init():void {
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
loader.load(new URLRequest(encodeURI("http://www.google.com/logos/2011/mary_blair-2011-hp.jpg")));
}
private function onComplete(e:Event)
{
//of course if all you were doing is displaying an image its better to do:
//image.source = e.currentTarget.content;
var bytes:ByteArray = LoaderInfo(e.currentTarget).bytes;
//binary output
trace(bytes);
var imageLoader:Loader = new Loader();
imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageComplete);
imageLoader.loadBytes(bytes, null);
}
private function onImageComplete(e:Event):void
{
image.source = LoaderInfo(e.currentTarget).content;
}
]]>
</fx:Script>
<s:Image id="image" />

Related

How to position spark List control below StageWebView in Flex Mobile

I am developing mobile application for iOS and Android using Flex Mobile. On one of the views I am displaying StageWebView with a Google map and a spark List control to display another data. I am using the StageWebView in order to benefit from Google Maps JavaScript API v3. Example code below:
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" title="Clubs" backgroundAlpha="0"
viewActivate="view1_viewActivateHandler(event)"
backKeyPressed="view1_backKeyPressedHandler(event)"
initialize="view1_initializeHandler(event)">
<fx:Script>
<![CDATA[
import flash.sensors.Geolocation;
import mx.collections.ArrayCollection;
import mx.events.FlexEvent;
import spark.events.ViewNavigatorEvent;
private var myWebView:StageWebView;
[Bindable]
private var locations:ArrayCollection;
private var geolocation:Geolocation;
protected function view1_initializeHandler(event:FlexEvent):void
{
myWebView = new StageWebView();
myWebView.stage = this.stage;
}
protected function view1_viewActivateHandler(event:ViewNavigatorEvent):void
{
if(Geolocation.isSupported)
{
geolocation = new Geolocation();
geolocation.addEventListener(GeolocationEvent.UPDATE, onGeolocationChange);
}
}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{
super.updateDisplayList(unscaledWidth, unscaledHeight);
if (myWebView) {
var point:Point = (new Point());
point = localToGlobal(point);
myWebView.viewPort = new Rectangle(point.x,point.y, stage.width,stage.height/3);
}
}
protected function view1_backKeyPressedHandler(event:Event):void
{
if (myWebView)
{
myWebView.viewPort = null;
myWebView = null;
}
navigator.popView();
}
protected function onGeolocationChange(event:GeolocationEvent):void
{
geolocation.removeEventListener(GeolocationEvent.UPDATE, onGeolocationChange);
locations = new ArrayCollection();
var location0:Object = new Object();
location0.lat = event.latitude;
location0.long = event.longitude;
locations.addItem(location0);
var location1:Object = new Object();
location1.lat = "42.697325";
location1.long = "23.315364";
locations.addItem(location1);
var location2:Object = new Object();
location2.lat = "42.696441";
location2.long = "23.321028";
locations.addItem(location2);
var url:String = "http://whozzzin.dev.mediatecture.at/gmapsformobile/map.php";
var counter:Number = 1;
for each(var location:Object in locations)
{
if(counter == 1)
{
url += "?locations["+counter.toString()+"][lat] = " + location.lat;
url += "&locations["+counter.toString()+"][long] = " + location.long;
}
else
{
url += "&locations["+counter.toString()+"][lat] = " + location.lat;
url += "&locations["+counter.toString()+"][long] = " + location.long;
}
counter++;
}
myWebView.loadURL(url);
}
]]>
</fx:Script>
<s:navigationContent>
<s:Button includeInLayout="{Capabilities.version.indexOf('IOS') > -1}" visible="{Capabilities.version.indexOf('IOS') > -1}" id="backButton" label="BACK" click="view1_backKeyPressedHandler(event)"/>
</s:navigationContent>
<s:List width="100%" contentBackgroundAlpha="0" id="placesList" dataProvider="{locations}" labelField="lat">
<s:layout>
<s:TileLayout columnWidth="{(width - 16)/3}"/>
</s:layout>
</s:List>
</s:View>
Currently the list is not visible because it appears behind the StageWebView. My question is how to position the List control exactly after the WebStageView.
You can use the top constraint:
<s:List width="100%" top="{stage.height/3}" id="placesList"
Edit: Put in a trace(stage.height); in your updateDisplayList function and also look at stage.stageHeight. Those values should help you figure out the exact top value to use in this case.
How I solved it:
I get the bottom of the WebStageView and convert a new point from global to local with x =0 and y = myWebView.bootom:
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{
super.updateDisplayList(unscaledWidth, unscaledHeight);
if (myWebView) {
var point:Point = (new Point(0,this.radiusDropDown.height));
point = localToGlobal(point);
myWebView.viewPort = new Rectangle(point.x,point.y, stage.width,stage.height/3);
this.placesList.y = globalToLocal(new Point(0,myWebView.viewPort.bottom)).y;
}
}

DataBinding in List

I am trying to bind data within a ArrayList to a list, but here only the last element shows up on the list(99), not the entire contents of the arraylist.
private function completeHandler(event:Event):void
{
var xmlData:XML = XML(event.target.data);
trace(xmlData);
var i:int = 0;
for (i;i<100;i++)
{
var arr:ArrayList = new ArrayList();
arr.addItem(i);
trace(arr);
}
list.dataProvider = arr;
}
I am not able to figure out what to do here?
You're creating an ArrayList with one item a 100 times. Replace with this and you should be fine:
var arr:ArrayList = new ArrayList();
for (var i:int = 0; i<100; i++) {
arr.addItem(i);
}
Or better yet, just wrap your XML in an XMLListCollection instead of copying the nodes one by one (assuming it is the actual content of the XML data you want instead of the indices):
private function completeHandler(event:Event):void
{
var xmlData:XML = XML(event.target.data);
list.dataProvider = new XMLListCollection(xmlData.children());
}
(Note that this is not DataBinding: it is just setting the dataProvider property)
check this code this will help you,
you can navigate through all data on the basis of rowcount of list....
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" minWidth="955" minHeight="600">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]private var _index:int = 0;
private var _coll:ArrayCollection = new ArrayCollection([{name:'ashish',age:'28'},{name:'abhi',age:'29'},{name:'kunal',age:'27'},
{name:'ashish1',age:'28'},{name:'abhi1',age:'29'},{name:'kunal1',age:'27'},
{name:'ashish2',age:'28'},{name:'abhi2',age:'29'},{name:'kunal2',age:'27'},
{name:'ashish3',age:'28'},{name:'abhi3',age:'29'},{name:'kunal3',age:'27'}]);
protected function button1_clickHandler(event:MouseEvent):void
{
// TODO Auto-generated method stub
if((_index-li.rowCount>=0))
_index = _index - li.rowCount;
}
protected function button2_clickHandler(event:MouseEvent):void
{
// TODO Auto-generated method stub
if((_index+li.rowCount<_coll.length))
_index = _index + li.rowCount;
}
]]>
</mx:Script>
<mx:List id="li" dataProvider="{_coll.source.slice(_index,(_index+li.rowCount))}" labelField="name" rowCount="3" width="100"/>
<mx:HBox>
<mx:Button label="<-" click="button1_clickHandler(event)"/>
<mx:Button label="->" click="button2_clickHandler(event)"/>
</mx:HBox>
</mx:Application>

ByteArray to Image display Flex - SQLite

I have recently figured out how to use an SQLite db with Flex. Now I'm having trouble displaying the data properly. I've tried several binding strategies and I've largely come up short. I had undefined property errors, unusable errors, and finally! Code without errors! Also, code without a displayed image. Any help is appreciated as always.
Here's my code so far; trying to keep it tidy, Async, and I've left an unused variable or two from my messing around with it. Thanks for any insight.
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
title="NM1"
>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import flash.data.SQLConnection;
import flash.data.SQLResult;
import flash.data.SQLStatement;
import flash.filesystem.File;
import mx.collections.ArrayCollection;
private var conn:SQLConnection;
private var createStmt:SQLStatement;
private var selectStmt:SQLStatement;
[bindable] private var dataField:ArrayCollection;
[bindable] private var row:Object;
[bindable] private var pngIndex:int;
[bindable] public var pngTitle:String;
[bindable] private var pngByteArray:ByteArray;
private function init():void
{
conn = new SQLConnection();
conn.addEventListener (SQLEvent.OPEN, openSuccess);
conn.addEventListener (SQLErrorEvent.ERROR, openFailure);
var dbFile:File = File.applicationDirectory.resolvePath("assets/NM.sqlite");
conn.openAsync(dbFile);
}
private function openSuccess(event:SQLEvent):void
{
conn.removeEventListener(SQLEvent.OPEN, openSuccess);
conn.removeEventListener(SQLErrorEvent.ERROR, openFailure);
getData();
}
private function openFailure(event:SQLErrorEvent):void
{
conn.removeEventListener(SQLEvent.OPEN, openSuccess);
conn.removeEventListener(SQLErrorEvent.ERROR, openFailure);
// Make an alert Dialog
// = "Error opening database";
trace("event.error.message:", event.error.message);
trace("event.error.details:", event.error.details);
}
private function getData():void
{
//status = "Loading data";
selectStmt = new SQLStatement();
selectStmt.sqlConnection = conn;
var sql:String = "SELECT Picture FROM Data WHERE 'Index' = 0";
selectStmt.text = sql;
selectStmt.addEventListener(SQLEvent.RESULT, selectResult);
selectStmt.addEventListener(SQLErrorEvent.ERROR, selectError);
selectStmt.execute();
}
private function selectResult(event:SQLEvent):void
{
//status = "Data loaded";
selectStmt.removeEventListener(SQLEvent.RESULT, selectResult);
selectStmt.removeEventListener(SQLErrorEvent.ERROR, selectError);
var result:SQLResult = selectStmt.getResult();
// dataField = new ArrayCollection(selectStmt.getResult().data);
if (result.data != null) {
row = result.data[0];
pngIndex = result.data[0].Index;
pngTitle = result.data[0].Title;
pngByteArray = result.data[0].Picture;
Pic.source = pngByteArray;
}
}
private function selectError(event:SQLErrorEvent):void
{
//status = "Error loading data";
selectStmt.removeEventListener(SQLEvent.RESULT, selectResult);
selectStmt.removeEventListener(SQLErrorEvent.ERROR, selectError);
trace("SELECT error:", event.error);
trace("event.error.message:", event.error.message);
trace("event.error.details:", event.error.details);
}
]]>
</fx:Script>
<s:Image id="Pic" x="0" y="0" width="263" height="99"/>
<s:TextArea id="text1" x="0" y="313"
/>
EDIT I have updated the code now, with perfect, error-free code that does not display my image. Help!!
Make sure you call the first function in the initialize() function as your program starts!
I had forgotten it somewhere in my code testing. :/

Error #1069: Property not found on and there is no default value

am having an issue with a project I am working on in Flash Builder.
Following is my stack and code example. Could someone please tell me what I am doing wrong?
Thank you for your time.
-- Stack --
ReferenceError: Error #1069: Property page4 not found on WOAPPv2 and there is no default value.
at WOAPPv2/dragDropHandler()[/Users/martinw/Documents/Adobe Flash Builder 4/WOAPPv2/src/WOAPPv2.mxml:165]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.core::UIComponent/dispatchEvent()[E:\dev\4.x\frameworks\projects\framework\src\mx\core\UIComponent.as:12528]
at mx.managers.dragClasses::DragProxy/_dispatchDragEvent()[E:\dev\4.x\frameworks\projects\framework\src\mx\managers\dragClasses\DragProxy.as:374]
at mx.managers.dragClasses::DragProxy/mouseUpHandler()[E:\dev\4.x\frameworks\projects\framework\src\mx\managers\dragClasses\DragProxy.as:599]
--Code Example -- This what works
import mx.core.DragSource;
import mx.events.DragEvent;
import mx.managers.DragManager;
private function initiateDrag(event:MouseEvent,value:String):void{
var dragInitiator:Image= event.currentTarget as Image;
var dragSource:DragSource = new DragSource();
dragSource.addData(value, 'value');
DragManager.doDrag(dragInitiator, dragSource, event);
}
private function dragEnterHandler(event:DragEvent):void {
var dropTarget:VBox =event.currentTarget as VBox;
if (event.dragSource.hasFormat('value')) {
DragManager.acceptDragDrop(dropTarget);
}
}
private function dragDropHandler(event:DragEvent):void {
var pageName:String = event.currentTarget.name as String;
var value:String = event.dragSource.dataForFormat('value') as String;
this[pageName].source = "assets/big/"+value;
}
<s>
<s:HGroup id="hGr"
requestedColumnCount="2"
variableColumnWidth="false"
columnWidth="475"
height="450"
gap="100"
clipAndEnableScrolling="true" paddingLeft="10" paddingRight="10">
<mx:VBox name="page1"
backgroundColor="#EFEFF0"
verticalScrollPolicy="off"
horizontalScrollPolicy="off"
horizontalAlign="center" verticalAlign="middle"
dragEnter="dragEnterHandler(event)"
dragDrop="dragDropHandler(event)"
width="475"
x="0">
<mx:Image id="page1" showBusyCursor="true" width="713" height="692" scaleContent="true" maintainAspectRatio="true" minWidth="713" minHeight="692" scaleX="1" scaleY="1" horizontalAlign="center" verticalAlign="top"/>
</mx:VBox>
</s:HGroup>
It Breaks If I do it this way by creating the containers and Images on runtime
<script>
private function initVars():void {
createSpreads();
}
public function createSpreads():void {
var s:VBox = new VBox();
s.name ="page4";
s.setStyle("backgroundColor","#fe0000");
s.verticalScrollPolicy="off";
s.horizontalScrollPolicy="off";
s.setStyle("horizontalAlign","center");
s.setStyle("verticalAlign","middle");
s.addEventListener(DragEvent.DRAG_ENTER, dragEnterHandler);
s.addEventListener(DragEvent.DRAG_DROP, dragDropHandler);
s.width= 475;
s.setStyle("x","0");
hGr.addElement(s);
hGrCol4.text = "Vboxname: "+s.name+"VboxID: "+s.id;
var page3:Image = new Image();
page3.id ="page4";
page3.showBusyCursor = true;
page3.width = 713;
page3.height = 692
page3.scaleContent = true;
page3.maintainAspectRatio = true;
page3.minWidth = 713;
page3.minHeight = 692;
page3.scaleX = 1;
page3.scaleY = 1;
page3.source = "assets/big/IMG_7112.jpg";
page3.setStyle("backgroundColor","#ffffff");
page3.setStyle("horizontalAlign","center");
page3.setStyle("verticalAlign","top");
s.addElement(page3);
hGrCol3.text = "Imagename: "+page3.name+"ImageID: "+page3.id;
}
import mx.core.DragSource;
import mx.events.DragEvent;
import mx.managers.DragManager;
private function initiateDrag(event:MouseEvent,value:String):void{
var dragInitiator:Image= event.currentTarget as Image;
var dragSource:DragSource = new DragSource();
dragSource.addData(value, 'value');
DragManager.doDrag(dragInitiator, dragSource, event);
}
private function dragEnterHandler(event:DragEvent):void {
var dropTarget:VBox =event.currentTarget as VBox;
if (event.dragSource.hasFormat('value')) {
DragManager.acceptDragDrop(dropTarget);
}
}
private function dragDropHandler(event:DragEvent):void {
var pageName:String = event.currentTarget.name as String;
var value:String = event.dragSource.dataForFormat('value') as String;
this[pageName].source = "assets/big/"+value;
}
</script>
<s>
<s:HGroup id="hGr"
requestedColumnCount="2"
variableColumnWidth="false"
columnWidth="475"
height="450"
gap="100"
clipAndEnableScrolling="true" paddingLeft="10" paddingRight="10">
</s:HGroup>
</s>
Above with no containers in HGroup returns the 'property page4 not found on WOAPPv2 and there is no default value' - My end result should be this
page4.source = "assets/big/imagename.jpg";
I am stumped. Im rethinking it and may just create the vboxes and then set a trigger to create the image and populate in the samedragDropHandler.
Thoughts?
Below is the solution - again - thanks goes to alxx. Now I need to start contributing my knowledge to other folks on here.
public function dragDropHandler(event:DragEvent):void {
// Retrieve the Image Name from Drop
var value:String = event.dragSource.dataForFormat('value') as String;
//
event.currentTarget.getChildAt(0).source = "assets/big/"+value;
}
...continuing here for proper formatting
Problem line:
var value:String = event.dragSource.dataForFormat('value') as String;
this[pageName].source = "assets/big/"+value;
My goal was to addelement a vbox and
image child that shared the name with
an id and use the event to grab the
currenttarget name being the image
control
Not sure if I understand it right. If event.currentTarget is Image you need, you can just cast it to Image. Or you need to find another Image somewhere (one generated in Repeater)?
update
"I am trying to use the name of the VBox as a string to use for dot notation to reference the Image inside of it"
Names of DisplayObjects are only labels, not references. If you think you can traverse object hierarchy with names like in JS DOM, then no, it's done other way in Flash. You can get reference to VBox with event.currentTarget - it's more useful that its name (String). You can get Image inside it with getChildAt.

Loading Swf with bytearray in AIR

We have requirement with the AIR application which loads the flex generated swf which inturn loads the flash generated swf using SWFLoader. This is not working as desired. This gives the following error:
SecurityError: Error #3226: Cannot import a SWF file when LoaderContext.allowCodeImport is false.
This is our AIR application.
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="initApp()">
<mx:Script>
<![CDATA[
import mx.controls.SWFLoader;
[Embed(source="FlexLoadingFlash.swf")]
public var flexMovie:Class;
private function initApp():void {
// First convert the Swf into MovieClip
var movieclip:MovieClip = new flexMovie();
// get the byteArray from movieClip
var byteArray:ByteArray = movieclip.movieClipData;
var swfLoader:SWFLoader = new SWFLoader();
// load bytearray into swfLoader
swfLoader.source = byteArray;
swfLoader.maintainAspectRatio = false;
swfLoader.percentHeight = vbox.height;
swfLoader.percentWidth = vbox.width;
swfLoader.invalidateDisplayList();
swfLoader.invalidateSize();
// now add the swfloader into container
vbox.addChild(swfLoader);
}
]]>
</mx:Script>
<mx:VBox id="vbox" width="100%" height="100%" verticalCenter="0" horizontalCenter="0" cacheAsBitmap="true" >
</mx:VBox>
</mx:WindowedApplication>
Please let me know how can we fix this issue.
Use Loader.loadBytes() to load your SWF. Create an instance of LoaderContext. loadBytes method takes a LoaderContext instance as a parameter. Set the allowCodeImport property of your LoaderContext instance to true and it should work
Or you can just add these three lines before you set the source
var loaderContext: LoaderContext = new LoaderContext();
loaderContext.allowLoadBytesCodeExecution = true;
swfLoader.loaderContext = loaderContext;
<mx:SWFLoader id="swfObj"
width="100%" height="100%"
complete="swfObj_completeHandler(event)"/>
<fx:Script>
<![CDATA[
[Bindable]
[Embed(source="assets/soundbar.swf")]
private static var swfClass:Class;
private var swfSoundBar : MovieClip;
[Bindable] private var mp3Player:MP3Player = MP3Player.getInstance();
protected function init(event:FlexEvent):void
{
swfSoundBar = new swfClass();
var byteArray:ByteArray = swfSoundBar.movieClipData;
var loaderContext: LoaderContext = new LoaderContext();
loaderContext.allowLoadBytesCodeExecution = true;
swfObj.loaderContext = loaderContext;
swfObj.source = byteArray;
}
protected function swfObj_completeHandler(event:Event):void
{
swfSoundBar = SWFLoader(event.target).content as MovieClip;
swfSoundBar.width = 32;
swfSoundBar.height = 14;
swfSoundBarShowHide();
}
protected function swfSoundBarShowHide():void
{
if (swfSoundBar){
if (mp3Player.isPlaying){
swfSoundBar.gotoAndStop(0);
swfSoundBar.stop();
} else {
swfSoundBar.gotoAndPlay(0);
}
}
}
]]>
</fx:Script>

Resources