Group Element not working in adobe flex 3 - actionscript-3

i am trying to create multiple tab with close button in adobe flex 3. for this i have created parent and child object. parent object for tab and child object for close button and place both object in Group container grammatically in function called "addButton()". my code working fine in adobe flex 4.5 but not working in adobe flex 3. due to some reason i have to use adobe flex 3. i have try other container like: HBox, controllbar etc but these are unable to make proper tab view. below is 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="127" minHeight="34" backgroundColor="#F4E8E8">
<s:layout>
<s:FormItemLayout/>
</s:layout>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.graphics.SolidColor;
import spark.components.Button;
import spark.components.Group;
import spark.primitives.Rect;
public function addButton():void {
//Child Object
var myButton:Button = new Button();
myButton.id = "dd";
myButton.label="X";
myButton.width = 40;
myButton.height = 20;
myButton.depth =1;
myButton.x=50;
myButton.setStyle("color",'red');
myButton.addEventListener(MouseEvent.CLICK, btn);
//Parent Object
var lble:Group = new Group();
var solidColor:SolidColor = new SolidColor(0xFF0000);
var rec:Rect = new Rect();
rec.fill = solidColor;
rec.percentWidth = 100;
rec.percentHeight = 100;
lble.width = 127;
lble.height = 34;
lble.depth =0;
lble.addElement(rec);
lble.addEventListener(MouseEvent.CLICK, lable);
lble.addElement(myButton);
myGroup.addElement(lble);
}
private function btn(e:Event):void {
e.stopPropagation();
jj.text = 'Text For Button';
}
private function lable(e:Event):void {
kk.text = "Text For Label";
}
]]>
</fx:Script>
<s:HGroup id="myGroup">
<s:Button width="126" height="34" click="addButton();" label="Click" skinClass="spark.skins.spark.ButtonSkin"/>
</s:HGroup>
<s:Label id="jj" x="14" y="150" width="1200" height="50" backgroundColor="gray" text="Button"/>
<s:Label id="kk" x="14" y="69" width="1200" height="50" backgroundColor="gray" text="Label"/>
</s:Application>
please help me

1) Group Element (container) Not working in Flex 3 :
Definitely it won't work in Flex 3, there is major difference between Flex 3 and Flex 4 or mx(halo) and spark(Gumbo) respectively. You need to have clear understanding of both the things if you want to convert a component from spark to mx or vice versa.
Here is a nice article that explain the
Difference between Flex 3 and Flex 4
2) I am trying to create multiple tab with close button in adobe flex 3:
Since Flex is a 10 years matured framework there are plenty of open source components available out there you don't have to create a component from scratch. But i appreciate your attempt to do it on your own way.
Have a look in to this before you start creating components
Flex 3 Component Life cycle
Flex 4 Component Life cycle and Creating Advanced spark components
Spark Tab with close button
Flex 3 SuperTabNavigator FlexLib component
Flex: How to add a tab close button for TabNavigator component

You can use Box as mx component. Here is what you can do in flex 3:
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import mx.containers.Box;
public function addButton():void {
//Child Object
var myButton:Button = new Button();
myButton.id = "dd";
myButton.label="X";
myButton.width = 40;
myButton.height = 20;
myButton.x=50;
myButton.setStyle("color",'red');
myButton.addEventListener(MouseEvent.CLICK, btn);
//Parent Object
var box:Box = new Box();
box.setStyle("borderThickness", "1");
box.setStyle("borderStyle", "solid");
box.setStyle("borderColor", "black");
box.setStyle("backgroundColor", "0xFF0000");
box.width = 127;
box.height = 34;
box.addEventListener(MouseEvent.CLICK, lable);
box.addChild(myButton);
myHBox.addChild(box);
}
private function btn(e:Event):void {
e.stopPropagation();
jj.text = 'Text For Button';
}
private function lable(e:Event):void {
kk.text = "Text For Label";
}
]]>
</mx:Script>
<mx:HBox id="myHBox">
<mx:Button width="126" height="34" click="{addButton();}" label="Click"/>
</mx:HBox>
<mx:Label id="jj" x="14" y="150" width="1200" height="50" text="Button"/>
<mx:Label id="kk" x="14" y="69" width="1200" height="50" text="Label"/>
</mx:Application>

Related

Dynamically generated MXML data doesn't get rendered

