Je voulais quelque chose de simple : un seul coin de redimensionnemt (bas droite), que le Panel puisse être redimensionnable ou pas, fermable ou pas, afin de pouvoir tester si l'on peut le fermer (typiquement pour valider une modification).

Voici le code :

La classe ResizePanel.as

package com.phiphou.components
{
import flash.events.MouseEvent;
import flash.geom.Point;
import mx.events.FlexEvent;
import mx.controls.Button;
import mx.containers.Panel;
import mx.core.Application;
import mx.managers.CursorManager;
import mx.managers.CursorManagerPriority;
 
[Event(name="closePanel", type="mx.events.FlexEvent")]
	
public class ResizePanel extends Panel{
		
[Embed(source="/assets/CloseButton.gif")]
public static const CLOSE_BUTTON:Class;
[Embed(source="/assets/CloseButtonOver.gif")]
public static const CLOSE_BUTTON_OVER:Class;
[Embed(source="/assets/handcursor.gif")]
public static const LEFT_OBLIQUE_SIZE:Class;
 
public static const SIDE_OTHER:Number = 0;
public static const SIDE_BOTTOM:Number = 1;
public static const SIDE_RIGHT:Number = 2;
		
private static var resizeObj:Object;
private static var mouseState:Number = 0;
		
private var pWidth:Number = 0;
private var pHeight:Number = 0;
private var pX:Number = 0;
private var pY:Number = 0;
private var pPoint:Point = new Point();
		
private var _showPanelButtons:Boolean = false;		
private var _panelMinSize:Number = 50;
private var _panelMaxSize:Number = 250;	
public var closable:Boolean = true;
public var resizable:Boolean = true;
		
public function ResizePanel(){	
	super();
	initPosition(this);
			
	this.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
	this.addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
	this.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
	this.addEventListener(FlexEvent.CREATION_COMPLETE, addButton);
			
	Application.application.parent.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
	Application.application.parent.addEventListener(MouseEvent.MOUSE_MOVE, onResize);	
}
		
	private function initPosition(obj:Object):void{	
		obj.pHeight = obj.height;
		obj.pWidth = obj.width;
		obj.pX = obj.x;
		obj.pY = obj.y;	
	}
		
	private function onMouseOut(event:MouseEvent):void{
		if(resizeObj == null){
		CursorManager.removeAllCursors();
		}	
	}
		
	private function onMouseDown(event:MouseEvent):void{
		if(mouseState != SIDE_OTHER){
			resizeObj = event.currentTarget;
			initPosition(resizeObj);
			pPoint.x = resizeObj.mouseX;
			pPoint.y = resizeObj.mouseY;
			pPoint = this.localToGlobal(pPoint);
		}
	}
		
		
	private function onMouseUp(event:MouseEvent):void{
		if(resizeObj != null){
			initPosition(resizeObj);
		}
		resizeObj = null;
                CursorManager.removeAllCursors();
	}
		
		
	private function onMouseMove(event:MouseEvent):void{
			
		if(resizeObj == null && resizable){
			var xPosition:Number = Application.application.parent.mouseX;
			var yPosition:Number = Application.application.parent.mouseY;
			if(xPosition >= (this.x + this.width - this.borderMetrics.right) 
                           && yPosition >= (this.y + this.height - this.borderMetrics.right)){
				CursorManager.setCursor(LEFT_OBLIQUE_SIZE, CursorManagerPriority.MEDIUM, -5, -5);
				mouseState = SIDE_RIGHT | SIDE_BOTTOM;
			}else{
				mouseState = SIDE_OTHER;
				CursorManager.removeAllCursors();
			}
		}
	}
		
		
	private function onResize(event:MouseEvent):void{
		if(resizeObj != null){	
			resizeObj.stopDragging();
			var xOffset:Number = Application.application.parent.mouseX - resizeObj.pPoint.x;
			var yOffset:Number = Application.application.parent.mouseY - resizeObj.pPoint.y;
 
			if(mouseState == (SIDE_RIGHT | SIDE_BOTTOM)){
			    	
			    	if(resizeObj.pWidth + xOffset <= _panelMinSize){
			    		resizeObj.width = _panelMinSize;
			    	} else if(resizeObj.pWidth + xOffset >= _panelMaxSize){
			    		resizeObj.width = _panelMaxSize;
			    	} else {
			    		resizeObj.width = resizeObj.pWidth + xOffset;
			    	}
			   
			   		if(resizeObj.pHeight + yOffset <= _panelMinSize){
			    		resizeObj.height = _panelMinSize;
			    	} else if(resizeObj.pHeight + yOffset >= _panelMaxSize){
			    		resizeObj.height = _panelMaxSize;
			    	} else {
			    		resizeObj.height = resizeObj.pHeight + yOffset;
			    	}
			}
			   
		}
	}
		
	private var PanelCloseButton:Button;
		
	public function set showPanelButtons(show:Boolean):void{
		_showPanelButtons = show;
		if(titleBar != null){
			addButton(new FlexEvent(""));
		}
	}
		
	public function get showPanelButtons():Boolean{
		return _showPanelButtons;
	}
		
	public function set panelMinSize(size:Number):void{
		if(size > 0){
			_panelMinSize = size;
			}
	}
		
	public function get panelMinSize():Number{
		return _panelMinSize;
	}
		
	public function set panelMaxSize(size:Number):void{
		if(size > 0){
			_panelMaxSize = size;
		}
	}
		
	public function get panelMaxSize():Number{
		return _panelMaxSize;
	}
		
	private function addButton(event:FlexEvent):void{
		if(_showPanelButtons){
			if(panelCloseButton == null){
				panelCloseButton = new Button();
				panelCloseButton.width=10;
				panelCloseButton.height=10;
				panelCloseButton.focusEnabled=false;
				panelCloseButton.setStyle("upSkin", CLOSE_BUTTON);
				panelCloseButton.setStyle("overSkin", CLOSE_BUTTON_OVER);
				panelCloseButton.setStyle("downSkin", CLOSE_BUTTON_OVER);
				panelCloseButton.addEventListener(MouseEvent.CLICK, windowCloseButton_clickHandler);
				titleBar.addChild(panelCloseButton);
		} 
		layoutPanelButtons();
		}else{	
		        titleBar.removeChild(panelCloseButton);
		        panelCloseButton = null;	
		}
	}
		
	private function panelCloseButton_clickHandler(event:MouseEvent):void{
		if(closable){
		dispatchEvent(new FlexEvent("closePanel"));
		}
	}
		
	private function layoutPanelButtons():void{
			
		if(panelCloseButton != null){
			panelCloseButton.move(titleBar.width - 10 - 6, (titleBar.height - 10) / 2);
		} 
	}
		
	override protected function layoutChrome(unscaledWidth:Number, unscaledHeight:Number):void{
		super.layoutChrome(unscaledWidth, unscaledHeight);
		layoutPanelButtons();	
		}
	}
}

