WindowShade and CollapsibleAccordion problems, migrating from Flex3 to Flex4 - apache-flex

I have two problems in my code:
First: is with the WindowShade. I have a WindowShade in my application, and the moment I click to run this everything just hangs up. This was working fine when I was using the Flex3 to compile.
The code looks like:
<mdi_containers:MDIWindow xmlns:mdi_containers="flexlib.mdi.containers.*"
xmlns:flexlib_controls="flexlib.controls.*"
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:containers="flexlib.containers.*"
width="800" layout="absolute"
height="500" title="News Articles"
textAlign="center"
verticalGap="0" horizontalGap="0"
minWidth="800"
minHeight="500">
<mx:Canvas width="100%" styleName="roundedBottomCorner">
<containers:WindowShade id="wshade_fox" top="0" width="100%" opened="false" visible="true"
openIcon="{null}" closeIcon="{null}" paddingTop="0"
headerRenderer="{new ClassFactory(c7.views.components.news.header)}">
<mx:VBox horizontalScrollPolicy="off" width="100%" height="225" verticalGap="0" horizontalGap="0">
</mx:VBox>
</containers:WindowShade>
</mx:Canvas>
Second: The CollapsibleAccordion. I have two canvas inside the CollapsibleAccordion, and everything works fine in Flex4 also, but the only problem, that i am unable to see the label on the Canvas.
The code for this problem is below:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:cal="cal.*"
layout="absolute"
addedToStage="stage_init()"
applicationComplete="init()"
xmlns:geometry="com.degrafa.geometry.*"
xmlns:degrafa="com.degrafa.*"
xmlns:paint="com.degrafa.paint.*"
xmlns:containers="flexlib.containers.*"
xmlns:flexlib_controls="flexlib.controls.*"
xmlns:mdi_containers="flexlib.mdi.containers.*"
xmlns:auto="com.hillelcoren.components.*"
xmlns:local="*" backgroundColor="#f7fafe" backgroundGradientColors="[#f7fafe, #6caaeb]"
xmlns:components="CollapsibleAccordion.*"
xmlns:notifications="c7.views.components.notifications.*"
xmlns:dbview="c7.views.apps.dashboard.*"
modalTransparency="0.8" preloader="c7.views.components.Pre"
modalTransparencyColor="0x000000" verticalScrollPolicy="auto"
backgroundSize="100%"
xmlns:components1="c7.views.components.*"
xmlns:notification="c7.views.components.notification.*"
xmlns:news="c7.views.components.news.*">
<mdi_containers:MDICanvas id="mdic" horizontalScrollPolicy="off" verticalScrollPolicy="off"
visible="{!GlobalModel.getInstance().dashboard_mode}"
minWidth="{top_bar.width}"
width="100%" height="100%" top="{top_bar.height}" backgroundAlpha="0">
<mx:Canvas id="cvs_widget_bar" right="0" top="0" height="100%">
<components:CollapsibleAccordion id="collapsibleAccordion1" height="100%" top="0" right="0"
orientation="left" barSize="30" currentWidth="30" openSize="150"
drawerButtonStyle="drawerButton" closeButtonStyle="drawerCloseRight" accordianStyle="drawerAccordion">
<mx:Canvas width="100%" top="0" right="0" height="100%" label="Widget Bar">
</mx:Canvas>
<mx:Canvas width="100%" height="100%" label="Feedback" icon="{IconUtility.getClass(cvs_comment,'assets/cloud_main/images/article-48x48.png')}"
id="cvs_comment" top="0" right="0">
</mx:Canvas>
</components:CollapsibleAccordion>
</mx:Canvas>

