Rendering text in Flex in Graphics - apache-flex

I'm new to Flex (and Flash) and just playing around at the moment. I was using the drawing methods on a Canvas to color it blue, and wanted to draw text, however, I have an error somewhere in the code.
<?xml version="1.0" ?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%" paddingLeft="0" paddingRight="0" paddingTop="0" paddingBottom="0" enterFrame="enterFrame(event)" applicationComplete="addtext(event)">
<mx:VBox width="640" height="480">
<mx:Label id="debug" text="No debug yet." />
<mx:Button id="myButton" label="Hello World" />
<mx:Button id="myOtherButton" label="Foo Bar Baz" />
<mx:Canvas id="myCanvas" width="100%" height="100%" />
</mx:VBox>
<mx:Script>
<![CDATA[
import flash.text.engine.*;
import mx.controls.*;
public function addtext(event:Event):void
{
Alert.show("foo!");
var str:String = "Hello World.";
var format:ElementFormat = new ElementFormat();
var textElement:TextElement = new TextElement(str, format);
var textBlock:TextBlock = new TextBlock();
textBlock.content = textElement;
var textLine:TextLine = textBlock.createTextLine(null, 300);
textLine.x = 30;
textLine.y = 200;
Alert.show("baz!");
this.addChild(textLine); // Execution appears to cease here.
Alert.show("bar!");
}
public function enterFrame(event:Event):void
{
myCanvas.graphics.clear();
myCanvas.graphics.beginFill(0x66666FF);
myCanvas.graphics.drawRect(0, 0, myCanvas.width, myCanvas.height);
myCanvas.graphics.endFill();
}
]]>
</mx:Script>
</mx:Application>
The alerts get to "baz!" but not "bar!", so the error is somewhere there. Also, I've been running this in Firefox and fdb, but fdb isn't outputting anything - it's just launching a Flash player. A starting point on how to debug Flash

IMHO this is a somewhat fuzzy mix up between flash and flex.
First: I would suggest that if you would like your canvas to be blue, you'd use:
<mx:canvas backgroundColor="0x66666FF" width="100%" height="100%" />
Secondly the text layout framework (Commonly TLF) is a topic I would reccomend you skip until you are a bit more familiar with flex and flash.
The error you are having is because TextLine does not implement IUIComponent, and therefore cannot be added to a Flex container.
If you want to use TLF, you will need to add a spark component capable of handling it, to your application, ex. s:RichText or s:TextArea
Happy coding!!

Related

Flex: Getting rid of "Warning: Filter will not render. The DisplayObject's filtered dimensions ..." error

