Flex: Adding Icons to the Panel

I run into this question every so often, so I thought I'd share the solution here. The Panel container looks very much like a window that you'd be able to manipulate, perhaps maximizing or minimizing. This simple example gets you as far as adding a couple of icons and listening for click events. You could do the same thing with a TitleWindow (popup) in order to institute a drag and drop interface.

The code, with comments, follows (or download the zip file below).

The extended Panel container, MyClass.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml">

   <mx:Script>
      <![CDATA[
         import mx.containers.Panel;
         import mx.controls.Image;
         import mx.containers.HBox;
         import flash.events.MouseEvent;
         import mx.controls.Alert;

         // Embed the icon graphics and their rollover states
         [Embed("square_blue.png")]
         private var blueSquare:Class;
         [Embed("square_blue_hi.png")]
         private var blueSquareHi:Class;
         [Embed("square_green.png")]
         private var greenSquare:Class;
         [Embed("square_green_hi.png")]
         private var greenSquareHi:Class;

         // Declare the UI elements which will go into the titleBar
         private var myHbox:HBox;
         private var blue:Image;
         private var blueHi:Image;
         private var green:Image;
         private var greenHi:Image;

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

            // Init blue image, its event handlers and its rollover state
            blue = new Image();
            blue.source = blueSquare;
            blue.width = 18;
            blue.height = 18;
            blue.addEventListener( MouseEvent.CLICK, onBlueClick );
            blue.addEventListener( MouseEvent.MOUSE_OVER, onBlueOver );
            blueHi = new Image();
            blueHi.source = blueSquareHi;
            blueHi.width = 18;
            blueHi.height = 18;
            blueHi.addEventListener( MouseEvent.CLICK, onBlueClick );
            blue.addEventListener( MouseEvent.MOUSE_OUT, onBlueOut );

            // Init green image, its event handlers and its rollover state
            green = new Image();
            green.source = greenSquare;
            green.width = 18;
            green.height = 18;
            green.addEventListener( MouseEvent.CLICK, onGreenClick );
            green.addEventListener( MouseEvent.MOUSE_OVER, onGreenOver );
            greenHi = new Image();
            greenHi.source = greenSquareHi;
            greenHi.width = 18;
            greenHi.height = 18;
            greenHi.addEventListener( MouseEvent.CLICK, onGreenClick );
            green.addEventListener( MouseEvent.MOUSE_OUT, onGreenOut );

            // Create an HBox in which to layout the icons
            myHbox = new HBox( );
            myHbox.addChild( blue );
            myHbox.addChild( green );

            // Add the HBox and the icons to the titleBar display
            titleBar.addChild( myHbox );

         }

         override protected function updateDisplayList (unscaledWidth:Number, unscaledHeight:Number):void
         {
            super.updateDisplayList(unscaledWidth, unscaledHeight);

            // Do this or the HBox won't appear!
            myHbox.setActualSize( myHbox.getExplicitOrMeasuredWidth(),
            myHbox.getExplicitOrMeasuredHeight() );

            // Position the HBox
            var y:int = 4;
            var x:int = this.width - myHbox.width - 12;
            myHbox.move(x, y);
         }

         // Handlers for click and mouseovers
         private function onBlueClick ( event:MouseEvent ):void {
            Alert.show('Blue!', 'You clicked...');
         }
         private function onBlueOver ( event:MouseEvent ):void {
            blue.source = blueSquareHi;
         }
         private function onBlueOut ( event:MouseEvent ):void {
            blue.source = blueSquare;
         }

         private function onGreenClick ( event:MouseEvent ):void {
            Alert.show('Green!', 'You clicked...');
         }
         private function onGreenOver ( event:MouseEvent ):void {
            green.source = greenSquareHi;
         }
         private function onGreenOut ( event:MouseEvent ):void {
            green.source = greenSquare;
         }
      ]]>
   </mx:Script>

</mx:Panel>

Instantiating the new Panel:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
   xmlns:comp="ca.olivermerk.panelicons.view.components.*" >


<comp:MyPanel id="myPanel" title="No Design Skills, Inc." width="80%">
   <mx:Text width="80%" >
      <mx:htmlText>
         <![CDATA[Here's a simple example of adding icons to the panel title. There's also a click handler on each one, as well as a rollover (to keep it sexy;)<br><br>Pretty cool!
         ]]>
      </mx:htmlText>
   </mx:Text>
</comp:MyPanel>

</mx:Application>

A zip file is attached at the very bottom ("Download") with all the code.

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
John's Gravatar Where is the link to the Zip file you reference?
# Posted By John | 6/17/07 2:00 PM
Oliver Merk's Gravatar At the very bottom: "Download"

Cheers,
Oliver
# Posted By Oliver Merk | 6/17/07 3:35 PM
Matt's Gravatar Perfect solution for what I was looking for. I simply needed to put my company logo in the title area of a panel component and was having difficulty getting the final pieces nailed down. This took care of it. Thanks!
# Posted By Matt | 6/20/07 4:22 PM
Sergio Barragan's Gravatar Excelent Component.
I've found one similar, but his code was very complex.
Thanks a lot.!
# Posted By Sergio Barragan | 7/12/07 5:58 PM
Greg's Gravatar Very, very nice! this is perfect!
Thanks A Lot
# Posted By Greg | 8/31/07 3:08 PM
Craig's Gravatar Thanks for nailing this down! Helped me out a great deal!
# Posted By Craig | 11/13/07 11:49 AM
Sreedhar's Gravatar I did't get the download button
# Posted By Sreedhar | 11/28/07 7:42 AM
Boris's Gravatar Thanks a lot, there is a lot of unused space on panel title bar
that can be used
# Posted By Boris | 1/12/08 1:31 PM
pratap's Gravatar Hi, nice component..
can u help me to solve my problem plz..
AM using u r component in my APP.