I had simliar problems with WindowShade going from Flex 3 to Flex 4. I had to define a button for the headerClass. Since I had a bunch of WindowShades, I added in my style sheet:
flexlib|WindowShade {
headerClass:ClassReference("mx.controls.Button");
}
Or, if you want when you declare a WindowShade, you can add in your MXML:
headerClass="mx.controls.Buttons"
...so that way your "wshade_fox" declaration looks something like:
<containers:WindowShade id="wshade_fox" top="0" width="100%" opened="false" visible="true"
openIcon="{null}" closeIcon="{null}" paddingTop="0"
headerRenderer="{new ClassFactory(c7.views.components.news.header)}"
headerClass="mx.controls.Button">
Hope that helps the first part of your problem.

Related

panel get unknown width

I have a Hgroup that contains of four panels. Sometimes it happens then when users open it the panls have a unknown width even bigger than the window resolution.
does anyone know what the problem is or how to solve it?
<s:Scroller width="100%" height="100%" >
<s:Group width="100%" height="100%">
<s:VGroup gap="10" width="100%">
<s:TextInput/>
<s:Line width="100%"><s:stroke><s:SolidColorStroke color="#696969"/></s:stroke></s:Line>
<s:HGroup gap="20" width="100%">
<s:Panel width="100%"/>
<s:Panel width="100%"/>
<s:Panel width="100%"/>
<s:Panel width="100%"/>
</s:HGroup>
<s:TextInput/>
</s:VGroup>
</s:Group>
</s:Scroller>
it seems that the User who was testing it was using an older version of the flash player! updating this. fixed the problem.

Why do I have a gap within my TabNavigator?

Apologies for the rookie Q - trying to learn Flex/Actionscript and just having some basic layout issues. (Using FlashBuilder 4, with Flex 4.5 HERO SDK)
I have a TitleWindow, and have embedded a mx:TabNavigator within it.
I have then placed a list within the first tab and set its width/height to 100%
However, there appears to be a gap between the top of the list, and the bottom of the tab menus.
Why is this happening and what is the best way to ensure the top of the list aligns up flush with the top of the VBox?
<s:TitleWindow title="Dekho Resource Center"
id="titleWindow"
close="cancel();"
width="375"
height="500"
backgroundAlpha="0"
cornerRadius="5">
<mx:TabNavigator borderStyle="solid" left="0" top="0" width="100%" height="100%" backgroundAlpha="0" >
<mx:VBox label="Blog Posts"
width="100%"
height="100%">
<s:List labelField="title" id="theList" width="100%" height="100%"
contentBackgroundAlpha="0.7" rollOverColor="#F58B57" selectionColor="#FF7227"
doubleClickEnabled="true" doubleClick="theList_doubleClickHandler(event)">
<mx:AsyncListView list="{getDataResult.lastResult}"/>
</s:List>
</mx:VBox>
<mx:VBox label="Search"
width="100%"
height="100%">
</mx:VBox>
</mx:TabNavigator>
Remove the padding from the TabNavigator:
<mx:TabNavigator paddingTop="0"
paddingLeft="0"
paddingRight="0"
paddingBottom="0">

flex 4 tabbar - disable tab