When printing (I think at the point I call FlexPrintJob.addObject()) I get the following:
Warning: Filter will not render. The DisplayObject's filtered dimensions (3324, 1740) are too large to be drawn.
I don't know what it thinks is 3324, 1740. The mx:Box object I pass to it is about 600x100.
I'm wondering if this problem is related to another problem I'm having. What gets printed has an extra border on the bottom and the right of what I want printed. I'm hoping that understanding this message will correct my problem.
I'm using the Flex 3.5 SDK
Here's a stripped down version of the code that still allows for this problem:
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml"
title="FPL Flight Strip"
showCloseButton="true"
borderAlpha="1"
borderColor="{BrandGlobals.COLOUR_DARK}"
borderThicknessBottom="1"
borderThicknessLeft="1"
borderThicknessRight="1"
borderThicknessTop="0"
dropShadowEnabled="true"
fontSize="{AppGlobals.fntSize}"
backgroundAlpha="1.0"
alpha="1.0"
creationComplete="init()"
close="PopUpManager.removePopUp(this);">
<mx:Script>
<![CDATA[
import mx.managers.PopUpManager;
import mx.printing.FlexPrintJobScaleType;
import mx.printing.FlexPrintJob;
private function init():void
{
this.setStyle('fontFamily', 'Arial');
}
private function printData():void
{
var dbPrintJob: FlexPrintJob = new FlexPrintJob();
if (dbPrintJob.start())
{
try
{
dbPrintJob.addObject(boxPrint, FlexPrintJobScaleType.NONE);
}
catch (e:Error)
{
//trace(e);
}
dbPrintJob.send();
}
}
]]></mx:Script>
<mx:VBox width="600" height="100" horizontalAlign="center" verticalAlign="middle" backgroundColor="#FFFFFF" verticalGap="1" paddingLeft="2" paddingRight="2" paddingTop="2" paddingBottom="2">
<mx:Box id="boxPrint" width="100%" height="100%" backgroundColor="#FFFFFF">
<mx:Box id="box" width="100%" height="100%"/>
</mx:Box>
</mx:VBox>
<mx:ControlBar width="100%" barColor="#E8E8E8" paddingBottom="0" paddingLeft="0" paddingRight="0" paddingTop="0">
<mx:VBox width="100%" height="100%" horizontalAlign="left" backgroundColor="#E8E8E8" paddingTop="5" paddingBottom="5" paddingRight="20" paddingLeft="20">
<mx:HBox width="100%" height="100%">
<mx:Button label="Print Strip" fontFamily="Arial" click="printData()" width="100" height="25" />
</mx:HBox>
</mx:VBox>
</mx:ControlBar>
</mx:TitleWindow>
I was not able to reproduce the filter error in Flex 3.6. Are you not able to upgrade? To my knowledge, there shouldn be very few issues with backwards compatibility, unless you are heavily overriding mx_internal.
I did however get the problem with the borders. This has to do with the way you are adding your objects. It's best to wrap the thing you want to print in a container, then add the container to the print job. This let's you control things like margins and spacing.
private function printData():void
{
var dbPrintJob:FlexPrintJob = new FlexPrintJob();
if(dbPrintJob.start())
{
try
{
dbPrintJob.addObject(this.canvas, FlexPrintJobScaleType.NONE);
}
catch(e:Error)
{
//trace(e);
}
dbPrintJob.send();
}
}
<mx:Canvas id="canvas" width="100%" height="100%">
<mx:Box id="boxPrint" top="10" left="10" bottom="10" right="10" backgroundColor="#FFFFFF">
<mx:Box id="box" width="100%" height="100%" />
</mx:Box>
</mx:Canvas>
Use the canvas to paint your background and space the children into the desired print layout.
I would also suggest giving this a quick read:
Setting size, scale, and orientation
You can try using a simple font such as "Arial", and try if the error still appears, to rule out problems than font.
And avoid using any component if you're having this problem to see if that eliminates the problem.

child elements of MXML class not appearing

I'm working on a simple task/calendar tool where tasks can be added dynamically to a canvas. Here is the main application as defined in Main.mxml, which is essentially just a Canvas and a button for adding a task:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Canvas id="MainCanvas" borderStyle="solid" width="300" height="300">
<mx:Button click="CreateTask();" label="create task" />
</mx:Canvas>
<mx:Script>
<![CDATA[
import Task;
private function CreateTask( ) : void
{
// create the task object
var thisTask:Task = new Task();
// add the task to the canvas
var taskUI : DisplayObject = MainCanvas.addChild( thisTask );
// position the task ui
taskUI.y = 50;
}
]]>
</mx:Script>
</mx:Application>
I want my tasks to be BorderContainers with a label and a button, defined in an external mxml, that can simply be instantiated and added to the canvas in Main.mxml. Here is Tasks.mxml:
<?xml version="1.0" encoding="utf-8"?>
<s:BorderContainer xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:s="library://ns.adobe.com/flex/spark" cornerRadius="10">
<s:layout>
<s:HorizontalLayout/>
</s:layout>
<s:Label id="NameLabel" text="task name" />
<s:Button label="Button 1"/>
</s:BorderContainer>
The problem is that when I add a Task instance to the Canvas, the children (the button and label) don't appear. I tried setting creationPolicy="all" on both the Canvas and the BorderContainer, but it still didn't work. I've read a bunch of posts about people having issues accessing members of their class before the class is fully loading, but all I want to do is SEE that Label and Button show up inside the BorderContainer.
Thanks.
You need to move off of the flex 3 mx namespace to the newer namespace if you want to mix mx and spark controls together.
Here's your main.mxml with the new mx namespace (library://ns.adobe.com/flex/mx), and the fx namespace added to handle the script block:
<?xml version="1.0" encoding="utf-8"?>
<mx: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" >
<fx:Script>
<![CDATA[
import Task;
private function CreateTask( ) : void
{
// create the task object
var thisTask:Task = new Task();
// add the task to the canvas
var taskUI : DisplayObject = MainCanvas.addChild( thisTask );
// position the task ui
taskUI.y = 50;
}
]]>
</fx:Script>
<mx:Canvas id="MainCanvas" borderStyle="solid" width="300" height="300">
<mx:Button click="CreateTask();" label="create task" />
</mx:Canvas>
</mx:Application>
Although as other people have commented, you could just move everything over to spark - if you do that, be sure to change the addChild call to addElement.
It appears that adding spark component to an mx:canvas never triggers the code necessary to create the spark component's children. Here is a workaround for you:
<?xml version = "1.0" encoding = "utf-8"?>
<s:BorderContainer
xmlns:mx = "http://www.adobe.com/2006/mxml"
xmlns:s = "library://ns.adobe.com/flex/spark"
cornerRadius = "10"
creationComplete = "{addElement(poorUseOfContainers)}">
<s:HGroup id = "poorUseOfContainers"
width = "100%" height = "100%">
<s:Label id = "NameLabel"
text = "task name" />
<s:Button label = "Button 1" />
</s:HGroup>
</s:BorderContainer>

