`

Flex中支持缩放的TitleWindow

阅读更多
  近日工作中需要用到类似Windows那种罕有最大化、最小化、关闭功能的TitleWindow,而Flex本身并无这个组件(Flex AI有NativeWindow这个组件)。于是上网搜索,发现了MDI,但是感觉代码太多而且代码侵入性很强不便于扩展,其更适合与在一个空间内存在多个Panel的场景,ResizeTitleWindow与ResizeManage更使用于我的应用场景,我最终使用的是ResizeManag这个组件但不幸的是下载下来的资源也是有残缺,心想反正自己也是得做扩展的因而放弃了寻找完全可用版的努力,继而开始研究源代码并进行了相应的修改与扩展。

ResizeWindow.as
package sjd.containers
{
	import flash.events.MouseEvent;
	import flash.geom.Point;
	
	import mx.containers.Form;
	import mx.containers.FormItem;
	import mx.containers.TitleWindow;
	import mx.controls.Button;
	import mx.controls.TextInput;
	import mx.core.Application;
	import mx.events.FlexEvent;
	
	import sjd.utils.CursorUtil;
 
  [Event(name="closeWindow", type="mx.events.FlexEvent")]
  [Event(name="minWindow", type="mx.events.FlexEvent")]
  [Event(name="maxWindow", type="mx.events.FlexEvent")]
     
  /**
   * @class ResizeWindow
   * @brief A TitleWindow with Resize Enabled and Max, Min, Close Button
   * @author Jove
   * @version 1.1
   */
  public class ResizeWindow extends TitleWindow{
   
    private static const SIDE_OTHER:Number = 0;
    private static const SIDE_TOP:Number = 1;
    private static const SIDE_BOTTOM:Number = 2;
    private static const SIDE_LEFT:Number = 4;
    private static const SIDE_RIGHT:Number = 8;
   
    private static var resizeObj:Object;
    private static var mouseState:Number = 0;
    private static var mouseMargin:Number = 10;
   
    [Embed(source="/sjd/assets/verticalSize.gif")]
    private var verticalSize:Class;
    [Embed(source="/sjd/assets/horizontalSize.gif")]
    private var horizontalSize:Class;
    [Embed(source="/sjd/assets/leftObliqueSize.gif")]
    private var leftObliqueSize:Class;
    [Embed(source="/sjd/assets/rightObliqueSize.gif")]
    private var rightObliqueSize:Class;
   
    private var oWidth:Number = 0;
    private var oHeight:Number = 0;
    private var oX:Number = 0;
    private var oY:Number = 0;
    private var oPoint:Point = new Point();
   
    private var _showWindowButtons:Boolean = true;
    private var _windowMinSize:Number = 150;
   
    //private var form:MyForm = new MyForm();
    /**
      * Constructor.
      * Add mouse envent to this window and application.
      * initialize the old positions.
      */
    public function ResizeWindow(){
      super();
      addContent();
      initPosition(this);
      
      this.addEventListener(MouseEvent.MOUSE_MOVE, oMouseMove);
      this.addEventListener(MouseEvent.MOUSE_OUT, oMouseOut);
      this.addEventListener(MouseEvent.MOUSE_DOWN, oMouseDown);
      //this.addEventListener(MouseEvent.MOUSE_UP, oMouseUp);
      this.addEventListener(FlexEvent.CREATION_COMPLETE, addButton);
     
      //Application.application.parent:SystemManager
      Application.application.parent.addEventListener(MouseEvent.MOUSE_UP, oMouseUp);
      Application.application.parent.addEventListener(MouseEvent.MOUSE_MOVE, oResize);
    }
    
    private function addContent():void{
    	var form:Form  = new Form();
    	var formItem1:FormItem = new FormItem();
    	formItem1.label = "事件源";
    	var text:TextInput = new TextInput();
    	formItem1.addChild(text);
    	form.width = 200;
    	form.addChild(formItem1);
    	//form.width = this.width;
    	//form.height = this.height;
    	this.addChild(form);
    	//this.updateDisplayList(100,100);
    }
   
    public function set showWindowButtons(show:Boolean):void{
      _showWindowButtons = show;
      if(titleBar != null){
        addButton(new FlexEvent(""));
      }
    }
   
    public function get showWindowButtons():Boolean{
      return _showWindowButtons;
    }
   
    public function set windowMinSize(size:Number):void{
      if(size > 0){
        _windowMinSize = size;
      }
    }
   
    public function get windowMinSize():Number{
      return _windowMinSize;
    }
   
    private static function initPosition(obj:Object):void{
      obj.oHeight = obj.height;
      obj.oWidth = obj.width;
      obj.oX = obj.x;
      obj.oY = obj.y;
    }
   
    /**
     * Set the first global point that mouse down on the window.
     * @param The MouseEvent.MOUSE_DOWN
     */
    private function oMouseDown(event:MouseEvent):void{
      if(mouseState != SIDE_OTHER){
        resizeObj = event.currentTarget;
        initPosition(resizeObj);
        oPoint.x = resizeObj.mouseX;
        oPoint.y = resizeObj.mouseY;
        oPoint = this.localToGlobal(oPoint);
      }
    }
   
    /**
     * Clear the resizeObj and also set the latest position.
     * @param The MouseEvent.MOUSE_UP
     */
    private function oMouseUp(event:MouseEvent):void{
      if(resizeObj != null){
        initPosition(resizeObj);
      }
      resizeObj = null;
    }
   
    /**
     * Show the mouse arrow when not draging.
     * Call oResize(event) to resize window when mouse is inside the window area.
     * @param The MouseEvent.MOUSE_MOVE
     */
    private function oMouseMove(event:MouseEvent):void{
      if(resizeObj == null){
        var xPosition:Number = Application.application.parent.mouseX;
        var yPosition:Number = Application.application.parent.mouseY;
        if(xPosition >= (this.x + this.width - mouseMargin) && yPosition >= (this.y + this.height - mouseMargin)){
          CursorUtil.changeCursor(leftObliqueSize, -6, -6);
          mouseState = SIDE_RIGHT | SIDE_BOTTOM;
        }else if(xPosition <= (this.x + mouseMargin) && yPosition <= (this.y + mouseMargin)){
          CursorUtil.changeCursor(leftObliqueSize, -6, -6);
          mouseState = SIDE_LEFT | SIDE_TOP;
        }else if(xPosition <= (this.x + mouseMargin) && yPosition >= (this.y + this.height - mouseMargin)){
          CursorUtil.changeCursor(rightObliqueSize, -6, -6);
          mouseState = SIDE_LEFT | SIDE_BOTTOM;
        }else if(xPosition >= (this.x + this.width - mouseMargin) && yPosition <= (this.y + mouseMargin)){
          CursorUtil.changeCursor(rightObliqueSize, -6, -6);
          mouseState = SIDE_RIGHT | SIDE_TOP;
        }else if(xPosition >= (this.x + this.width - mouseMargin)){
          CursorUtil.changeCursor(horizontalSize, -9, -9);
          mouseState = SIDE_RIGHT;  
        }else if(xPosition <= (this.x + mouseMargin)){
          CursorUtil.changeCursor(horizontalSize, -9, -9);
          mouseState = SIDE_LEFT;
        }else if(yPosition >= (this.y + this.height - mouseMargin)){
          CursorUtil.changeCursor(verticalSize, -9, -9);
          mouseState = SIDE_BOTTOM;
        }else if(yPosition <= (this.y + mouseMargin)){
          CursorUtil.changeCursor(verticalSize, -9, -9);
          mouseState = SIDE_TOP;
        }else{
          mouseState = SIDE_OTHER;
          CursorUtil.changeCursor(null, 0, 0);
        }
      }
      //Use SystemManager to listen the mouse reize event, so we needn't handle the event at the current object.
      //oResize(event);
    }
   
    /**
     * Hide the arrow when not draging and moving out the window.
     * @param The MouseEvent.MOUSE_MOVE
     */
    private function oMouseOut(event:MouseEvent):void{
      if(resizeObj == null){
        CursorUtil.changeCursor(null, 0, 0);
      }
    }
   
    /**
     * Resize when the draging window, resizeObj is not null.
     * @param The MouseEvent.MOUSE_MOVE
     */
    private function oResize(event:MouseEvent):void{
      if(resizeObj != null){  
        resizeObj.stopDragging();
        var xPlus:Number = Application.application.parent.mouseX - resizeObj.oPoint.x;
        var yPlus:Number = Application.application.parent.mouseY - resizeObj.oPoint.y;
       switch(mouseState){
         case SIDE_RIGHT | SIDE_BOTTOM:
           resizeObj.width = resizeObj.oWidth + xPlus > _windowMinSize ? resizeObj.oWidth + xPlus : _windowMinSize;
           resizeObj.height = resizeObj.oHeight + yPlus > _windowMinSize ? resizeObj.oHeight + yPlus : _windowMinSize;
           break;
         case SIDE_LEFT | SIDE_TOP:
           resizeObj.x = xPlus < resizeObj.oWidth - _windowMinSize ? resizeObj.oX + xPlus: resizeObj.x;
           resizeObj.y = yPlus < resizeObj.oHeight - _windowMinSize ? resizeObj.oY + yPlus : resizeObj.y;
           resizeObj.width = resizeObj.oWidth - xPlus > _windowMinSize ? resizeObj.oWidth - xPlus : _windowMinSize;
           resizeObj.height = resizeObj.oHeight - yPlus > _windowMinSize ? resizeObj.oHeight - yPlus : _windowMinSize;
           break;
         case SIDE_LEFT | SIDE_BOTTOM:
           resizeObj.x = xPlus < resizeObj.oWidth - _windowMinSize ? resizeObj.oX + xPlus: resizeObj.x;
           resizeObj.width = resizeObj.oWidth - xPlus > _windowMinSize ? resizeObj.oWidth - xPlus : _windowMinSize;
           resizeObj.height = resizeObj.oHeight + yPlus > _windowMinSize ? resizeObj.oHeight + yPlus : _windowMinSize;
           break;
         case SIDE_RIGHT | SIDE_TOP:
           resizeObj.y = yPlus < resizeObj.oHeight - _windowMinSize ? resizeObj.oY + yPlus : resizeObj.y;
           resizeObj.width = resizeObj.oWidth + xPlus > _windowMinSize ? resizeObj.oWidth + xPlus : _windowMinSize;
           resizeObj.height = resizeObj.oHeight - yPlus > _windowMinSize ? resizeObj.oHeight - yPlus : _windowMinSize;
           break;
         case SIDE_RIGHT:
           resizeObj.width = resizeObj.oWidth + xPlus > _windowMinSize ? resizeObj.oWidth + xPlus : _windowMinSize;
           break;
         case SIDE_LEFT:
           resizeObj.x = xPlus < resizeObj.oWidth - _windowMinSize ? resizeObj.oX + xPlus: resizeObj.x;
           resizeObj.width = resizeObj.oWidth - xPlus > _windowMinSize ? resizeObj.oWidth - xPlus : _windowMinSize;
           break;
         case SIDE_BOTTOM:
           resizeObj.height = resizeObj.oHeight + yPlus > _windowMinSize ? resizeObj.oHeight + yPlus : _windowMinSize;
           break;
         case SIDE_TOP:
           resizeObj.y = yPlus < resizeObj.oHeight - _windowMinSize ? resizeObj.oY + yPlus : resizeObj.y;
           resizeObj.height = resizeObj.oHeight - yPlus > _windowMinSize ? resizeObj.oHeight - yPlus : _windowMinSize;
           break;
       }
      }
    }
   
   
    //--------------------------------------------------------------------------
    //
    // Control the window buttons.
    //
    //--------------------------------------------------------------------------
   
    private var windowMinButton:Button;
    private var windowMaxButton:Button;
    private var windowCloseButton:Button;
   
    [Embed(source="/sjd/assets/WindowMinButton.gif")]
    private var windowMinButtonImg:Class;
    [Embed(source="/sjd/assets/WindowMinButton2.gif")]
    private var windowMinButtonImg2:Class;
    [Embed(source="/sjd/assets/WindowMaxButton.gif")]
    private var windowMaxButtonImg:Class;
    [Embed(source="/sjd/assets/WindowMaxButton2.gif")]
    private var windowMaxButtonImg2:Class;
    [Embed(source="/sjd/assets/WindowCloseButton.gif")]
    private var windowCloseButtonImg:Class;
    [Embed(source="/sjd/assets/WindowCloseButton2.gif")]
    private var windowCloseButtonImg2:Class;
   
    /**
     * Add the window buttons and layout them.
     * @param The FlexEvent.CREATION_COMPLETE
     */
    private function addButton(event:FlexEvent):void{
      if(_showWindowButtons){
        if(windowMinButton == null){
          windowMinButton = new Button();
          windowMinButton.width=10;
          windowMinButton.height=10;
          windowMinButton.focusEnabled=false;
          windowMinButton.setStyle("upSkin", windowMinButtonImg);
          windowMinButton.setStyle("overSkin", windowMinButtonImg2);
          windowMinButton.setStyle("downSkin", windowMinButtonImg2);
          windowMinButton.addEventListener(MouseEvent.CLICK, windowMinButton_clickHandler);
          titleBar.addChild(windowMinButton);
        }
        if(windowMaxButton == null){
          windowMaxButton = new Button();
          windowMaxButton.width=10;
          windowMaxButton.height=10;
          windowMaxButton.focusEnabled=false;
          windowMaxButton.setStyle("upSkin", windowMaxButtonImg);
          windowMaxButton.setStyle("overSkin", windowMaxButtonImg2);
          windowMaxButton.setStyle("downSkin", windowMaxButtonImg2);
          windowMaxButton.addEventListener(MouseEvent.CLICK, windowMaxButton_clickHandler);
          titleBar.addChild(windowMaxButton);
        }
        if(windowCloseButton == null){
          windowCloseButton = new Button();
          windowCloseButton.width=10;
          windowCloseButton.height=10;
          windowCloseButton.focusEnabled=false;
          windowCloseButton.setStyle("upSkin", windowCloseButtonImg);
          windowCloseButton.setStyle("overSkin", windowCloseButtonImg2);
          windowCloseButton.setStyle("downSkin", windowCloseButtonImg2);
          windowCloseButton.addEventListener(MouseEvent.CLICK, windowCloseButton_clickHandler);
          titleBar.addChild(windowCloseButton);
        }
        layoutWindowButtons();
      }else{
        titleBar.removeChild(windowMinButton);
        windowMinButton = null;
        titleBar.removeChild(windowMaxButton);
        windowMaxButton = null;
        titleBar.removeChild(windowCloseButton);
        windowCloseButton = null;
      }
    }
   
    private function windowMinButton_clickHandler(event:MouseEvent):void{
      dispatchEvent(new FlexEvent("minWindow"));
    }
   
    private function windowMaxButton_clickHandler(event:MouseEvent):void{
      dispatchEvent(new FlexEvent("maxWindow"));
    }
   
    private function windowCloseButton_clickHandler(event:MouseEvent):void{
      dispatchEvent(new FlexEvent("closeWindow"));
    }
   
    private function layoutWindowButtons():void{
      if(windowMinButton != null){
        windowMinButton.move(titleBar.width - 10 * 3 - 6 - 6 - 6, (titleBar.height - 10) / 2);
      }
      if(windowMaxButton != null){
        windowMaxButton.move(titleBar.width - 10 * 2 - 6 - 6, (titleBar.height - 10) / 2);
      }
      if(windowCloseButton != null){
        windowCloseButton.move(titleBar.width - 10 - 6, (titleBar.height - 10) / 2);
      }
    }
   
    override protected function layoutChrome(unscaledWidth:Number, unscaledHeight:Number):void{
      super.layoutChrome(unscaledWidth, unscaledHeight);
      layoutWindowButtons();
    }
  }
}

一个工具类(可以将其并入到ResizeTitleWindow.as中)
package sjd.utils
{
	import mx.managers.CursorManager;
	import mx.managers.CursorManagerPriority;
	
	/**
	 * @class CursorUtil
	 * @brief Set the cursor image
	 * @author Jove
	 * @version 1.0
	 */
	public class CursorUtil{
		private static var currentType:Class = null;
		
		/**
		 * Remove the current cursor and set an image.
		 * @param type The image class
		 * @param xOffset The xOffset of the cursorimage
		 * @param yOffset The yOffset of the cursor image
		 */
		public static function changeCursor(type:Class, xOffset:Number = 0, yOffset:Number = 0):void{
			if(currentType != type){
				currentType = type;
				CursorManager.removeCursor(CursorManager.currentCursorID);
				if(type != null){
					CursorManager.setCursor(type, CursorManagerPriority.MEDIUM, xOffset, yOffset);
				}
			}
		}
	}

}

一个自定义的视图类:xxxView.mxml,也即使用ResizeWindow的类
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:mywindow="sjd.containers.*">
	
	<mx:Script>
		<![CDATA[
			import mx.controls.TextInput;
			import mx.containers.FormItem;
			import mx.containers.Form;
			import mx.controls.Alert;
			import sjd.containers.ResizeWindow;
			private function initApp():void{
			    var window:ResizeWindow = new ResizeWindow();
			    var form:Form  = new Form();
    	        var formItem1:FormItem = new FormItem();
    			formItem1.label = "事件源";
    			var text:TextInput = new TextInput();
    			formItem1.addChild(text);
    			form.addChild(formItem1);
    			//form.width = window.width * 0.2;
				window.addChild(form);
			}
			//var window:ResizeWindow = new ResizeWindow();
			private function closeWindowHandler():void{
				win.height = 100;
				win.width = 100;
			}
			
			private function minWindowHandler():void{
				win.height = 200;
				win.width = 200;
			}
			
			private function maxWindowHandler():void{
				var window:ResizeWindow = new ResizeWindow();
				win.height = 400;
				win.width = 400;
			}
		]]>
	</mx:Script>
	
	<mywindow:ResizeWindow height="200" width="200" x="100" y="100" id="win"
		 closeWindow="closeWindowHandler()" maxWindow="maxWindowHandler()" minWindow="minWindowHandler()"/>
</mx:Application>


问题: 当向改装后的lsyTitleWindow使用addChild(Flex3)或者addElement(Flex4)方法添加组件时如何控制所添加的控件相对于LsyTitleWindow的位置。 你会发现你预先设置的
我所知道的有两种方式:
第一种(我现在所使用的):
   就是预先在LsyTitleWindow中设置某个空间如Group,然后调整此Group在整个LsyTtileWindow中的位置,并且将其visialbe属性置为false; 当添加新控件时就将新控件放置在Group所在的范围内并同时将Group的visiable属性置为true。
   这种方式我把它称之为黔驴技穷式(当时项目中要使用我就只想到了这种)

第二种:从网上学到的使用UpdateDisplayList
   推荐一个不错的参考资料:
   参考百度文库中的《ActionScript开发高级可视化组件》
文章末尾附上了个人从网上搜索到的一些参考资料,资料中也提供了实现方案,大家若是需要的话就下载自行研究。
MDI组件.rar(googlecode中的flex-lib开源项目)
Jpane.rar
  • mdi.rar (474.6 KB)
  • 下载次数: 149
分享到:
评论
1 楼 hexin46373 2011-09-07  
谢谢博主 整在研究

相关推荐

    flex4.6 可以拉伸的TitleWindow

    flex4.6 可以拉伸的TitleWindow。自由缩放。

    flex TitleWindow 放大、缩小、可缩放 弹出窗口

    在这个主题中,我们将深入探讨如何在Flex中创建一个具有放大、缩小和可缩放功能的TitleWindow弹出窗口。 首先,让我们了解TitleWindow的基本结构。TitleWindow组件包含一个标题栏,可以显示窗口的标题,并提供关闭...

    自定义缩放titlewindow

    前段时间在做flex的一个文档在线浏览时用到了需要TitleWindow的缩放以及最大化、最小化功能,于是自己就查看资料和参考各位大虾的代码,自己实现了下

    实现最大化、最小化、缩放功能的TitleWindow

    一个实现最大化、最小化、缩放功能的TitleWindow,是参照其他大虾的代码,然后自己写的一个TitleWindow,并且限制了TitleWindow的拖动区域。里面提供了一个MyTitleWindow.as和一个使用MyTitleWindow的.mxml的文件...

    Flex详细文档.pdf

    - **Flex与WebService通信**: 实现Flex应用程序与WebService的通信,支持JSON或XML数据交换。 - **Flex与Ajax交互**: 结合Ajax技术,实现异步数据加载和更新。 #### 六、总结 通过以上内容,我们可以看到Flex不仅...

    flex 模仿WINDOWS窗口

    在模仿Windows窗口的过程中,开发者可能会使用ActionScript来处理窗口的动态行为,例如拖动、缩放、打开/关闭事件,以及窗口间的交互逻辑。 5. 定制皮肤:为了使Flex窗口更接近Windows的视觉效果,开发者可能通过...

    TitleWidonw

    TitleWindow是Adobe Flex框架中的一个核心组件,它用于创建具有标题栏、边界和操作按钮(如最大化、最小化、还原和关闭)的可自定义窗口。在Flex4中,TitleWindow进行了重写,以提供更丰富的功能和更好的用户体验。...

    FLEX问题总汇 (总结篇)

    在本文中,我们将深入探讨关于FLEX的一系列常见问题及其解答,这些问题涵盖了FLEX与HTML的集成、系统资源访问、文件操作、数据类型处理、对象访问、界面元素控制、模块通信、编码格式、数据传输、多选功能、图表定制...

    Flex开发实例.pdf

    - Flex支持集成地图服务,如Google Maps API,可以在应用中显示地图并进行交互。 #### 3. **地图使用范围设置** - 可以通过API设置地图的显示范围、缩放级别等参数,以便更好地适应具体的应用场景。 #### 4. **...

    Flex开发实例--学习必备

    - Flex中的 **Form** 组件可以方便地创建表格布局,并且可以轻松管理表单中的输入字段。 - 支持多种输入类型,如文本框、复选框等。 #### 12. 基本组件 - Flex提供了大量的基本UI组件,如按钮、文本框、复选框等。 ...

    FLEX常见问题总汇

    3. **文件操作**:Flex本身不支持文件I/O操作,如果你想对文件进行读写,需要借助Java或其他服务器端语言来完成。 4. **数据类型转换**:当你读取的数据是`Object`类型时,可能需要将其转换为`String`。如果转换有...

    flex 入门实例教程

    - Flex的应用程序可以通过Flash Player或者Adobe AIR进行部署,支持桌面应用和Web应用。 #### 二、MXML与ActionScript概述 - **MXML** 是一种基于XML的语言,用于定义应用程序的界面结构。 - **ActionScript** 是一...

    flex题目大全

    - Flex Builder 4同样支持多种项目类型,包括Flex项目、Flex Mobile项目、Adobe AIR应用程序等。 #### 26. 什么是RSL,如何使用? - **答案**:RSL(Runtime Shared Library)是在运行时按需加载的共享库。使用...

    《Flex 3 组件实例与应用(2009版)》(PDF)

    本书由Dason精心整理于2009年2月,全面覆盖了Flex 3中的各种控件、容器、数据可视化组件以及效果、视图状态和过渡等内容,旨在帮助开发者深入了解并掌握Flex 3的应用技巧。 ### 通用控件(General controls) ####...

    Flex UI组件使用全集

    - **TitleWindow**: 带有标题栏的窗口容器。 - **VBox**: 垂直方向布局的容器。 - **VDivideBox**: 垂直方向可调整大小的容器。 - **ViewStack**: 在多个视图之间切换的容器。 #### Repeatercontrol(重复器组件) ...

Global site tag (gtag.js) - Google Analytics