Flex panel with Maximize, Restore capability

November 18, 2008


Bookmark and Share var addthis_pub = ‘prosenjit23′;

Recently I have been working with Adobe Flex 3 for a project of mine. Flex offers a lot of UI components out-of-the-box that can be used as is. One of them is the Panel control. The Panel is essentially a container to house other components like data grids, etc. Panels are useful when creating dashboard applications. Unfortunately Flex does not offer inbuilt maximize or restore functions on the Panel controls. Rather it is left to the developers to devise their own  mechanisms. Long story short, I had a need for it and Flex did not offer it. And so I started scouring the net for samples. There were loads of good ones but their implementations were much too complicated for my needs. Reluctantly I started working on my own prototype.

<pre style="text-align:justify;"><?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
	width="598" height="620">
	<mx:Script>
		<![CDATA[
			import mx.core.UIComponent;
			import mx.managers.SystemManager;
			import mx.controls.Alert;
			import mx.collections.ArrayCollection;
			import mx.managers.PopUpManager;
			import mx.containers.TitleWindow;
			import mx.core.IFlexDisplayObject;
			import mx.containers.Panel;

			// Button constants
			private static const _RESTORE_LABEL_:String = "Restore";
			private static const _MAXIMIZE_LABEL_:String = "Maximize";

			[Bindable]
			private var currWidth:int; // Stores the current width of the panel to be resized
			[Bindable]
			private var currHeight:int; // Stores the current height of the panel to be resized
			[Bindable]
			private var currTop:int; // Stores the current y coordinate of the panel to be resized
			[Bindable]
			private var currLeft:int; // Stores the current x coordinate of the panel to be resized
			[Bindable]
			private var isMaximized:Boolean = false; // Stores the current state of the panel as a boolean
			[Bindable]
			private var currIndex:int; // Stores the current index of the panel to be maximized

			/**
			 * This function orchestrates what method
			 * is called on the button click event depending on
			 * its label value.
			 */
			private function maxRestore(thePanel:Panel, minRestorBtn:Button):void
			{
				if(minRestorBtn.label == _RESTORE_LABEL_)
					restore(thePanel, minRestorBtn);
				else if(minRestorBtn.label == _MAXIMIZE_LABEL_)
					maximize(thePanel, minRestorBtn);
			}

			/**
			 * This method maximizes the specified panel to occupy the
			 * whole displayed screen area. This method can be tuned to
			 * occupy the area of its parent component rather than the parent
			 * application.
			 */
			private function maximize(thePanel:Panel, minRestorBtn:Button):void
			{
				if(!isMaximized)
				{
					// Save previous position info
					currWidth = thePanel.width;
					currHeight = thePanel.height;
					currTop = thePanel.y;
					currLeft = thePanel.x;
					currIndex = thePanel.parentApplication.getChildIndex(thePanel);

					// Set the maximized flag to true
					isMaximized = true;

					// Set current info
					thePanel.width=this.width;
					thePanel.height = this.height;
					thePanel.x = 0;
					thePanel.y = 0;

					var parentApp:UIComponent = thePanel.parentApplication as UIComponent;
					parentApp.removeChildAt(currIndex);
					parentApp.addChild(thePanel);

					// Set the button properties
					minRestorBtn.label = _RESTORE_LABEL_;
				}
			}

			/**
			 * This method restores the panel to its original location
			 * and size on the screen.
			 */
			private function restore(thePanel:Panel,minRestorBtn:Button):void
			{
				if(isMaximized)
				{
					var parentApp:UIComponent = thePanel.parentApplication as UIComponent;
					// Set the maximized flag to false
					isMaximized = false;

					// Set the button properties
					minRestorBtn.label = _MAXIMIZE_LABEL_;

					// Restore the original size and location information
					thePanel.width = currWidth;
					thePanel.height = currHeight;
					thePanel.x = currLeft;
					thePanel.y = currTop;

					// Now relocate the panel to its original position
					// in the child stack.
					parentApp.setChildIndex(thePanel,currIndex);
				}
			}
		]]>
	</mx:Script>

    <mx:Resize id="resize" /> <!-- This helps in the resize effect -->
    <mx:Move id="moveEffect" /> <!-- This helps in the move effect -->

	<mx:Panel id="upperPanel" x="47.5" y="35" width="500" height="142" layout="absolute"
		resizeEffect="{resize}"
		moveEffect="{moveEffect}" backgroundAlpha="1.0"
		borderAlpha="1.0" title="Top Panel">
		<mx:TextInput x="136" y="19"/>
		<mx:Button x="304" y="19" label="Button"/>
		<mx:ControlBar width="100%" alpha="1.0">
            <mx:Spacer width="100%" alpha="1.0"/>
            <mx:Button id="upperPanelMaxBtn" label="{_MAXIMIZE_LABEL_}" click="maxRestore(upperPanel, upperPanelMaxBtn)"/>
        </mx:ControlBar>
	</mx:Panel>
	<!-- This panel has the capability to maximize and restore -->
	<mx:Panel id="maxminPanel" name="maxminPanel" x="47.5" y="195" width="500" height="184"
		layout="absolute" resizeEffect="{resize}"
		moveEffect="{moveEffect}" backgroundAlpha="1.0"
		borderAlpha="1.0">
		 <mx:title>Middle Panel</mx:title>
		 <mx:DataGrid top="10" right="10" bottom="10" left="10">
		 	 <mx:columns>
		 	 	 <mx:DataGridColumn headerText="Column 1" dataField="col1"/>
		 	 	 <mx:DataGridColumn headerText="Column 2" dataField="col2"/>
		 	 	 <mx:DataGridColumn headerText="Column 3" dataField="col3"/>
		 	 </mx:columns>
		 </mx:DataGrid>
		 <mx:ControlBar width="100%" alpha="1.0">
            <mx:Spacer width="100%" alpha="1.0"/>
            <mx:Button id="maxminPanelMaxBtn" label="{_MAXIMIZE_LABEL_}" click="maxRestore(maxminPanel, maxminPanelMaxBtn)"/>
        </mx:ControlBar>
	</mx:Panel>
	<mx:Panel id="lowerPanel" x="47.5" y="403" width="500" height="197" layout="absolute"
		resizeEffect="{resize}"
		moveEffect="{moveEffect}" backgroundAlpha="1.0"
		borderAlpha="1.0" title="Bottom Panel">
		<mx:TextInput x="104" y="35"/>
		<mx:ControlBar width="100%" alpha="1.0">
            <mx:Spacer width="100%" alpha="1.0"/>
            <mx:Button id="lowerPanelMaxBtn" label="{_MAXIMIZE_LABEL_}" click="maxRestore(lowerPanel, lowerPanelMaxBtn)"/>
        </mx:ControlBar>
	</mx:Panel>