In main application i imported u r panel and inserted a LIST BOX into it. I need a requirement like.. if i select an item in list box and if click on panel icon(blue), i want that selected item to be removed from the list. I know how to delete item from list box.
Problem is how to access the ICON click event from main applcation at runtime.
Can u give me some idea how to do this??

I think u understand the problem..
plz help me.. thankx in advance..

......Pratap
# Posted By pratap | 2/7/08 12:29 AM
MArcio's Gravatar How to add a Combobox with dataprovider ?
# Posted By MArcio | 8/23/08 3:43 PM
Mark's Gravatar Great Example! Trying to take this one step further. I'm trying to use the title bar somewhat like an <mx:ControlBar /> and have a home link.
So instead of saying Alert("Blue was clicked") how could I change the currentState of the parent application that is using <comp:MyPanel> control?
# Posted By Mark | 10/10/08 3:03 PM
John's Gravatar Hi Guys,

I have made a custom mxml component and its called my panel. The panel is held in a view, however my problem is the first call to the view works fine all the links and everything are correct, however when I do a second call to the same view the old data is in the links, I know i need to invalidate the display some how but I am totally stumpted.

Any suggestions / soultions would be great

thanks in advance

John





This is a typical call to it

<common:customPanel screenID="overviewLinks" linkName="{modelAnnuity.annuityOverviewVO.annuityOwnerAnnuitantPnlTitle}" titleStyleName="txtPanelHead" styleName="pnlContent" verticalGap="0" horizontalAlign="right" width="100%" height="100%" id="owners_Title">


My panel code is this

<?xml version="1.0" encoding="utf-8"?>
<mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml"; creationComplete="updateText()" styleName="pnlContent" titleStyleName="txtPanelHead">

<mx:Script>
<![CDATA[
import mx.controls.Text;
import mx.containers.Panel;
import mx.controls.Image;
import mx.containers.HBox;
import flash.events.MouseEvent;
import mx.controls.Alert;
import com.sunlife.us.workbench.util.common.linkUrlFunction;
import mx.collections.ArrayCollection;

[Bindable]
public var linkName:String = new String();
[Bindable]
public var returnedArray : ArrayCollection = new ArrayCollection();
[Bindable]
public var linkURL:String = new String();
[Bindable]
public var linkImage:String = new String();
[Bindable]
public var visibleImage:Boolean = false;
[Bindable]
public var identify : String = new String();
[Bindable]
public var screenID : String = new String();



private var myHbox:HBox;
private var myText:Text;
private var myImage:Image;

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

linkName = this.linkName;
returnedArray = linkUrlFunction.returnLink(identify,screenID);
linkURL = String(returnedArray.getItemAt(0));
visibleImage = returnedArray.getItemAt(2);
linkImage = this.linkImage;

//create the text object
myText = new Text;
myText.text = this.linkName ;
// Create an HBox in which to layout the icon
myHbox = new HBox( );
myHbox.addChild( myText );
myHbox.styleName="txtPanelHead";


if(visibleImage){
// Init image, its event handlers
myImage = new Image( );
myImage.source = String(returnedArray.getItemAt(1));
myImage.width = 18;
myImage.height = 18;
myImage.buttonMode=true;
myImage.addEventListener(MouseEvent.CLICK, linkHandler);
myHbox.addChild( myImage );
}

// Add the HBox and the icons to the titleBar display
titleBar.addChild( myHbox );

}

override protected function updateDisplayList (unscaledWidth:Number, unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
// Do this or the HBox won't appear!
myHbox.setActualSize( myHbox.getExplicitOrMeasuredWidth(),
myHbox.getExplicitOrMeasuredHeight() );
}


private function linkHandler(event:MouseEvent):void
{
// Open the link in a new window,
navigateToURL(new URLRequest(this.linkURL), '_link')
trace(this.linkURL);
}


private function updateText():void{
//used for delayed rendering
if(linkURL != ""){
this.visibleImage = true;
}
myText.text =this.linkName;










}

]]>
</mx:Script>


</mx:Panel>
# Posted By John | 10/21/08 6:04 AM
FlexBeginner's Gravatar Hi,

Is there a way to make the image thats been added to the panel TitleBar visible and invisible on a button click ?

Thank you in advance
# Posted By FlexBeginner | 12/2/08 10:26 AM
Oliver Merk's Gravatar Sure. In the click event handler, you can get a reference to the item that was clicked and set its visible property to false.

-Oliver
# Posted By Oliver Merk | 12/2/08 10:38 AM
# Posted By gdg54 | 12/16/08 5:32 AM
FreeMind's Gravatar Thanks for the example.
# Posted By FreeMind | 1/19/09 5:28 AM
JK's Gravatar Thanks for the sample. Very useful.
# Posted By JK | 1/22/09 6:05 AM
varma's Gravatar Hi ,

Iam trying to add an bacward image to Windowshade (like an image in the tool bar of Panel ) for panel we say like panel.addChild() so that we can add the image to the tool bar of panel .In the case of WindowShade(FlexLib) can somebody tell me what is it called as .Iam not able to add an image to the WindowShade on the extreme right side like max and min button in Window .there is no proper documentation for it .
# Posted By varma | 2/27/09 3:24 PM
Sauri's Gravatar Great post man... keep up the good work...
# Posted By Sauri | 3/16/09 6:10 AM
BlogCFC was created by Raymond Camden. This blog is running version 5.8.001.