is there a common way to disable a tab of a spark tabbar component in flex 4? with the mx tabnavigator component you can just disable the content corresponding to the tab and the tab is also disabled then. but doing this with the spark tab bar component disables just the content not the tab.
here is my simple example:
<mx:TabNavigator x="122" y="155" width="200" height="200">
<s:NavigatorContent label="Tab 1" width="100%" height="100%">
<s:Label text="Label1"/>
</s:NavigatorContent>
<s:NavigatorContent label="Tab 2" width="100%" height="100%" enabled="false">
<s:Label text="Label2"/>
</s:NavigatorContent>
<s:NavigatorContent label="Tab 3" width="100%" height="100%">
</s:NavigatorContent>
</mx:TabNavigator>
<s:TabBar x="368.7" y="100.35" dataProvider="{viewstack1}" />
<mx:ViewStack x="364" y="133" id="viewstack1" width="200" height="200">
<s:NavigatorContent label="Tab 1" width="100%" height="100%">
<s:Label text="Label1"/>
</s:NavigatorContent>
<s:NavigatorContent label="Tab 2" width="100%" height="100%" enabled="false">
<s:Label text="Label2"/>
</s:NavigatorContent>
<s:NavigatorContent label="Tab 3" width="100%" height="100%">
<s:Label text="Label3" x="1" y="0"/>
</s:NavigatorContent>
</mx:ViewStack>
many thx,
florian
Addendum:
Literally two minutes after I got back to actually working, I found an "elegant" solution using a skin.
If you apply a custom skinClass to your tab bar you can bind the tab.enabled property just like you'd expect/want.
<fx:Script>
<![CDATA[
[Bindable] private var tab2IsReady:Boolean = false;
private function checkCriteria():void{
tab2IsReady = someOtherThing.isFinished;//Boolean
}
]]>
</fx:Script>
<s:TabBar id="theTabBar"
dataProvider="{viewStack}"
skinClass="skins.CustomTabBarSkin"/>
<mx:ViewStack id="viewStack">
<s:NavigatorContent label="Tab index 0">
<!-- Your first tab's content -->
</s:NavigatorContent>
<s:NavigatorContent label="Tab index 1" enabled="{tab2IsReady}">
<!-- Your second tab's content -->
</s:NavigatorContent>
</mx:ViewStack>
When you type "skinClass" use the auto complete to generate (in FlashBuilder ~4.5+???) the custom skin (named whatever you want).
The code will appear like below (I left out the Script tag).
<?xml version="1.0" encoding="utf-8"?>
<!-- skins/CustomTabBarSkin.mxml
...
Adobe's copyright & doc comments
...
-->
<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"
alpha.disabled="0.5">
<fx:Metadata>
<![CDATA[
/**
* #copy spark.skins.spark.ApplicationSkin#hostComponent
*/
[HostComponent("spark.components.TabBar")]
]]>
</fx:Metadata>
<!-- optional Script tag here -->
<s:states>
<s:State name="normal" />
<s:State name="disabled" />
</s:states>
<!--- #copy spark.components.SkinnableDataContainer#dataGroup -->
<s:DataGroup id="dataGroup" width="100%" height="100%">
<s:layout>
<s:ButtonBarHorizontalLayout gap="-1"/>
</s:layout>
<s:itemRenderer>
<fx:Component>
<s:ButtonBarButton skinClass="spark.skins.spark.TabBarButtonSkin" />
</fx:Component>
</s:itemRenderer>
</s:DataGroup>
</s:Skin>
<!-- End skins/CustomTabBarSkin.mxml -->
Change:
<fx:Component>
<s:ButtonBarButton skinClass="spark.skins.spark.TabBarButtonSkin" />
</fx:Component>
To:
<fx:Component>
<s:ButtonBarButton skinClass="spark.skins.spark.TabBarButtonSkin"
enabled="{data.enabled}" />
</fx:Component>
Then any <s:NavigatorContent/> in the ViewStack with its enabled property set or bound will do exactly what you expect
(be enabled when true, & disabled when false).
One solution to try would be to use mx:VBox components instead of s:NavigatorContent.
From http://blog.flexexamples.com/2007/08/25/enabling-and-disabling-specific-tabs-in-a-tabbar-control/ :
<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2007/08/25/enabling-and-disabling-specific-tabs-in-a-tabbar-control/ -->
<mx:Application name="TabBar_enabled_test"
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical"
verticalAlign="middle"
backgroundColor="white">
<mx:ApplicationControlBar dock="true">
<mx:CheckBox id="tabBarEnabled"
label="TabBar.enabled"
selected="true"
width="25%" />
<mx:CheckBox id="tab1Enabled"
label="Tab1.enabled"
selected="true"
width="25%" />
<mx:CheckBox id="tab2Enabled"
label="Tab2.enabled"
selected="true"
width="25%" />
<mx:CheckBox id="tab3Enabled"
label="Tab3.enabled"
selected="true"
width="25%" />
</mx:ApplicationControlBar>
<mx:VBox verticalGap="0">
<mx:TabBar id="tabBar"
width="400"
dataProvider="{viewStack}"
enabled="{tabBarEnabled.selected}" />
<mx:ViewStack id="viewStack" width="400" height="100">
<mx:VBox id="tab1"
label="Tab1"
backgroundColor="haloGreen"
enabled="{tab1Enabled.selected}">
<mx:Label text="Label 1" />
</mx:VBox>
<mx:VBox id="tab2"
label="Tab2"
backgroundColor="haloBlue"
enabled="{tab2Enabled.selected}">
<mx:Label text="Label 2" />
</mx:VBox>
<mx:VBox id="tab3"
label="Tab3"
backgroundColor="haloOrange"
enabled="{tab3Enabled.selected}">
<mx:Label text="Label 3" />
</mx:VBox>
</mx:ViewStack>
</mx:VBox>
</mx:Application>
For those who want an working answer for Flex 4.5 (probably Flex 4 also). I finally figured out a solution. It feels like a hack to me, but Adobe's not answering the call and it's working for me. Here's a simplified example.
<!-- component that has the the TabBar in it... -->
<fx:Script>
<![CDATA[
//imports here
import mx.core.UIComponent;
//imports
private function setTabEnabled(index:int,enabled:Boolean):void{
var theTab:UIComponent = theTabBar.dataGroup.getElementAt(index) as UIComponent;
if(theTab){theTab.enabled = enabled;}
}
]]>
</fx:Script>
<s:TabBar id="theTabBar"
dataProvider="{viewStack}"/>
<mx:ViewStack id="viewStack">
<s:NavigatorContent label="0th Tab">
<!-- ...Content -->
</s:NavigatorContent>
<s:NavigatorContent label="1st Tab">
<!-- ...Content -->
</s:NavigatorContent>
<s:NavigatorContent label="2nd Tab">
<!-- ...Content -->
</s:NavigatorContent>
</mx:ViewStack>
<!-- rest of the component that has the the TabBar in it... -->
Then you just call setTabEnabled(theTabIndex,trueFalse) in an event handler related to whatever decides why the tab is, or isn't, enabled.
I should extend the TabBar to support this, but I've already spent enough time trying to figure it out.
Happy Coding =D

