Need Flex Migration Help?
- Adobe ends Flash player support in 2020
- Flex apps will no longer function
- We can help migrate your app
7/25 – I’ve updated this class to now work with the released version of Flex 2. The only changes needed was to replace rerfrences to the currentIcon property (which was protected in the betas, but is a private property in the released version), to instead use the getChildByName method. So, what was
var upAsset:IFlexDisplayObject = btStateUp.currentIcon;
var downAsset:IFlexDisplayObject = btStateDown.currentIcon;
becomes
var upAsset:DisplayObject = btStateUp.getChildByName("upIcon");
var downAsset:DisplayObject = btStateDown.getChildByName("upIcon");
Someone was recently asking on the flex coders list about subclassing Panel to add custom functionality. Below is a class I wrote for an upcoming book, which adds buttons for a Panel to be maximized or restored to normal. Those of you who worked with Flex 1.5, may notice the structure of this was initially based on Christophe’s Pod class. Needless to say, I’ve stripped it down to make it a simpler to follow, and modified it to run in Flex 2.
package views{
import mx.containers.Panel;
import mx.controls.Button;
import flash.events.Event;
import flash.display.DisplayObject;
[Event(name="restore")]
[Event(name="maximize")]
public class MaxRestorePanel extends Panel {
private var state:int = 0;
private var btStateUp: Button;
private var btStateDown: Button;
[Embed("../assets/upArrow.gif")]
private var buttonUpIcon:Class;
[Embed("../assets/downArrow.gif")]
private var buttonDownIcon:Class;
private function setState(state:int):void{
this.state=state;
if (state==0){ // Minimized
this.dispatchEvent(new Event('restore'));
} else {
this.dispatchEvent(new Event('maximize'));
}
}
private function doMaximize(event:Event) :void{
setState(1);
btStateUp.visible = false;
btStateDown.visible = true;
}
private function doRestore(event:Event) :void{
setState(0);
btStateUp.visible = true;
btStateDown.visible = false;
}
protected override function createChildren(): void {
super.createChildren();
btStateUp = new Button();
btStateDown = new Button();
btStateUp.addEventListener("click",doMaximize);
btStateDown.addEventListener("click",doRestore);
btStateUp.setStyle("overIcon",buttonUpIcon);
btStateUp.setStyle("downIcon",buttonUpIcon);
btStateUp.setStyle("upIcon",buttonUpIcon);
btStateDown.setStyle("overIcon",buttonDownIcon);
btStateDown.setStyle("downIcon",buttonDownIcon);
btStateDown.setStyle("upIcon",buttonDownIcon);
btStateUp.visible =true;
btStateDown.visible =false;
rawChildren.addChild(btStateUp);
rawChildren.addChild(btStateDown);
}
protected override function updateDisplayList(unscaledWidth: Number, unscaledHeight:Number):void {
super.updateDisplayList(unscaledWidth, unscaledHeight);
if(unscaledWidth > 0){
this.visible = true;
} else {
this.visible = false
}
var upAsset:DisplayObject = btStateUp.getChildByName("upIcon");
var downAsset:DisplayObject = btStateDown.getChildByName("upIcon");
var margin:int = 4;
btStateUp.setActualSize(upAsset.width+margin, upAsset.height+margin);
btStateDown.setActualSize(downAsset.width+margin, downAsset.height+margin);
var pixelsFromTop:int = 5;
var pixelsFromRight:int = 10;
var buttonWidth:int=btStateUp.width;
var x:Number = unscaledWidth - buttonWidth - pixelsFromRight;
var y:Number = pixelsFromTop;
btStateDown.move(x, y);
btStateUp.move(x, y);
}
}
}
hi
can u give me full example with mxml and other stuff….
Please can u send me. or u can post once again
Thank you,
I can’t get it compiled (out-of-the-box, it’s true) with Flex2. I get 5 errors for now:
E:flextestviewsMaxRestorePanel.as(22): col: 33 Error: Property is read-only.
this.className = “MaxRestorePanel”;
^
E:flextestviewsMaxRestorePanel.as(60): col: 16 Error: Access of undefined property allChildrenLi
st.
allChildrenList.addChild(btStateUp);
^
E:flextestviewsMaxRestorePanel.as(61): col: 16 Error: Access of undefined property allChildrenLi
st.
allChildrenList.addChild(btStateDown);
^
E:flextestviewsMaxRestorePanel.as(71): col: 61 Error: Implicit coercion of a value of type flash
.display:DisplayObject to an unrelated type mx.core:IFlexDisplayObject.
var upAsset:IFlexDisplayObject = btStateUp.getChildByName(“upIcon”);
^
E:flextestviewsMaxRestorePanel.as(72): col: 66 Error: Implicit coercion of a value of type flash
.display:DisplayObject to an unrelated type mx.core:IFlexDisplayObject.
var downAsset:IFlexDisplayObject = btStateDown.getChildByName(“upIcon”);
Evidently I never finished updating the code before, its now current. The comment before the code block was correct, in terms of changing IFlexDisplayObject to DisplayObject, but allChildren has to be changed to rawChildren, and the constructor can be removed, as the className is implicity set.
Sorry for the confusion. I wrote this for the upcoming book, and battled trying to keep all the versions (client projects, book and blog) in sync. Sadly, the code on the blog was lowest on the priority order, as this is the only place I’m not being paid to maintain it 🙂
I got this to work by:
* comment out the this.className line
* remove “allChildrenList” so the line just starts addChild(
* import flash.display.DisplayObject;
* change lines to:
var upAsset:DisplayObject = btStateUp.getChildByName(“upIcon”);
var downAsset:DisplayObject = btStateDown.getChildByName(“upIcon”);
*Find some buttons for up/down arrows, adjust embed pathe accordingly.
Note that this class does not actually maximize or restore the panel, it just adds the toggling image and emits event for its container to use.
I have created a custom panel based on Jeff’s work. Just simply use it in place of your regular panel. If you find any bugs please send me an email jgervin@adhder.com.
// ActionScript file
package components{
import mx.containers.Panel;
import mx.controls.Button;
import flash.events.Event;
import flash.display.DisplayObject;
public class MaxRestorePanel extends Panel {
private var state:int = 0;
private var btStateUp: Button;
private var btStateDown: Button;
private var originalHeight:Number;
private var boolSized:Boolean = false;
private var hdHeight:Number;
private var buttonUpIcon:Class;
private var buttonDownIcon:Class;
private function getSized():void
{
if(boolSized == false){
originalHeight = this.height;
trace(originalHeight);
boolSized = true;
trace(boolSized);
}
}
private function minimizePanel():void {
getSized();
hdHeight = this.getStyle(‘headerHeight’);
this.height = hdHeight + 15;
}
private function restorePanel():void {
this.percentHeight = 100;
}
private function setState(state:int):void{
this.state=state;
if (state==0){ // Minimized
this.dispatchEvent(new Event(‘restore’));
} else {
this.dispatchEvent(new Event(‘minimize’));
}
}
private function doMinimize(event:Event) :void{
setState(1);
btStateUp.visible = false;
btStateDown.visible = true;
minimizePanel();
}
private function doRestore(event:Event) :void{
setState(0);
btStateUp.visible = true;
btStateDown.visible = false;
restorePanel();
}
protected override function createChildren(): void {
super.createChildren();
btStateUp = new Button();
btStateDown = new Button();
btStateUp.addEventListener(“click”,doMinimize);
btStateDown.addEventListener(“click”,doRestore);
btStateUp.setStyle(“overIcon”,buttonUpIcon);
btStateUp.setStyle(“downIcon”,buttonUpIcon);
btStateUp.setStyle(“upIcon”,buttonUpIcon);
btStateDown.setStyle(“overIcon”,buttonDownIcon);
btStateDown.setStyle(“downIcon”,buttonDownIcon);
btStateDown.setStyle(“upIcon”,buttonDownIcon);
btStateUp.visible =true;
btStateDown.visible =false;
rawChildren.addChild(btStateUp);
rawChildren.addChild(btStateDown);
}
protected override function updateDisplayList(unscaledWidth: Number, unscaledHeight:Number):void {
super.updateDisplayList(unscaledWidth, unscaledHeight);
if(unscaledWidth > 0){
this.visible = true;
} else {
this.visible = false
}
var upAsset:DisplayObject = btStateUp.getChildByName(“upIcon”);
var downAsset:DisplayObject = btStateDown.getChildByName(“upIcon”);
var margin:int = 4;
btStateUp.setActualSize(upAsset.width+margin, upAsset.height+margin);
btStateDown.setActualSize(downAsset.width+margin, downAsset.height+margin);
var pixelsFromTop:int = 5;
var pixelsFromRight:int = 10;
var buttonWidth:int=btStateUp.width;
var x:Number = unscaledWidth – buttonWidth – pixelsFromRight;
var y:Number = pixelsFromTop;
btStateDown.move(x, y);
btStateUp.move(x, y);
getSized();
}
}
}
I have developed a similar class called Pod.as but I think the approach is a little different. Might help someone…
http://jwopitz.wordpress.com/2007/03/21/extending-mxpanel-a-new-approach-maybe/
Hi,
Could you please explain to me why the childname is “upIcon” no matter which style “upIcon/icon/overIcon” etc is set?
Thanks,
Ian
Ian –
If you look in the createChildren() method, you will see we are using the same asset, for the upIcon, overIcon and downIcon, so, while we could write extra code to get the current icon, it was not neccessary, as they were all the same, and therefore, it was easiest for this example to just just getChildByName(“upIcon”). If you have a situation where the size of your up, over, down and disabled icons is different, you should indeed be more specific about which you are measuring.
hope this helps