how to replace the images in flex 3?

In my flex application, i am maintaining 5 images. When user clicks on 'next' button, it should display one image say 'image1'. If that button clicked again, then image1 should replace with image2 and so on. I am basically following 'image.visible' method. But images are displaying side by side. I think it is not the correct procedure. Any alternative? Thanks in advance
here is my code. I kept all my images and buttons in mx:panel. Even i used x and y positions which are not working.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Panel
title = 'Learn and Test your Knowledge'
height = '80%'
paddingBottom = '10' paddingTop = '10'
paddingLeft = '10' paddingRight = '10'
borderAlpha='0.20' fontFamily="Verdana" fontSize="15" color="#F30C32" backgroundImage="#Embed(source='../images/lad.jpg')" width="413" x="139">
<mx:Script>
<![CDATA[
public function nextEvent():void
{
// here i should write next button code
}
]]>
</mx:Script>
<mx:Image source="../images/image1.jpg" visible="true" id="image1" />
<mx:Image source="../images/image3.jpg" visible="true" id="image2"/>
<mx:Image source="../images/image3.jpg" visible="true" id="image3"/>
<mx:Button id="next" visible="false" click="nextEvent()">
</mx:Button>
The best way is to use only one image component if you are only ever showing one image. You can create an array or vector with the embedded images and reference that to change the source property on the image component. Here is an example: (the code below will work with any layout/container)
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Image id="image" click="imageClick()" source="{new images[0]()}" />
<mx:Script>
<![CDATA[
[Embed(source="assets/1.png")]
private var image1:Class;
[Embed(source="assets/2.png")]
private var image2:Class;
[Embed(source="assets/3.png")]
private var image3:Class;
private var images:Array = [image1, image2, image3];
private var imageIndex:uint = 0;
protected function imageClick():void
{
imageIndex++;
if(imageIndex == images.length) imageIndex = 0;
image.source = new images[imageIndex]();
}
]]>
</mx:Script>
</mx:Canvas>
Specify the x and y position of images as same and play around with their visibility.It ll definitely work.
ViewStack is my option it fits very well in this occasion.
At a time it shows only one component, for next action it will automatically override previous content by its new component.
<mx:ViewStack id="myViewStack" borderStyle="solid" width="100%" height="80%">
<mx:Canvas id="one" click="myViewStack.selectedChild=two;">
<mx:Image source="assets/1.png" />
</mx:Canvas>
<mx:Canvas id="two" click="myViewStack.selectedChild=three;">
<mx:Image source="assets/2.png" />
</mx:Canvas>
<mx:Canvas id="three" click="myViewStack.selectedChild=four;">
<mx:Image source="assets/3.png" />
</mx:Canvas>
<mx:Canvas id="four" click="myViewStack.selectedChild=five;">
<mx:Image source="assets/4.png" />
</mx:Canvas>
<mx:Canvas id="five" click="myViewStack.selectedChild=one;">
<mx:Image source="assets/5.png" />
</mx:Canvas>
</mx:ViewStack>

How content dynamically updated in flex