</mx:Application></pre>

This is, like I said, just a prototype. The MXML file contains a couple of methods that take in the Panel controls as parameters and work their magic. For production use, I would surely extend the Panel control to create a custom one and wire it up with the necessary behavior. I would have loved to upload my SWF file to this blog but unfortunately WordPress does not permit that (for some ridiculous reason).

The moment a UI library offers widgets like panels and windows it becomes quite obvious that people would want to have minimize, maximize, restore and resize capabilities on them (and no the resize and move effects do not help much since they do not manipulate the z-ordering of components).Unfortunately Adobe does not think it is necessary. Personally I think the guys at Adobe are being extremely lazy about this. Of course there is always an excuse of being busy doing bigger and better things. Well so much for making lives easier for developers.


Bookmark and Share var addthis_pub = ‘prosenjit23′;

Entry Filed under: adobe flash, adobe flex, enterprise technology, flash, flex, rich internet application. Tags: , , , , , , , , , , , , , , , , , .

6 Comments Add your own

  • 1. oldmonk  |  December 5, 2008 at 9:29 pm

    seems to work very well with absolute layout but not verywell with automatic horizontal/vertical layout.

    Reply
  • 2. varun  |  December 31, 2008 at 12:35 am

    Thank you for sharing this component… I’m really looking for this effect… :)

    Reply
  • 3. John Gag  |  February 3, 2009 at 8:06 pm

    Thanks, gonna give it a look.

    Reply
  • 4. Rohit  |  September 29, 2009 at 1:20 pm

    Can you make this example work if you replace the with and with so that it can be used in other components also.

    Reply
  • 5. Rohit  |  September 29, 2009 at 1:21 pm

    Can you make this example work if you replace the Application tag with and Panel tag so that it can be used in other components also.

    Reply
  • 6. Online Stock Trading  |  September 30, 2009 at 3:10 am

    Hey, I read a lot of blogs on a daily basis and for the most part, people lack substance but, I just wanted to make a quick comment to say GREAT blog!…..I”ll be checking in on a regularly now….Keep up the good work! :)

    Reply

Leave a Comment

hidden

Some HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <pre> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Trackback this post  |  Subscribe to the comments via RSS Feed


Express your opinion

I am on LinkedIn

View Prosenjit Bhattacharyya's profile on LinkedIn

Blogroll

Recent Posts

Top Posts

My Posts

Blog Stats

My Categories

apple app store future technology google google chrome google phone iphone iphone 3g ipod Kubuntu laptop Linux mac book macbook air mac book pro macbook touch mac os mbp microsoft mozilla new laptop notebook open source operating system palm smart phone Ubuntu Uncategorized web browser windows

My Tags

adobe android android market apple apple iphone apple iphone 3g app store call drop chrome firefox flex g1 google google android google chrome google phone iphone iphone 3g iphone 3g problem ipod javascript kde Kubuntu laptop lawsuit Linux mac macbook macbook pro mac os microsoft mozilla new apple laptops new macbook new macbook pro notebook open source palm psystar silverlight smart phone t-mobile g1 Ubuntu web browser windows