package import mx.controls.Alert; import spark.components.Button; //dispatched when titleBar is click //dispatched when restore button is click /** [SkinPart(required="false")] /** [Bindable] /** /** /** /** //set defaults setStyle("skinClass", MySuperPanelSkin); parallel=new Parallel(); /** /** /** resize.widthTo=restoreRect.width; _move.xTo=restoreRect.x; parallel.play(); maxBtn.visible=maxBtn.enabled=true; dispatchEvent(new MySuperPanelEvent("max")); isMaximized=false; topGroup.addEventListener(MouseEvent.MOUSE_DOWN, topGroupMouseDownHandler); /** parallel.target=this; resize.widthTo=this.parent.width - 2 * maxGap; _move.xTo=this.parent.x + maxGap; parallel.play(); maxBtn.visible=maxBtn.enabled=false; Group(this.parent).setElementIndex(this, Group(this.parent).numChildren - 1); dispatchEvent(new MySuperPanelEvent("max")); isMaximized=true; topGroup.removeEventListener(MouseEvent.MOUSE_DOWN, topGroupMouseDownHandler); /** /** if (this.y <= 0) this.addEventListener(MouseEvent.ROLL_OVER, rollOverHandler); /*if (!restoreRect) /** /** /** /** protected function topGroupDoubleClickHandler(event:MouseEvent):void isMinimized=false; isMaximized=false; maxBtn.visible=maxBtn.enabled=true; topGroup.addEventListener(MouseEvent.MOUSE_DOWN, topGroupMouseDownHandler); this.height=topGroup.height; isMinimized=true; //set minimized state; /** if (instance == topGroup) topGroup.addEventListener(MouseEvent.MOUSE_DOWN, topGroupMouseDownHandler); if (instance == restoreBtn) } /** if (instance == topGroup) if (instance == maxBtn) <?xml version="1.0" encoding="utf-8"?> <!-- ADOBE SYSTEMS INCORPORATED NOTICE: Adobe permits you to use, modify, and distribute this file --> <!--- The default skin class for a Spark Panel container. @see spark.components.Panel @langversion 3.0 <fx:Script fb:purpose="styling"> /** /** /** dropShadow.visible=getStyle("dropShadowVisible"); var cr:Number=getStyle("cornerRadius"); dropShadow.tlRadius=cornerRadius; setPartCornerRadii(topMaskRect, withControls); if (bottomMaskRect) borderStroke.color=getStyle("borderColor"); super.updateDisplayList(unscaledWidth, unscaledHeight); /** private var cornerRadius:Number; <s:states> <!-- drop shadow can't be hittable so it stays sibling of other graphics --> <!-- drop shadow can't be hittable so all other graphics go in this group --> <!-- top group mask --> <!-- bottom group mask --> <!-- layer 1: border --> <!-- layer 2: background fill --> <!-- layer 3: contents --> <!--- @private --> <!-- layer 0: title bar fill --> <!-- layer 1: title bar highlight --> <!-- layer 2: title bar divider --> <!-- layer 3: text --> <s:Button id="maxBtn" <!-- <!--- @private --> <s:Group left="0" <!-- layer 0: control bar divider line --> <!-- layer 1: control bar highlight --> <?xml version="1.0" encoding="utf-8"?> </fx:Declarations>
{
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import mx.core.Container;
import mx.core.IVisualElement;
import mx.core.UIComponent;
import mx.effects.Parallel;
import mx.events.EffectEvent;
import spark.components.Group;
import spark.components.Panel;
import spark.effects.Move;
import spark.effects.Resize;
import spark.effects.easing.Elastic;
import spark.effects.easing.IEaser;
//dispatched when max button is click
[Event(type="MySuperPanelEvent", name="max")]
[Event(type="MySuperPanelEvent", name="min")]
[Event(type="MySuperPanelEvent", name="restore")]
*
* @author jixin_huang
*/
public class MySuperPanel extends Panel
{
[SkinPart(required="false")]
/**
* 最大化按钮
* @default
*/
public var maxBtn:Button;
/**
*
* @default
*/
public var restoreBtn:Button;
[SkinPart(required="false")]
/**
* 标题栏
* @default
*/
public var topGroup:Group;
/**
*
* @default
*/
protected var parallel:Parallel;
/**
*
* @default
*/
protected var resize:Resize;
/**
*
* @default
*/
protected var _move:Move;
*
* @default
*/
protected var restoreRect:Rectangle;
/**
* 最大化边距
* @default
*/
private var _maxGap:Number=5;
*
* @default
*/
protected var flag:Boolean=false;
*
* @default
*/
protected var isMinimized:Boolean=false;
*
* @default
*/
protected var isMaximized:Boolean=false;
*
*/
public function MySuperPanel()
{
//TODO: implement function
super();
resize=new Resize();
_move=new Move();
parallel.addChild(resize);
parallel.addChild(_move);
}
*
* @return
*/
public function get maxGap():Number
{
return _maxGap;
}
*
* @param value
*/
public function set maxGap(value:Number):void
{
_maxGap=value;
}
* 复原
* @param event
*/
protected function restoreBtnClickHandler(event:MouseEvent):void
{
resize.heightTo=restoreRect.height;
_move.yTo=restoreRect.y;
restoreBtn.visible=restoreBtn.enabled=false;
}
* 最大化
* @param event
*/
protected function maxBtnClickHandler(event:MouseEvent):void
{
if (!restoreRect)
{
restoreRect=new Rectangle(x, y, this.width, this.height);
}
parallel.duration=500;
resize.heightTo=this.parent.height - 2 * maxGap;
_move.yTo=this.parent.y + maxGap;
restoreBtn.visible=restoreBtn.enabled=true;
isMinimized=false;
}
*
* @param event
*/
protected function topGroupMouseDownHandler(event:MouseEvent):void
{
topGroup.addEventListener(MouseEvent.MOUSE_UP, topGroupMouseUpHandler);
topGroup.addEventListener(MouseEvent.MOUSE_MOVE, topGroupMouseMoveHandler);
}
*
* @param event
*/
protected function topGroupMouseUpHandler(event:MouseEvent):void
{
topGroup.removeEventListener(MouseEvent.MOUSE_MOVE, topGroupMouseMoveHandler);
this.stopDrag();
{
this.y=-this.height + 4;
this.addEventListener(MouseEvent.ROLL_OUT, rollOutHandler);
}
else
{
this.removeEventListener(MouseEvent.ROLL_OVER, rollOverHandler);
this.removeEventListener(MouseEvent.ROLL_OUT, rollOutHandler);
{
restoreRect=new Rectangle(this.x, this.y, this.width, this.height);
}
else
{
restoreRect.x=this.x;
restoreRect.y=this.y;
}*/
}
}
*
* @param event
*/
protected function topGroupMouseMoveHandler(event:MouseEvent):void
{
this.startDrag();
}
*
* @param event
*/
protected function rollOverHandler(event:MouseEvent):void
{
this.y=-2;
}
*
* @param event
*/
protected function rollOutHandler(event:MouseEvent):void
{
this.y=-this.height + 4;
}
*
* @param event
*/
{
trace(topGroup.height + "");
if (isMinimized)
{
if (restoreRect)
{
this.height=restoreRect.height;
}
}
else if (isMaximized)
{
this.height=restoreRect.height;
this.width=restoreRect.width;
this.x=restoreRect.x;
this.y=restoreRect.y;
restoreBtn.visible=restoreBtn.enabled=false;
}
else
{
if (!restoreRect)
{
restoreRect=new Rectangle(this.x, this.y, this.width, this.height);
}
}
}
* override functions
*/
override protected function partAdded(partName:String, instance:Object):void
{
super.partAdded(partName, instance);
{
topGroup.doubleClickEnabled=true;
topGroup.addEventListener(MouseEvent.DOUBLE_CLICK, topGroupDoubleClickHandler);
}
if (instance == maxBtn)
{
maxBtn.addEventListener(MouseEvent.CLICK, maxBtnClickHandler);
}
{
restoreBtn.addEventListener(MouseEvent.CLICK, restoreBtnClickHandler);
}
*
* @param partName
* @param instance
*/
override protected function partRemoved(partName:String, instance:Object):void
{
super.partRemoved(partName, instance);
{
topGroup.doubleClickEnabled=false;
topGroup.removeEventListener(MouseEvent.DOUBLE_CLICK, topGroupDoubleClickHandler);
}
{
maxBtn.removeEventListener(MouseEvent.CLICK, maxBtnClickHandler);
}
{
maxBtn.removeEventListener(MouseEvent.CLICK, restoreBtnClickHandler);
}
}
}
}
Copyright 2008 Adobe Systems Incorporated
All Rights Reserved.
in accordance with the terms of the license agreement accompanying it.
@playerversion Flash 10
@playerversion AIR 1.5
@productversion Flex 4
-->
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
blendMode="normal"
mouseEnabled="false"
minWidth="131"
minHeight="127"
alpha.disabled="0.5"
alpha.disabledWithControlBar="0.5"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Metadata>[HostComponent("MySuperPanel")]</fx:Metadata>
/* Define the skin elements that should not be colorized.
For panel, border and title background are skinned, but the content area and title text are not. */
static private const exclusions:Array=["background", "titleDisplay", "contentGroup", "controlBarGroup"];
* @private
*/
override public function get colorizeExclusions():Array
{
return exclusions;
}
* @private
*/
override protected function initializationComplete():void
{
useChromeColor=true;
super.initializationComplete();
}
* @private
*/
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
if (getStyle("borderVisible") == true)
{
border.visible=true;
background.left=background.top=background.right=background.bottom=1;
contents.left=contents.top=contents.right=contents.bottom=1;
}
else
{
border.visible=false;
background.left=background.top=background.right=background.bottom=0;
contents.left=contents.top=contents.right=contents.bottom=0;
}
var withControls:Boolean=(currentState == "disabledWithControlBar" || currentState == "normalWithControlBar");
if (cornerRadius != cr)
{
cornerRadius=cr;
dropShadow.trRadius=cornerRadius;
dropShadow.blRadius=cornerRadius;
dropShadow.brRadius=cornerRadius;
setPartCornerRadii(border, withControls);
setPartCornerRadii(background, withControls);
}
setPartCornerRadii(bottomMaskRect, withControls);
borderStroke.alpha=getStyle("borderAlpha");
backgroundFill.color=getStyle("backgroundColor");
backgroundFill.alpha=getStyle("backgroundAlpha");
}
* @private
*/
private function setPartCornerRadii(target:Rect, includeBottom:Boolean):void
{
target.topLeftRadiusX=cornerRadius;
target.topRightRadiusX=cornerRadius;
target.bottomLeftRadiusX=cornerRadius;
target.bottomRightRadiusX=cornerRadius;
}
</fx:Script>
<s:State name="normal"/>
<s:State name="disabled"/>
<s:State name="normalWithControlBar"
stateGroups="withControls"/>
<s:State name="disabledWithControlBar"
stateGroups="withControls"/>
</s:states>
<!--- @private -->
<s:RectangularDropShadow id="dropShadow"
blurX="20"
blurY="20"
alpha="0.32"
distance="11"
angle="90"
color="#000000"
left="0"
top="0"
right="0"
bottom="0"/>
<s:Group left="0"
right="0"
top="0"
bottom="0">
<!--- @private -->
<s:Group left="1"
top="1"
right="1"
bottom="1"
id="topGroupMask">
<!--- @private -->
<s:Rect id="topMaskRect"
left="0"
top="0"
right="0"
bottom="0">
<s:fill>
<s:SolidColor color="0xdae8eb"/>
</s:fill>
</s:Rect>
</s:Group>
<!--- @private -->
<s:Group left="1"
top="1"
right="1"
bottom="1"
id="bottomGroupMask"
includeIn="normalWithControlBar, disabledWithControlBar">
<!--- @private -->
<s:Rect id="bottomMaskRect"
left="0"
top="0"
right="0"
bottom="0">
<s:fill>
<s:SolidColor alpha="0"/>
</s:fill>
</s:Rect>
</s:Group>
<!--- @private -->
<s:Rect id="border"
left="0"
right="0"
top="0"
bottom="0">
<s:stroke>
<!--- @private -->
<s:SolidColorStroke id="borderStroke"
weight="1"/>
</s:stroke>
</s:Rect>
<!--- Defines the appearance of the PanelSkin class's background. -->
<s:Rect id="background"
left="1"
top="1"
right="1"
bottom="1">
<s:fill>
<!--- @private
Defines the PanelSkin class's background fill. The default color is 0xFFFFFF. -->
<s:SolidColor id="backgroundFill"
color="#000000"/>
</s:fill>
</s:Rect>
<!--- Contains the vertical stack of titlebar content and controlbar. -->
<s:Group left="1"
right="1"
top="1"
bottom="1"
id="contents">
<s:layout>
<s:VerticalLayout gap="0"
horizontalAlign="justify"/>
</s:layout>
<s:Group id="topGroup"
mask="{topGroupMask}">
<!--- @private -->
<s:Rect id="tbFill"
left="0"
right="0"
top="0"
bottom="1">
<s:fill>
<s:LinearGradient rotation="90">
<s:GradientEntry color="0xE2E2E2"/>
<s:GradientEntry color="0xD9D9D9"/>
</s:LinearGradient>
</s:fill>
</s:Rect>
<!--- @private -->
<s:Rect id="tbHilite"
left="0"
right="0"
top="0"
bottom="0">
<s:stroke>
<s:LinearGradientStroke rotation="90"
weight="1">
<s:GradientEntry color="0xEAEAEA"/>
<s:GradientEntry color="0xD9D9D9"/>
</s:LinearGradientStroke>
</s:stroke>
</s:Rect>
<!--- @private -->
<s:Rect id="tbDiv"
left="0"
right="0"
height="1"
bottom="0">
<s:fill>
<s:SolidColor color="0xC0C0C0"/>
</s:fill>
</s:Rect>
<!--- @copy spark.components.Panel#titleDisplay -->
<s:Label id="titleDisplay"
maxDisplayedLines="1"
left="9"
right="3"
top="1"
bottom="0"
minHeight="30"
verticalAlign="middle"
fontWeight="bold">
</s:Label>
skinClass="MaxBtnSkin"
verticalCenter="0"
right="4"/>
<s:Button id="restoreBtn"
visible="false"
enabled="false"
skinClass="RestoreBtnSkin"
verticalCenter="0"
right="4"/>
</s:Group>
Note: setting the minimum size to 0 here so that changes to the host component's
size will not be thwarted by this skin part's minimum size. This is a compromise,
more about it here: http://bugs.adobe.com/jira/browse/SDK-21143
-->
<!--- @copy spark.components.SkinnableContainer#contentGroup -->
<s:Group id="contentGroup"
width="100%"
height="100%"
minWidth="0"
minHeight="0">
</s:Group>
<s:Group id="bottomGroup"
minWidth="0"
minHeight="0"
includeIn="normalWithControlBar, disabledWithControlBar">
right="0"
top="0"
bottom="0"
mask="{bottomGroupMask}">
<s:Rect left="0"
right="0"
top="0"
height="1"
alpha="0.22">
<s:fill>
<s:SolidColor color="0x000000"/>
</s:fill>
</s:Rect>
<s:Rect left="0"
right="0"
top="1"
bottom="0">
<s:stroke>
<s:LinearGradientStroke rotation="90"
weight="1">
<s:GradientEntry color="0xE5E5E5"/>
<s:GradientEntry color="0xD8D8D8"/>
</s:LinearGradientStroke>
</s:stroke>
</s:Rect>
<s:Rect left="1"
right="1"
top="2"
bottom="1">
<s:fill>
<s:LinearGradient rotation="90">
<s:GradientEntry color="0xDADADA"/>
<s:GradientEntry color="0xC5C5C5"/>
</s:LinearGradient>
</s:fill>
</s:Rect>
</s:Group>
<!-- layer 3: control bar -->
<!--- @copy spark.components.Panel#controlBarGroup -->
<s:Group id="controlBarGroup"
left="0"
right="0"
top="1"
bottom="1"
minWidth="0"
minHeight="0">
<s:layout>
<s:HorizontalLayout paddingLeft="10"
paddingRight="10"
paddingTop="7"
paddingBottom="7"
gap="10"/>
</s:layout>
</s:Group>
</s:Group>
</s:Group>
</s:Group>
</s:SparkSkin>
<?xml version="1.0" encoding="utf-8"?>
<s:Skin xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:fx="http://ns.adobe.com/mxml/2009">
<fx:Metadata>[HostComponent("spark.components.Button")]</fx:Metadata>
<s:states>
<s:State name="up"/>
<s:State name="over"/>
<s:State name="down"/>
<s:State name="disabled"/>
</s:states>
<s:Path data="M 18.5 16.5 C 18.5 17.605 17.605 18.5 16.5 18.5 L 2.5 18.5 C 1.396 18.5 0.5 17.605 0.5 16.5 L 0.5 2.5 C 0.5 1.396 1.396 0.5 2.5 0.5 L 16.5 0.5 C 17.605 0.5 18.5 1.396 18.5 2.5 L 18.5 16.5 Z"
winding="nonZero"
x="0"
y="0">
<s:stroke.over>
<s:SolidColorStroke caps="none"
joints="miter"
miterLimit="4"
weight="1"/>
</s:stroke.over>
<s:stroke.down>
<s:SolidColorStroke caps="none"
joints="miter"
miterLimit="4"
weight="1"/>
</s:stroke.down>
<s:stroke.disabled>
<s:SolidColorStroke caps="none"
joints="miter"
miterLimit="4"
weight="1"/>
</s:stroke.disabled>
<s:fill>
<s:SolidColor color="0xffffff"
alpha="0"
alpha.over="0.5"/>
</s:fill>
</s:Path>
<s:Rect height="8"
width="10"
x="4"
y="6">
<s:stroke>
<s:SolidColorStroke color="0x012012"
caps="none"
joints="{JointStyle.ROUND}"
miterLimit="4"
weight="1.5"/>
</s:stroke>
</s:Rect>
</s:Skin>
<s:Skin xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:fx="http://ns.adobe.com/mxml/2009">
<fx:Metadata>[HostComponent("spark.components.Button")]</fx:Metadata>
<s:states>
<s:State name="up"/>
<s:State name="over"/>
<s:State name="down"/>
<s:State name="disabled"/>
</s:states>
<s:Path data="M 18.5 16.5 C 18.5 17.605 17.605 18.5 16.5 18.5 L 2.5 18.5 C 1.396 18.5 0.5 17.605 0.5 16.5 L 0.5 2.5 C 0.5 1.396 1.396 0.5 2.5 0.5 L 16.5 0.5 C 17.605 0.5 18.5 1.396 18.5 2.5 L 18.5 16.5 Z"
winding="nonZero"
x="0"
y="0">
<s:stroke.over>
<s:SolidColorStroke caps="none"
joints="miter"
miterLimit="4"
weight="1"/>
</s:stroke.over>
<s:stroke.down>
<s:SolidColorStroke caps="none"
joints="miter"
miterLimit="4"
weight="1"/>
</s:stroke.down>
<s:stroke.disabled>
<s:SolidColorStroke caps="none"
joints="miter"
miterLimit="4"
weight="1"/>
</s:stroke.disabled>
<s:fill>
<s:SolidColor color="0xffffff"
alpha="0"
alpha.over="0.5"/>
</s:fill>
</s:Path>
<s:Rect height="8"
width="8"
x="3"
y="8">
<s:stroke>
<s:SolidColorStroke caps="none"
joints="miter"
miterLimit="4"
weight="2"/>
</s:stroke>
</s:Rect>
<s:Rect height="8"
width="8"
x="8"
y="3">
<s:stroke>
<s:SolidColorStroke caps="none"
joints="miter"
miterLimit="4"
weight="2"/>
</s:stroke>
</s:Rect>
</s:Skin>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
minWidth="955"
minHeight="600"
xmlns:local="*">
<fx:Style>
@namespace s "library://ns.adobe.com/flex/spark";
@namespace mx "library://ns.adobe.com/flex/mx";
@namespace local "*";
s|Application{
background-color:#000000;
}
</fx:Style>
<fx:Declarations>
<!-- 将非可视元素(例如服务、值对象)放在此处 -->
<!--<local:FxWindow x="55"
y="195"
width="330"
height="250">
</local:FxWindow>-->
<local:MySuperPanel title="超级面板"
x="296"
y="55"
width="219"
height="467"
cornerRadius="4"
maxGap="20">
<local:filters>
<s:GlowFilter color="0xaebfed"
blurX="20"
blurY="20"/>
</local:filters>
</local:MySuperPanel>
</s:Application>
编写超级面板
最新推荐文章于 2026-07-02 11:58:26 发布
我们需要有如此功能的面板:可以最小化,可以最大化,可以复原,可以拖拽,类似于QQ的停靠功能。
解决方案:自定义面板添加相应的功能。
难点:在flex4.0当中,怎么在面板头部加上按钮;怎么控制其位置;怎么保存复原信息?做拖拽的时候应该怎么做?
到了flex4.0,不在有titleBar,不再有chrome函数。adobe提供了另外一种思路,利用皮肤来做。编写皮肤类,在头部加上你想要的按钮。在自定义面板的构造函数当中使用setStyle(“skinClass”)方法引入皮肤。复写partAdded和partRemoved函数,其中利用instance检测实例同时在其中加入事件监听等。值得一说的是需要注意到新的元数据标签SkinPart,有了它可以引入皮肤类里面的组件。
面板示例代码如下:
if (instance == restoreBtn)
面板皮肤类的代码如下:
<!-- layer 2: control bar fill -->
最大化按钮的皮肤类如下:
复原按钮的皮肤类如下:
<?xml version="1.0" encoding="utf-8"?>
主应用程序代码:
1429

被折叠的 条评论
为什么被折叠?