i need your help about below purposes.
problem-1:In php we can easily move one page to another and easily use different type of function from those pages.In flex3 how i can use different type of .mxml pages like php. Please guide me with tutorials.It will really helpful for me.
problem-2: In same page some content dynamically updated its resource by done one task.How can i do that please guide me.
Rather than treating your Flex application as a series of pages, you may want to consider an all-in-one SWF instead. This greatly reduces navigation time, at the cost of a longer initial download. You can switch among different views using tab pages or view stacks. As far as keeping your functions for each page separate, you can do this by implementing each logical "page" as a separate MXML component. Your top-level application MXML would look something like this:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:my="com.mycompany.myapp"
>
<mx:ViewStack id="pageViewStack" width="100%" height="100%">
<my:MyComponent1 width="100%" height="100%"/>
<my:MyComponent2 width="100%" height="100%"/>
</mx:ViewStack>
</mx:Application>
For your second problem I have 2 files
imageResize.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" viewSourceURL="srcview/index.html">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
private var _imageHolderWidth:Number = 500;
private var _imageHolderHeight:Number = 500;
[Bindable]
private var imageArrayCollection:ArrayCollection = new ArrayCollection();
private function changeSize():void{
this.imageHolder.width = this._imageHolderWidth *(this.widthSlider.value * 0.01);
this.imageHolder.height = this.imageHolder.width;
}
private function addToTileList():void{
var bitmapData : BitmapData = new BitmapData(this.imageHolder.width, this.imageHolder.height );
var m : Matrix = new Matrix();
bitmapData.draw( this.imageHolder, m );
this.imageArrayCollection.addItem({bitmapData: bitmapData, width: this.imageHolder.width, height: this.imageHolder.height});
}
]]>
</mx:Script>
<mx:Image id="imageHolder" source="#Embed('fx.png')" />
<mx:HSlider id="widthSlider" width="400" y="520" maximum="100" value="100" minimum="1" labels="[1%, 50%, 100%]" snapInterval="1" change="{changeSize();}" liveDragging="true" />
<mx:Button label="add to tile" click="{this.addToTileList();}"/>
<mx:TileList x="520" dataProvider="{this.imageArrayCollection}" itemRenderer="TileListRenderer" />
</mx:Application>
second file TileListRenderer.mxml:
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="100" height="140">
<mx:Script>
<![CDATA[
import mx.utils.ObjectUtil;
override public function set data(value:Object):void
{
super.data = value;
}
]]>
</mx:Script>
<mx:VBox horizontalAlign="center">
<mx:Image id="thumbHolder" source="{new Bitmap(data.bitmapData)}" maxWidth="100" maxHeight="100" />
<mx:Label text="{data.width}x{data.height}" />
</mx:VBox>
</mx:Canvas>
Because it is easier to see it with working source (right mouse button to see the source):
blog.arnomanders.nl/upload/imageResize/imageResize.html

How can I drag and drop canvases within a Vbox to re-order?

I'm getting up to speed with Flex and I am looking for any example of implementing a drag and drop re-sort within a vbox container. Basically I have a Vbox that contains a number of canvas's that are full width and 35px high. I want to be able to drag and drop them to re-order within the vbox.
Any help is greatly appreciated - thanks,
b
Have you tried using a mx:List - drag and drop support is already built in and very easy to use - i threw together a sample for you using the dimensions you mentioned:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.events.DragEvent;
import mx.collections.ArrayCollection;
[Bindable]
private var _source:ArrayCollection = new ArrayCollection();
private function init():void{
var n:int = 10;
for(var i:int = 0; i < n; i++){ _source.addItem({value:Math.random()}); }
}
private function handleReorder(event:DragEvent):void{
Alert.show("A change was made!");
}
]]>
</mx:Script>
<mx:List dataProvider="{_source}" width="250" height="500" dragMoveEnabled="true"
dragEnabled="true" dropEnabled="true" dragDrop="handleReorder(event)">
<mx:itemRenderer>
<mx:Component>
<mx:Canvas width="100%" height="35">
<mx:Text text="{data.value}" width="100%" height="100%" selectable="false" />
</mx:Canvas>
</mx:Component>
</mx:itemRenderer>
</mx:List>
</mx:Application>
And there is of course more info here: http://livedocs.adobe.com/flex/3/langref/mx/controls/List.html
good luck!
If I were you, I'd first check the Flex documentation available online. There's this example. You will have to customize this for your list control's itemeditor. There's another example which you should take a look at. If you have a problem let us know.

Resources