Flex Question: Can I use a ComboBox in Flex to change a view stack?

I am trying to use a combobox in flex with an array to change to a canvas in a view stack.
Can I do this with some custom action script? The UI I am designing could really benefit form this.
Here's a little demo app that demonstrates what you are trying to do:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
<mx:Script>
<![CDATA[
import mx.core.Container;
private function onComboBoxChange():void
{
stackNav.selectedChild = this[comboNav.selectedItem];
}
]]>
</mx:Script>
<mx:ComboBox id="comboNav" dataProvider="{['canvas1','canvas2']}" change="onComboBoxChange()"/>
<mx:ViewStack id="stackNav" width="400" height="300">
<mx:Canvas id="canvas1" width="100%" height="100%">
<mx:Label text="Hello" horizontalCenter="0" verticalCenter="0"/>
</mx:Canvas>
<mx:Canvas id="canvas2" width="100%" height="100%">
<mx:Label text="World!" horizontalCenter="0" verticalCenter="0"/>
</mx:Canvas>
</mx:ViewStack>
</mx:Application>
You can change the logic in onComboBoxChange() to use selectedIndex as well:
stackNav.selectedIndex = comboNav.selectedIndex;
Or you can bind the selectedIndex of the viewStack to the selectedIndex property of the combo:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
<mx:ComboBox id="comboNav" dataProvider="{['canvas1','canvas2']}"/>
<mx:ViewStack id="stackNav" width="400" height="300"
selectedIndex="{comboNav.selectedIndex}">
<mx:Canvas id="canvas1" width="100%" height="100%">
<mx:Label text="Hello" horizontalCenter="0" verticalCenter="0"/>
</mx:Canvas>
<mx:Canvas id="canvas2" width="100%" height="100%">
<mx:Label text="World!" horizontalCenter="0" verticalCenter="0"/>
</mx:Canvas>
</mx:ViewStack>
</mx:Application>
You can use this solution, but be warned that you can not pike a word with space
(try to change "canvas1" to "canvas 1") and you will see:
[Bindable] private var models:Array = ["tasks","users","bugs"];
public function changeViewStackModel():void {
//this.modelViewStack.selectedChild=users; //works
//this.modelViewStack.selectedChild="users"; //does not work
//this.modelViewStack.selectedChild=this.modelsCombo.selectedItem; //does not work
switch(modelsCombo.selectedItem) {
case "tasks": modelViewStack.selectedChild=tasks; break;
case "users": modelViewStack.selectedChild=users; break;
case "bugs": modelViewStack.selectedChild=bugs; break;
}
}
MXML code:
<mx:ComboBox id="modelsCombo" dataProvider="{models}" selectedIndex="0"
change="changeViewStackModel()"/>
<mx:ViewStack x="29.25" y="55" id="modelViewStack" width="90%" height="200">
<mx:Canvas id="tasks" label="Tasks"><mx:Label text="Tasks stack view!!"/>
</mx:Canvas>
<mx:Canvas id="users" label="Users"><mx:Label text="Users stack view!!"/>
</mx:Canvas>
<mx:Canvas id="bugs" label="Bugs"><mx:Label text="Bugs stack view!!"/>
</mx:Canvas>
</mx:ViewStack>

