28
Aug
08

Flex Resizable Panel Component

The following component extends the Panel class, adds a functionality so that it can resizable.

The Component ResizablePabel overrides the createChildren() method to add a button at the bottom – right corner of the panel using rawChildren property, so that user can resize the panel using the mouse. Using the various MouseEvent and listeners, component resizes the height and width of the panel.

Here is the sample code to use it:


<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" xmlns:com="*" xmlns:flexScript="flexScript.*">
    <flexScript:ResizablePanel title="Resize Me !!" x="73"
    y="110" width="258" height="213"/>
</mx:Application>

Here is the component source code:


package flexScript
{
    import flash.events.MouseEvent;

    import mx.containers.Panel;
    import mx.controls.Button;

    public class ResizablePanel extends Panel
    {
        private var resizer:Button = new Button();

        public function ResizablePanel()
        {
            super();
            resizer.addEventListener(MouseEvent.MOUSE_DOWN, resizeDown);
        }
        override protected function createChildren():void{
            resizer.height=10;
            resizer.width = 10;
            super.createChildren();
            rawChildren.addChild(resizer);
        }
        override protected function updateDisplayList(w:Number, h:Number):void{
            super.updateDisplayList(w,h);
            resizer.y = h - resizer.height;
            resizer.x = w - resizer.width;
        }
        private function resizeDown(e:MouseEvent):void{
            stage.addEventListener(MouseEvent.MOUSE_MOVE, scalePanel);
            stage.addEventListener(MouseEvent.MOUSE_UP, stopScale);
        }
        private function scalePanel(e:MouseEvent):void{
            if((stage.mouseX - x)>50)
                width = (stage.mouseX-x);
            if((stage.mouseY-y)>50)
                height = (stage.mouseY-y);   
        }
        private function stopScale(e:MouseEvent):void{
            stage.removeEventListener(MouseEvent.MOUSE_MOVE, scalePanel);
            stage.removeEventListener(MouseEvent.MOUSE_UP, stopScale);
        }
    }
}

The component can be extended to add more functionalities.


5 Responses to “Flex Resizable Panel Component”


  1. 1 Stephen Stulov
    September 26, 2008 at 6:54 am

    inside createChildren() method you should check whether the component is already created and added with addChild() call.

    override protected function createChildren():void
    {
    super.createChildren();
    if( resizer == null )
    {
    resizer = new Button();
    resizer.height=10;
    resizer.width = 10;
    rawChildren.addChild(resizer);
    }
    }

    Since createChildren() method is called every time the panel is added. Your method is good. But if you will removeChild() your panel, and then addChild() it again – createChildren() method will be called again, and button is reattached.

  2. 2 Shrikant Patil
    September 26, 2008 at 11:53 am

    Yes that is important thing. Thanks for commenting on it. We become perfect if we share! Thanks again.

  3. September 4, 2009 at 3:30 pm

    Shrikant,

    Great simple component – was almost exactly what I was looking for! However to achieve the functionality my project requires, I made a few minor tweaks.

    Firstly, I implemented Stephen Stulov’s suggestion about checking the existence of the resizer button in createChildren() so as to prevent duplicate creation of the resize button.

    Secondly, I changed the resize method to obey the minWidth/minHeight & maxWidth/maxHeight properties. Nothin’ fancy, just additional constraint checking.

    Thirdly, added a resize corner/handle icon (made a transparent PNG from the corner handle of Safari). You’ll need to create & correctly embed your handle image you want one.

    Code:

    package flexscript {

    import flash.events.MouseEvent;

    import mx.containers.Panel;
    import mx.controls.Button;
    import mx.managers.CursorManager;

    public class ResizablePanel extends Panel {

    [Embed(source="../../../../../assets/imgs/resize_handle.png")] public var resizeIcon:Class;

    private var resizer:Button;

    public function ResizablePanel() {
    super();
    }

    override protected function createChildren():void {
    super.createChildren();

    if (resizer == null) {
    resizer = new Button();
    resizer.width = resizer.height = 14;
    resizer.setStyle(“cornerRadius”, 0);
    resizer.setStyle(“icon”, resizeIcon);

    rawChildren.addChild(resizer);
    resizer.addEventListener(MouseEvent.MOUSE_DOWN, resizeDown);
    }
    }

    override protected function updateDisplayList(w:Number, h:Number):void {
    super.updateDisplayList(w, h);
    resizer.x = w – resizer.width;
    resizer.y = h – resizer.height;
    }

    private function resizeDown(e:MouseEvent):void {
    stage.addEventListener(MouseEvent.MOUSE_MOVE, scalePanel);
    stage.addEventListener(MouseEvent.MOUSE_UP, stopScale);
    }

    private function scalePanel(e:MouseEvent):void {
    if ((stage.mouseX – x) > minWidth
    && (stage.mouseX – x) minHeight
    && (stage.mouseY – y) < maxHeight) {
    height = (stage.mouseY – y);
    }
    }

    private function stopScale(e:MouseEvent):void {
    stage.removeEventListener(MouseEvent.MOUSE_MOVE, scalePanel);
    stage.removeEventListener(MouseEvent.MOUSE_UP, stopScale);
    }
    }
    }

    • 4 Shrikant Patil
      September 7, 2009 at 4:36 am

      Thanks rkdd,
      Thanks lot for additions for this component, which gives perfect meaning for this component. :)

      • September 8, 2009 at 2:17 pm

        No problem.

        I noticed my copy/paste seems to have been messed up a little… here’s what the scalePanel function should be:

        private function scalePanel(e:MouseEvent):void {
        if ((stage.mouseX – x) > minWidth
        && (stage.mouseX – x) minHeight
        && (stage.mouseY – y) < maxHeight) {
        height = (stage.mouseY – y);
        }
        }


Leave a Reply