So I have a requirement to display dynamically generated data in the view.
For this, my idea was to create a mxml file and then use it as an object. Fill the data in the ibject and then use addChild to display it. But even after adding all the data. The dynamically generated mxml file doesn't gets displayed.
Code
BuyTogetherGrid.MXML
<?xml version="1.0" encoding="utf-8"?>
<mx:Box xmlns:mx="http://www.adobe.com/2006/mxml" width="80" height="60" xmlns:image="org.commodity.detail.image.*">
<mx:HBox>
<image:ImageBox id="buyTogetherImg"></image:ImageBox>
<mx:VBox id="textInfo">
<mx:Box id="commonNameBox">
<mx:Label id="commonName">
</mx:Label>
</mx:Box>
<mx:Box id="commonPriceBox">
<mx:Label id="commonPrice">
</mx:Label>
</mx:Box>
</mx:VBox>
</mx:HBox>
<mx:Script>
<![CDATA[
public function createGrid():void{
this.buyTogetherImg = new ImageBox();
this.commonName = new Label();
this.commonPrice = new Label();
}
]]>
</mx:Script>
</mx:Box>
This is my MXMl File. My idea was to create an object of this mxml object. Add data to buyTogetherImg, CommonName, CommonPrice and then use addChild
Part where I set the data
<mx:HBox id="buyTogetherBox" width="100%" borderColor="black">
</mx:HBox>
The upper HBox is the container where I will keep all my generated object
var buyTogetherBox : BuyTogetherGrid = new BuyTogetherGrid();
buyTogetherBox.createGrid();
for each(var item:cmListItem in commod.items){
if(item.dataFormat == 2){
buyTogetherBox.buyTogetherImg.imgData = item.value as ImageData;
} else if(item.dataFormat == 0){
buyTogetherBox.commonName.text = item.value.toString();
} else if(item.dataFormat == 3){
buyTogetherBox.commonPrice.text = StringUtil.numToStrPrice(item.value as Number);
}
}
this.buyTogetherBox.addChild(buyTogetherBox);
}
The code check some conditions and add the data. However the buyTogetherBox is not visible. But if I try something like
this.buyTogetherBox.addChild(buyTogetherBox.buyTogetherImg);
then i can see the image in the H:Box.
I am pretty new to Flex. so may be I would have missed something
You are leaving the statically created instances of the label and image control unused and creating new instances instead. Basically, the entire createGrid() function is unnecessary. You already have the controls created in MXML. Just use them with creating new instances.
var grid:BuyTogetherGrid = new BuyTogetherGrid();
grid.addEventListener(FlexEvent.CREATION_COMPLETE, this.grid_creationCompleteHandler);
Elsewhere in the same class...
private function grid_creationCompleteHandler(event:FlexEvent):void
{
// Set your properties here
}
As Pranav said it takes some time to create MXML components and if you try to assess them immediately you will get a null pointer exception because they don't exist yet. A quick and dirty solution is to make public variables in your BuyTogetherGrid.MXML and then bind the text properties to these variables, like
<?xml version="1.0" encoding="utf-8"?>
<mx:Box xmlns:mx="http://www.adobe.com/2006/mxml" width="80" height="60" xmlns:image="org.commodity.detail.image.*">
<fx:Script>
<![CDATA[
[Bindable] public var imageData:ImageData;
[Bindable] public var name:String;
[Bindable] public var price:String;
]]>
</fx:Script>
<mx:HBox>
<image:ImageBox id="buyTogetherImg" imgData={imageData}/>
<mx:VBox id="textInfo">
<mx:Box id="commonNameBox">
<mx:Label id="commonName" text="{name}">
</mx:Label>
</mx:Box>
<mx:Box id="commonPriceBox">
<mx:Label id="commonPrice" text="{price}">
</mx:Label>
</mx:Box>
</mx:VBox>
and then you do
buyTogetherBox.imageData = yourImageData;
buyTogetherBox.name = "Your Name";
buyTogetherBox.imageData = "Your price";
and yes, remove the unnecessary createGrid() method

How do you get rid of the scrollbars in AS3, Feathers. SCROLL_BAR_DISPLAY_MODE_NONE not working