Flex: Call function from included component

This is similar to my previous posting. But this time I want to call a function that exists on the main mxml page.
This is my main mxml page:
main.mxml
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:ns1="*">
<mx:Script>
<![CDATA[
public function changeText(currentText:String):void{
switch (currentText){
case "changeText":
lblOne.text = "More Text";
}
}
]]>
</mx:Script>
<mx:HBox x="137.5" y="10" width="100%" height="100%">
<ns1:menu id="buttons"> </ns1:menu>
</mx:HBox>
<mx:Canvas x="137" y="88" width="408.5" height="200">
<mx:HBox x="0" y="10" width="388.5" height="190">
<mx:Panel width="388" height="179" layout="absolute">
<mx:Label x="10" y="10" text="Some Text" visible="{buttons.showLabel}" id="lblOne"/>
</mx:Panel>
</mx:HBox>
</mx:Canvas>
</mx:Application>
Here is my included page:
menu.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="300">
<mx:Script>
<![CDATA[
[Bindable] public var showLabel:Boolean = true;
]]>
</mx:Script>
<mx:MenuBar width="380" height="58"></mx:MenuBar>
<mx:Button x="10" y="10" width="80" label="Show" id="btnOne" click="this.showLabel=true;" />
<mx:Button x="94" y="10" width="80" label="Hide" id="btnTwo" click="this.showLabel=false;"/>
<mx:Button x="181" y="10" width="80" label="Run Function" id="btnThree" click="{changeText('changeText')}"/>
</mx:Canvas>
How do I call the changeText function from the button on menu.mxml?
Add this to menu:
<mx:Metadata>
[Event(name="buttonClicked", type="flash.events.Event")]
</mx:Metadata>
<mx:Button x="10" y="10" width="80" label="Show" id="btnOne" click="this.showLabel=true;dispatchEvent(new Event("buttonClicked"));"/>
Change main to:
<ns1:menu id="buttons" buttonClicked="changeText("Your Text");">
I couldn't tell where current text is coming from but if it is from menu you may have to build your own custom flex event or create a common variable for the two parts to access. The first is usually preferred.
P.S. The event metadata thing could also be achieved by adding the event listener when the creation of the application completes. You would add to main:
buttons.addEventListener("buttonClicked",changeText("Your Text"));
there is a simpler way, just use parentDocument.
Change this:
<mx:Button x="181" y="10" width="80" label="Run Function" id="btnThree" click="{changeText('changeText')}"/>
to:
<mx:Button x="181" y="10" width="80" label="Run Function" id="btnThree" click="{parentDocument*.changeText('changeText')}"/>**

Resources