Et l'exemple :

Main.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
	layout="absolute" creationComplete="popupPanel();"
	width="350" height="300">
<mx:Script>
<![CDATA[
	import com.phiphou.components.ResizePanel;
	import mx.events.FlexEvent;
	import mx.managers.PopUpManager;
		
	[Bindable]
	public var pop:test;
		
	public function popupPanel():void{
			
	pop = test(PopUpManager.createPopUp(this, test, false));
			
	pop.y = 75;
	pop.x = 15;
	pop.width = 150;
	pop.height = 150;
			
	pop.panelMinSize = 100;
	pop.panelMaxSize = 200;
	pop.showPanelButtons = true;
	pop.addEventListener("closePanel", closePanel);
	}
		
	private function closePanel(event:FlexEvent):void{
		PopUpManager.removePopUp(ResizePanel(event.currentTarget));
		pop = null;
	}
]]>
</mx:Script>
<mx:CheckBox
	x="15" y="15" id="toggle_closable" 
	label="{this.toggle_closable.selected ? 'Fermeture impossible (pour test)':'Fermeture possible'}"
	click="this.toggle_closable.selected ? this.pop.closable=false:this.pop.closable=true"/>
<mx:CheckBox
	x="15" y="45" id="toggle_resizable"
	label="{this.toggle_resizable.selected ? 'Resize impossible':'Resize possible'}"
	click="this.toggle_resizable.selected ? this.pop.resizable=false:this.pop.resizable=true"/>
<mx:Button x="216" y="15" label="Rouvrir le panel" click="popupPanel()" visible="{this.pop==null}"/>
</mx:Application>

et le fichier test.mxml

<?xml version="1.0" encoding="utf-8"?>
<ResizePanel xmlns="com.phiphou.components.*" xmlns:mx="http://www.adobe.com/2006/mxml"
width="400" height="300" layout="absolute" title="Un panel resizable">
<mx:DataGrid left="10" right="10" bottom="10" top="10">
	<mx:columns>
		<mx:DataGridColumn headerText="A" />
		<mx:DataGridColumn headerText="B" />
		<mx:DataGridColumn headerText="C" />
	</mx:columns>
</mx:DataGrid>
</ResizePanel>

Ce qui nous donne :

;

Et voilà :)