I have a TextArea where I print out lots of stuff. Becuase i print every message on a new line the TextArea needs scrollbars. I want to be able to scroll but i dont wanna see scrollbars. I don't want any scrollbars because they dont fit in with my program and they increase my draw calls.
i tried:
SCROLL_BAR_DISPLAY_MODE_NONE
This got rid of the scrollbars and the scrolling with it. With this i can still scroll, but the TextArea will then only scroll if I add stuff to it. So that's not really working for me.
I just wanna be able to scroll without any(visible) scrollbars.
Here is my TextArea code:
private var Text:TextArea = new TextArea();
Text.y = stage.stageHeight - 355;
Text.height = 340;
Text.width = 1320;
Text.x = 15;
Text.isEditable = false;
Text.hasElasticEdges = true;
Text.text = welcomeText;
set "verticalScrollPolicy" and "horizontalScrollPolicy" to off in your textarea. xou can still scroll using mouse scroller or by arrows, but scrollbars won't be visible. in mxml it looks like this:
<s:TextArea verticalScrollPolicy="off" horizontalScrollPolicy="off"/>
in action script it would look like this:
var text:TextArea = new TextArea();
text.setStyle("verticalScrollPolicy", ScrollPolicy.OFF);
text.setStyle("horizontalScrollPolicy", ScrollPolicy.OFF);
I'm using spark TextArea container. simple app code for tests above:
<?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="onCC()">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<mx:VBox id="container">
<s:Label text="type here:" />
<s:TextArea id="source" width="100" height="50"/>
<s:Label text="and text will appear in this noneditable field below" />
</mx:VBox>
<fx:Script>
<![CDATA[
import spark.events.TextOperationEvent;
import flashx.textLayout.container.ScrollPolicy;
private function onCC():void{
var text:TextArea = new TextArea();
text.width = 100;
text.height = 50;
text.editable = false;
text.setStyle("verticalScrollPolicy", ScrollPolicy.OFF);
text.setStyle("horizontalScrollPolicy", ScrollPolicy.OFF);
source.addEventListener(TextOperationEvent.CHANGE, function(e:Event):void{
text.text = source.text;
});
container.addElement(text);
}
]]>
</fx:Script>
</s:Application>

Dynamically create button in Flex

I have very basic question about Flex SDK, but I didn't find any resources for my problem and honestly don't know if it even possible to do what I want. So here is my question:
I created Flex project with Adobe Flex Builder 4.6. Then I placed the button (let's say it's id is btn1) in main MXML file. I want to create second button dynamically right from the script part of main MXML file. Specifically I want to create it from button click handler of btn1.
Here is my MXML code (it is the only file in project ):
<?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[
protected function btn1_clickHandler(event:MouseEvent):void
{
var btn2:Button = new Button();
btn2.label = "Hello";
btn2.x = 50;
btn2.y = 50;
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Non visual elements -->
</fx:Declarations>
<s:Button id="btn1"
x="10" y="10"
label="Кнопка"
click="btn1_clickHandler(event)"/>
</s:Application>
But when I click btn1 - nothing happens. It is possible that I don't understand something in flex programming paradigm - please point it out for me.
You have to add the button to the view using addElement().
var btn2:Button = new Button();
btn2.label = "Hello";
btn2.x = 50;
btn2.y = 50;
addElement(btn2);

Flex spark list vistual layout control how many items are binded

I have a spark list with custom Itemrenderer.
I use virtuallayout , because I'm binding it with about 500 elements.
I traced the datachange event of the item renderer and I've seen that about 120 items are binded to the list on the first load.
I need to show only 10 items on the stage, so I want to decrease the number of items fetched in the list, is there a property or a function to override to obtain this behaviour?
The code is so simple
<s:List id="thumbnailList" verticalScrollPolicy="off"
useVirtualLayout="true" itemRenderer="ThumbnailItemRenderer" >
<s:layout>
<s:HorizontalLayout gap="10" requestedColumnCount="10" />
</s:layout>
</s:List>
The item renderer
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
autoDrawBackground="false" >
<fx:Script>
override public function set data(value:Object):void{
super.data=value;
if(data !=null){
LoadImg();
}
}
protected function LoadImg():void{
trace(data.pagnum.toString());
var cacheDir:File=null;
cacheDir= Config.DirCache();
var folder:File = new File(cacheDir.nativePath + Config.CATALOG_FOLDER_NAME + Config.selected_catalog_id + "/");
var file:File = new File(folder.nativePath + "/" + data.pagnum.toString() + "_th.jpg");
trace(file.url);
thumbnail.source = file.url;
cacheDir=null;
folder=null;
file=null;
}
</fx:Script>
<s:Image id="thumbnail" top="0" left="0" right="0" bottom="0" scaleMode="letterbox" cacheAsBitmap="true" />
</s:ItemRenderer>
and the binding of the list
thumbnailList.dataProvider= {ArrayCollection with about 480 items}

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);