blogjava-凯发k8网页登录

blogjava-凯发k8网页登录http://www.blogjava.net/usherlight/category/18755.html天平山上白云泉,云自无心水自闲。何必奔冲山下去,更添波浪向人间!zh-cnfri, 24 aug 2007 14:14:38 gmtfri, 24 aug 2007 14:14:38 gmt60viewstack的大小问题http://www.blogjava.net/usherlight/archive/2007/08/24/139173.html云自无心水自闲云自无心水自闲fri, 24 aug 2007 12:26:00 gmthttp://www.blogjava.net/usherlight/archive/2007/08/24/139173.htmlhttp://www.blogjava.net/usherlight/comments/139173.htmlhttp://www.blogjava.net/usherlight/archive/2007/08/24/139173.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/139173.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/139173.html
viewstack的大小是由其子组件的大小决定的,而viewstack并不会在改变活动子组件的时候自动resize。
只有使用以下方法来控制viewstack的大小。
1. 使用相同的固定值明确指定所有子组件的大小
2. 使用相同的比例值指定所有子组件的大小
3. 将viewstack的width和height的值设置为一个固定或者值。

上述3种方法是adobe官方文档提供的。但是这3种方法不能解决viewstack子组件大小不一致,viewstack不能自动调整的问题。
我最后是使用actionscript动态解决的。
在更换viewstack的active child之间,首先设置viewstack的大小。


       
       

public function changechild() : void {
        appstack.width = 200;
        appstack.height = 200;
        appstack.selectchild = v1;
}

我错了,使用viewstack的resizetocontent是最好的解决办法。



云自无心水自闲 2007-08-24 20:26
]]>
flex中使用模块module的例子http://www.blogjava.net/usherlight/archive/2007/04/28/114300.html云自无心水自闲云自无心水自闲sat, 28 apr 2007 04:38:00 gmthttp://www.blogjava.net/usherlight/archive/2007/04/28/114300.htmlhttp://www.blogjava.net/usherlight/comments/114300.htmlhttp://www.blogjava.net/usherlight/archive/2007/04/28/114300.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/114300.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/114300.html来加载模块

xml version="1.0"?>

<mx:application xmlns:mx="http://www.adobe.com/2006/mxml" viewsourceurl="srcview/index.html">

    
<mx:panel
    title
="module example"
    height
="90%"
    width
="90%"
    paddingtop
="10"
    paddingleft
="10"
    paddingright
="10"
    paddingbottom
="10"
    
>
    
    
<mx:label width="100%" color="blue"
    text
="select the tabs to change the panel."/>
    
    
<mx:tabnavigator id="tn"
    width
="100%"
    height
="100%"
    creationpolicy
="auto"
    
>
    
        
<mx:vbox id="vb1" label="column chart module">
        
            
<mx:label id="l1" text="columnchartmodule.swf"/>
            
<mx:moduleloader url="columnchartmodule.swf"/>
        
        
mx:vbox>
        
        
<mx:vbox id="vb2" label="pie chart module">
        
            
<mx:label id="l2" text="piehchartmodule.swf"/>
            
<mx:moduleloader url="piechartmodule.swf"/>
        
        
mx:vbox>
        
        
<mx:vbox id="vb3" label="line chart module">
        
            
<mx:label id="l3" text="linehchartmodule.swf"/>
            
<mx:moduleloader url="linechartmodule.swf"/>
        
        
mx:vbox>
    
    
mx:tabnavigator>
    
mx:panel>

mx:application>


在这个应用中主要是一个tagnavigator, 里面有三个标签页. 每个标签页加载一个模块.
下面是其中一个模块的代码:


xml version="1.0"?>

<mx:module xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%" >

    
<mx:script>[cdata[
    
        
import mx.collections.arraycollection;
        [bindable]
        
public var expenses:arraycollection = new arraycollection([
        
{month:"jan", profit:2000, expenses:1500},
        
{month:"feb", profit:1000, expenses:200},
        
{month:"mar", profit:1500, expenses:500}
        ]);
        
    ]]
>mx:script>
    
    
<mx:columnchart id="mychart" dataprovider="{expenses}">
    
        
<mx:horizontalaxis>
        
            
<mx:categoryaxis
            dataprovider
="{expenses}"
            categoryfield
="month"
            
/>
            
        
mx:horizontalaxis>
        
        
<mx:series>
        
            
<mx:columnseries
            xfield
="month"
            yfield
="profit"
            displayname
="profit"
            
/>
            
            
<mx:columnseries
            xfield
="month"
            yfield
="expenses"
            displayname
="expenses"
            
/>
            
        
mx:series>
    
    
mx:columnchart>
    
    
<mx:legend dataprovider="{mychart}"/>
    
mx:module>


最后, 应用和三个模块一共会生成4个swf. 一般来说, 应用使用延迟加载策略. 也就是说, 如果你打开应用后, 从来都不使用其中的某个模块, 那个这个模块永远不会被加载. 这次做的好处是, 加快了第一次打开应用的速度, 但随之而来的缺点就是, 第一次打开使用某个功能, 需要加载模块时, 会需要一点等待的时间.

云自无心水自闲 2007-04-28 12:38
]]>
amfphp 1.9 beta 介绍http://www.blogjava.net/usherlight/archive/2007/04/21/112449.html云自无心水自闲云自无心水自闲sat, 21 apr 2007 08:06:00 gmthttp://www.blogjava.net/usherlight/archive/2007/04/21/112449.htmlhttp://www.blogjava.net/usherlight/comments/112449.htmlhttp://www.blogjava.net/usherlight/archive/2007/04/21/112449.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/112449.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/112449.html 

新特性
1. 支持amf3, 这一点无疑是激动人心的.
2. 支持json, 除了gateway.php外, 增加了json.php, 让你的服务能够使用json.
有两个例子:


3. 一个新的service browser
4. 在php端, 不再需要写 $this->methodtable 这个东东了. 在amfphp 1.9 中 所有的方法默认为可以远程访问,除非方法名是以下划线开始 或者 方法是 private 的(只有 php5 支持) 。

 



云自无心水自闲 2007-04-21 16:06
]]>
flex应用启动背后的故事http://www.blogjava.net/usherlight/archive/2007/04/17/111365.html云自无心水自闲云自无心水自闲tue, 17 apr 2007 09:47:00 gmthttp://www.blogjava.net/usherlight/archive/2007/04/17/111365.htmlhttp://www.blogjava.net/usherlight/comments/111365.htmlhttp://www.blogjava.net/usherlight/archive/2007/04/17/111365.html#feedback1http://www.blogjava.net/usherlight/comments/commentrss/111365.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/111365.html首先介绍一下systemmanager. systemmanager是flex应用的主控者, 它控制着应用窗口, application实例, 弹出窗口, cursors, 并管理着applicationdomain中的类. systemmanager是flashplayer实例化的第一个类, 它存储了主应用窗口的大小和位置信息, 保存其子组件比如:浮动弹出窗口和模态窗口的痕迹. 通过systemmanager可以获得内嵌字体,样式和document对象.
自定义的可视化组件(uicomponent的子类)只有在调用过addchild()后, 才会有一个systemmanager赋给他们, 之前是null. 所以在自定义可视化组件的构造函数中不要使用systemmanager.

通常, application对象创建时, 发生如下事件:
1. 实例化application对象
2. 初始化application.systemmanager
3. application在初始化过程之前, 派发预初始化事件.
4. 调用createchild(). 此时, 所有应用组件被创建, 所有组件的createchild()被调用.
5. application派发初始化事件, 表明所有的组件初始化完毕.
6. 派发creationcomplete事件
7. application对象添加到显示列表中
8. 派发applicationcomplete事件

大多数情况下, 我们使用来创建application对象, 但如果使用actionscript来创建的话, 那么建议不要在application的构造函数中创建组件, 推荐在cratechildren函数中, 主要是从性能方面考虑.

flash包含的是一个时间线上的多个帧, 而flex的swf只包含2个帧. systemmanager, preloader, downloadprogressbar和少量工具类都在第一帧, 剩下的包括应用代码/ 内嵌资源全都在第二帧中. 当flash player下载下载swf时, 只要接收到第一帧内足够的数据, 就会实例化systemmanager, 由它来创建preloader, 然后创建downloadprogressbar, 这两个对象会察看剩余字节的传输过程. 当第一帧的所有字节传输完毕后, systemmanager发送enterframe到第二帧, 然后是其他事件. 最后application对象派发applicationcomplete事件.



云自无心水自闲 2007-04-17 17:47
]]>
flex中一个动态修改tree节点标签的例子http://www.blogjava.net/usherlight/archive/2007/04/15/110820.html云自无心水自闲云自无心水自闲sun, 15 apr 2007 12:50:00 gmthttp://www.blogjava.net/usherlight/archive/2007/04/15/110820.htmlhttp://www.blogjava.net/usherlight/comments/110820.htmlhttp://www.blogjava.net/usherlight/archive/2007/04/15/110820.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/110820.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/110820.html一个动态修改tree节点标签的例子
xml version="1.0" encoding="utf-8"?>
<mx:application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"  horizontalalign="left"
    creationcomplete
="initapp()">
<mx:script>[cdata[
  [bindable]
public var _xmldata:xml;
  [bindable]
private var _xmlcur:xml;
 
  
private function initapp():void
  {
    
//set the test data
    _xmldata =
      
<node label="mail box">
        
<node label="inbox"/>
        
<node label="deleted mail"/>
        
<node label="personal"/>
        
<node label="professional"/>
        
<node label="spam"/>
        
<node label="sent"/>
      
node>                                             

    mytree.selecteditem 
= mytree.dataprovider[0];        //select the first node
    calllater(expandtreenode, [mytree.selecteditem]);    //use calllater to expand that node
  }//initapp
 
  
private function expandtreenode(myxmlnode:xml):void{
    mytree.expandchildrenof(myxmlnode,
true);              //expand the node
    _xmlcur = xml(mytree.selecteditem);                   //set the bindable variable
  }
 
  
private function ochangetree(oevent:event):void
  {
    _xmlcur 
= xml(oevent.target.selecteditem);            //set the bindable variable
  }//
 
  
private function updatenode(oevent:event):void
  {
    var xmlselected:xml 
= xml(mytree.selecteditem)        //get a reference to the selected node
    xmlselected.@label = tilabel.text;                    //set the label attribute
  }//updatenode
   
    
]]
>mx:script> 
  
<mx:label text="update selected node label" />
  
<mx:textinput id="tilabel" text="{_xmlcur.@label}" change="updatenode(event)" />
  
<mx:hbox>
    
<mx:tree id="mytree" width="200" height="200" labelfield="@label"
        showroot
="true"
        dataprovider
="{_xmldata}"
        change
="ochangetree(event)" />
 
<mx:datagrid id="dg" dataprovider="{_xmldata.node}"  >
    
<mx:columns>
      
<mx:array>
        
<mx:datagridcolumn headertext="name" datafield="@label"  />
       
mx:array>
    
mx:columns>
  
mx:datagrid>
  
<mx:label text="{_xmlcur.@label}" />
  
mx:hbox>
      
mx:application>



应用中主要包含4个组件, 一个textinput, 一个tree, 一个datagrid, 一个label
1. 先看tree, tree使用_xmldata作为数据源, 定义一个change事件处理函数, 将当前节点存储到_xmlcur变量中.
2. textinput的数据源就是_xmlcur的label属性, 也就是tree当前节点的标签. 他也定义了一个change事件处理函数, 在textinput中的文本改变时, 将新的文本赋值给tree当前节点的标签, 也就是改变当前tree节点的标签值. 值得注意的是赋值并不是直接给tree中或者节点中的某个属性, 而是通过修改数据源xml的值来改变的.
3. datagrid的使用显示了如何在datagrid中展示xml的技巧.
4. 最后一个label只是简单的显示当前节点的标签值, 与textinput的文本保持同步



云自无心水自闲 2007-04-15 20:50
]]>
整理了一下cairngorm 2.1版本的新变化http://www.blogjava.net/usherlight/archive/2007/04/10/109722.html云自无心水自闲云自无心水自闲tue, 10 apr 2007 11:48:00 gmthttp://www.blogjava.net/usherlight/archive/2007/04/10/109722.htmlhttp://www.blogjava.net/usherlight/comments/109722.htmlhttp://www.blogjava.net/usherlight/archive/2007/04/10/109722.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/109722.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/109722.html1. caringorm2.1的包中增加了完整的asdoc文档

2. 增加locale,错误信息的国际化的处理。
添加了一个properties文件,
添加了com.adobe.cairngorm.cairngormmessagecodes和com.adobe.cairngorm.cairngormerror两个类,其中cairngormmessagecodes用于定义properties文件中的键值,而cairngormerror封装了error,在应用执行的过程不再直接抛出error,而抛出一个cairngormerror,其中带一个参数就是messagecode,根据messagecode到properties文件中取出相应的消息。

3. 在business中,添加了一个iservicelocator的接口
servicelocator实现iservicelocator接口,相比以前增加了以下几个方法:
a、public function getremoteobject( serviceid : string ) : remoteobject // return the remoteobject for the given service id.
b、public function gethttpservice( serviceid : string ) : httpservice // return the httpservice for the given service id.
c、public function getwebservice( serviceid : string ) : webservice // return the webservice for the given service id.
d、public function getconsumer( serviceid : string ) : consumer  // return the message consumer for the given service id.
e、public function getproducer( serviceid : string ) : producer // return the message produce for the given service id.
f、public function getdataservice( serviceid : string ) : dataservice // return the dataservice for the given service id.
g、public function setcredentials( username : string, password : string ) : void // set the credentials for all registered services. note that services that use a proxy or a third-party adapter to a remote endpoint will

原来的getservice和getinvokerservice方法已经废弃,改为了getremoteobject

4. 在command中,增加了icommand接口,原来的command接口继承icommand

5. 在vo中,增加了ivalueobject接口,原来的valueobject继承ivalueobject接口

上面添加的几个接口,除了iservicelocator相较2.0版本有了较大的变化,增加了一些方法,其他的几个接口,依我所见,纯粹是换了名字而已。

 



云自无心水自闲 2007-04-10 19:48
]]>
fds(flex data service)改名为livecycle data servicehttp://www.blogjava.net/usherlight/archive/2007/04/04/108511.html云自无心水自闲云自无心水自闲wed, 04 apr 2007 11:07:00 gmthttp://www.blogjava.net/usherlight/archive/2007/04/04/108511.htmlhttp://www.blogjava.net/usherlight/comments/108511.htmlhttp://www.blogjava.net/usherlight/archive/2007/04/04/108511.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/108511.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/108511.html这个名字的改变反应出fds的一个重要的扩展:livecycle data service与adobe其他livecycle服务产品的整合将更紧密。

livecycel data service将有一些重要的新的变化:
1. 提升数据服务消息的性能
2. 与pdf、j2ee门户等的集成
3. 另外还有一些针对未来apollo应用的很重要的功能,比如:本地数据缓存和脱机消息等。

下载地址:

云自无心水自闲 2007-04-04 19:07
]]>
flex.org正式改版了http://www.blogjava.net/usherlight/archive/2007/04/04/108508.html云自无心水自闲云自无心水自闲wed, 04 apr 2007 10:59:00 gmthttp://www.blogjava.net/usherlight/archive/2007/04/04/108508.htmlhttp://www.blogjava.net/usherlight/comments/108508.htmlhttp://www.blogjava.net/usherlight/archive/2007/04/04/108508.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/108508.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/108508.html左边4个,分别是:flex实例,flex下载、flex社区、帮助
右边一个大块是:flex介绍和flex盛会。

整体感觉比以前要清新爽洁。

最上面的一排菜单项好像比以前要多。
有博客、社区、文档、下载、工作、演示、支持。

云自无心水自闲 2007-04-04 18:59
]]>
flex lib 出了新版本http://www.blogjava.net/usherlight/archive/2007/03/30/107459.html云自无心水自闲云自无心水自闲fri, 30 mar 2007 05:23:00 gmthttp://www.blogjava.net/usherlight/archive/2007/03/30/107459.htmlhttp://www.blogjava.net/usherlight/comments/107459.htmlhttp://www.blogjava.net/usherlight/archive/2007/03/30/107459.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/107459.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/107459.html下载地址:


里面有4个目录:
bin
src
docs
examples

包含:
advancedform
convertibletreelist
dragcanvas
draggableslider
haccordion
imagemap
promptingtextinput
scrollablemenus
supertabnavigator
treegrid
verticalmenubar
这些内容

云自无心水自闲 2007-03-30 13:23
]]>
一个cairngorm的代码生成器http://www.blogjava.net/usherlight/archive/2007/03/24/106000.html云自无心水自闲云自无心水自闲fri, 23 mar 2007 16:13:00 gmthttp://www.blogjava.net/usherlight/archive/2007/03/24/106000.htmlhttp://www.blogjava.net/usherlight/comments/106000.htmlhttp://www.blogjava.net/usherlight/archive/2007/03/24/106000.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/106000.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/106000.htmlcaringen是一个eric feminella自己开发的一个小工具. 现在他把这个工具共享出来.
cairngen并不能让所有的人解决所有的问题, 它只是简单地加快开发的过程.

cairngen是一个caringorm的代码生成器, 它使得开发者可以很方便地生成cairngorm项目的结构框架, 包括: cairngorm项目的目录结构, 一个缺省的modellocator, controller, servicelocator. cairngen也可以生成event, command, delegate类.

cairngen使用flex2和php5.2.0开发, 利用了amfphp. 安装过程十分方便. 你可以在flex builder的浏览器中直接运行cairngen来快速方便地生成cairngorm的类.

cairngen使用'步骤(sequence)'来描述event, command, delegate类之间的关系.
在cairngen中只要命名一个'步骤',点击一下生成按钮就可以生成一个'步骤'. 然后刷新一下flex项目, 生成的类就ok了. 在一些特殊的情况下, 你不希望添加delegate类, 那么你可以选择排除delegate类的生成, 这样的话, cairngen只生成event和command.
生成的command类实现cairngorm的command接口, 但不实现iresponder接口. cairngen还能够正确地将事件强制性转化(casting)为coand中的类型, 并import所有相关的类.

系统需求:
1. 了解amfphp, apache2.0.59和php5.2.0, 在使用cairngen之前要求先安装amfphp, 而且gateway.php的访问虚拟目录应该如下设置: . 在1.0版正式发布后, 这个url可以自由配置.
2. 还需要安装flex2, php, 你可以用wamp5来集成安装apache5.5和php. 安装好php和amfphp后, 就可以解压缩cairngen alpha 1. 把services目录复制到amfphp的根目录下. 然后复制cairgen-ui目录到apache的www根目录下.

使用:
安装好php和amfphp后, 就可以开始使用cairngen了. 打开浏览器输入打开生成器的图形界面. 创建cairgen项目:
点击 begin
给你的cairngen项目命名. 这个名称与flex项目的名称相同, 选择你的cairngorm的版本, 选择flex项目的路径. 设置项目中包路径(比如: com.domain.projectname). 最后, 检验一下输入内容, 点击"create project". 刷新flex项目查看缺省的cairngorm项目结构, modellocator, service和controller类.

创建"步骤":

首先是给步骤命名, 然后选择是否要生成delegate类, 点击生成, 并刷新flex项目. 可以发现需要的类已经生成完毕了. 现在需要把它们添加到controller中.
接下来编辑模板文件: 你可以修改模板文件(.tpl)来实现你的特定的cairngorm需求; 模板文件在 amfphp\services\com\ericfeminella\cairngen\templates目录下.

生成器下载地址:



云自无心水自闲 2007-03-24 00:13
]]>
flexlib & flexboxhttp://www.blogjava.net/usherlight/archive/2007/03/09/102779.html云自无心水自闲云自无心水自闲fri, 09 mar 2007 03:46:00 gmthttp://www.blogjava.net/usherlight/archive/2007/03/09/102779.htmlhttp://www.blogjava.net/usherlight/comments/102779.htmlhttp://www.blogjava.net/usherlight/archive/2007/03/09/102779.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/102779.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/102779.html
最近adobe公司的一批人在google的code project上发布了flexlib,一个开源的flex2组件库。
现有的组件包括:
   convertibletreelist, 
   draggable slider, 
   promptingtextinput, 
   scrollable menu controls, 
   supertabnavigator, 
   alternative scrolling canvases, 
   horizontal accordion

大家可以去看看。

另外,还有个人也发布了一个flex2 组件目录: flexbox。这个网站
  • flexlib home page -
  • flexlib discussion group -
  • flexbox -


云自无心水自闲 2007-03-09 11:46
]]>
数据绑定的小技巧 flex data binding tiphttp://www.blogjava.net/usherlight/archive/2007/03/08/102702.html云自无心水自闲云自无心水自闲thu, 08 mar 2007 14:58:00 gmthttp://www.blogjava.net/usherlight/archive/2007/03/08/102702.htmlhttp://www.blogjava.net/usherlight/comments/102702.htmlhttp://www.blogjava.net/usherlight/archive/2007/03/08/102702.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/102702.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/102702.html 

现在有一个方便的做法来根据选择enable/disable控件。比如:有一个datagrid和数个操作数据的按钮,当选中某行是激活其中一个按钮,选中另一行时,激活其中另一个按钮,等等。

通常的做法是写一大堆的if else语句,或者是设置一堆变量绑定到按钮上,然后在代码中设置这些变量的值,比如:

[bindable] private var somethingselected:boolean = false;

这是一个有益的尝试。所有的依赖于datagrid状态的控件都绑定一个变量。改变变量的值就改变控件的enabled状态。但是你还需要确定改变变量值的时机。比如:

private function publishitem() : void {
     // get the selected item
     // publish it
     grid.selecteditem = -1; // clear the selection
     somethingselected = false;
}

在复杂的情况下,假设有另一个按钮需要在选中某个特定值时被激活。那么你不仅需要考虑选中对应的那个变量,还需要考虑其他按钮的情况。也就是说,在publishitem函数中你还需要设置其他变量的值。

一个更方便的做法是这样的。现在我们publish按钮和somethingselected变量进行绑定。我们还需要做的是把somethingselected变量与datagrid的选中状态进行关联。对此,我们可以使用标签。

这样somethingselected的值与datagrid的选中状态就紧密地联系起来了。当选中了datagrid中的某条数据时,所有进行enabled="{somethingselected}"绑定的按钮就被激活。标签的source属性不需要一定是一个变量,完全可以是一个表达式。

比如稍微复杂一点的一个例子:

这样,当datagrid选中行的code字段的值为1时,变量codeonepicked的值被设置为true。
mxml中可以如下定义:


这样,当选中行的code字段值为1时,上面的复选框被激活,而下面的按钮无效。



云自无心水自闲 2007-03-08 22:58
]]>
开源的fds出现http://www.blogjava.net/usherlight/archive/2007/03/01/101318.html云自无心水自闲云自无心水自闲thu, 01 mar 2007 14:22:00 gmthttp://www.blogjava.net/usherlight/archive/2007/03/01/101318.htmlhttp://www.blogjava.net/usherlight/comments/101318.htmlhttp://www.blogjava.net/usherlight/archive/2007/03/01/101318.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/101318.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/101318.html

支持amf3
  • 支持amf3
  • ejb3服务的透明externalization机制,参见flex2的开发文档

  • 在flex的序列化和反序列化过程中,只能传递public的,非静态的属性,如果要序列化此部分内容在flex与java间传递,必须使用externalization机制

  • actionscript3的beans的lazy initialize
  • ejb3实体bean到actionscript3的类的代码生成(计划中)
  • pojo服务(远程调用简单java类的公共方法)
  • 一系列flex组件用于复杂的数据结构(计划中)、


  • 云自无心水自闲 2007-03-01 22:22
    ]]>
    flex的事件流http://www.blogjava.net/usherlight/archive/2007/02/11/99340.html云自无心水自闲云自无心水自闲sun, 11 feb 2007 15:50:00 gmthttp://www.blogjava.net/usherlight/archive/2007/02/11/99340.htmlhttp://www.blogjava.net/usherlight/comments/99340.htmlhttp://www.blogjava.net/usherlight/archive/2007/02/11/99340.html#feedback1http://www.blogjava.net/usherlight/comments/commentrss/99340.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/99340.htmlflex是一个事件驱动的编程模型, 任何事情的发生, 其背后必然存在一个事件. 而开发者第一次看到mxml时, 很难体会到一个xml标记的应用的事件流和实例化的生命周期. 这个对于html和flash的开发者尤其会感到困惑, 因为其熟悉的方式与flex的一点也不相似. html的实例化是从上到下的, flash的执行是从frame0开始一帧帧运行的. 而flex则又有不同.

    从我们开始学习flex时, 我们就需要了解事件流和mxml的实例化. 我非常困惑因为我实在难以理解什么样的事件会被触发或者事件什么时候会被触发. 关键是要理解事件的基础并亲自观察事件流的初始化.


    我们来看一个简单的mxml的应用.


        xmlns:mx=""
        layout="absolute"
        backgroundgradientcolors="[#67cbff, #fcffff]"
        color="#000000"
        fontsize="12"   
        preinitialize="report( event , 'preinitialize' )"
        initialize="report( event , 'initialize' )"
        creationcomplete="report( event , 'creationcomplete' )"
        applicationcomplete="report( event , 'applicationcomplete' )"
        >
       
       
                               
                [bindable]
               
                public var outtextdata:string="";
               
                public function report( event:event , value:string ):void
                {
                    outtextdata = string( flash.utils.gettimer() ) 'ms >> '
                    event.currenttarget '.' value '\n';   
                }
               
            ]]>
       

       
                id="outtextarea"
            text="{ outtextdata }"
            right="10" left="10" top="50" bottom="10" alpha="0.5"
            wordwrap="false"
            initialize="report( event , 'initialize' )"
            creationcomplete="report( event , 'creationcomplete' )"
            />
       
                y="10" height="30" left="168" width="150"
            id="hellobutton"
            label="say hello"
            initialize="report( event , 'initialize' )"
            creationcomplete="report( event , 'creationcomplete' )"
            rollover="report( event , 'rollover' )"
            rollout="report( event , 'rollout' )"
            click="report( event , 'click > hello!' )"
            />
           
                id="goodbyebutton"
            label="say goodbye"
            y="10" left="10" height="30" width="150" color="#000000"
            initialize="report( event , 'initialize' )"
            creationcomplete="report( event , 'creationcomplete' )"
            click="report( event , 'click > goodbye!' )"
            />
           
                id="clearbutton"
            label="clear"
            y="10" left="326" height="30" color="#000000" right="10"       
            initialize="report( event , 'initialize' )"
            creationcomplete="report( event , 'creationcomplete' )"
            click="outtextdata='';report( event , 'click' )"
             />
       


    这个应用运行时, 输出了实例流程和事件流. 这校我们就能够看到所有事件的触发顺序. 可以发现应用启动后, 事件的顺序是一定的. 下面是输出的内容:

    167ms >> eventflow0.preinitialize
    183ms >> eventflow0.outtextarea.initialize
    187ms >> eventflow0.hellobutton.initialize
    188ms >> eventflow0.goodbyebutton.initialize
    189ms >> eventflow0.clearbutton.initialize
    189ms >> eventflow0.initialize
    243ms >> eventflow0.outtextarea.creationcomplete
    243ms >> eventflow0.hellobutton.creationcomplete
    243ms >> eventflow0.goodbyebutton.creationcomplete
    244ms >> eventflow0.clearbutton.creationcomplete
    244ms >> eventflow0.creationcomplete
    246ms >> eventflow0.applicationcomplete

    一旦applicationcomplete事件触发后, 组件就会在鼠标事件派发后触发自己的事件.

    1807ms >> eventflow0.hellobutton.rollover
    2596ms >> eventflow0.hellobutton.rollout
    2954ms >> eventflow0.hellobutton.rollover
    3170ms >> eventflow0.hellobutton.rollout
    3543ms >> eventflow0.hellobutton.rollover
    4052ms >> eventflow0.hellobutton.click > hello!
    4267ms >> eventflow0.hellobutton.click > hello!
    4474ms >> eventflow0.hellobutton.click > hello!
    4569ms >> eventflow0.hellobutton.rollout
    4907ms >> eventflow0.goodbyebutton.click > goodbye!
    5130ms >> eventflow0.goodbyebutton.click > goodbye!

     



    云自无心水自闲 2007-02-11 23:50
    ]]>
    actionscript3.0/flex2中的反射http://www.blogjava.net/usherlight/archive/2007/02/10/99134.html云自无心水自闲云自无心水自闲sat, 10 feb 2007 06:32:00 gmthttp://www.blogjava.net/usherlight/archive/2007/02/10/99134.htmlhttp://www.blogjava.net/usherlight/comments/99134.htmlhttp://www.blogjava.net/usherlight/archive/2007/02/10/99134.html#feedback1http://www.blogjava.net/usherlight/comments/commentrss/99134.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/99134.html 

    在actionscript 3中,你会发现在flash.utils包中有一系列函数提供了反射的功能。主要包含以下功能:

        * 确定对象的类
        * 获取类的成员、方法、构造函数、父类的信息
        * 确定接口声明的常数和方法
        * 在运行时根据类名创建类的实例
        * 在运行时根据成员名称获取或者设置对象成员的值
        * 在运行时根据方法名称,调用对象的方法

    你可以使用类似于"describetype"之类的功能,它返回一个xml对象。举一个例子:

    package {
        import flash.display.sprite;
        import flash.utils.describetype;
      
        public class describetypeexample extends sprite {
            public function describetypeexample() {
                var child:sprite = new sprite();
                var description:xml = describetype(child);
                trace(());
            }
        }
    }

    如果你想进一步,根据类名创建对象的实例,我们可以使用"getdefinitionbyname()"

    package {
        import flash.display.displayobject;
        import flash.display.sprite;
        import flash.utils.getdefinitionbyname;

        public class getdefinitionbynameexample extends sprite {
            private var bgcolor:uint = 0xffcc00;
            private var size:uint = 80;

            public function getdefinitionbynameexample() {
                var classreference:class = getdefinitionbyname(“flash.display.sprite”) as class;
                var instance:object = new classreference();
                instance.graphics.beginfill(bgcolor);
                instance.graphics.drawrect(0, 0, size, size);
                instance.graphics.endfill();
                addchild(displayobject(instance));
            }
        }
    }

    尽管这是一些非常方便的方法,但是在flashplayer中使用反射还是会有许多的限制,因为缺乏运行时的动态源码编译。上面的功能对于那些在内建的类,比如:sprite类来说无疑是有用的,但是对于自定义类来说,我们会遇到很多麻烦。比如:

    package {
        import com.customtypes.string; // custom string implementation class
        import flash.utils.getdefinitionbyname;

        public class getdefinitionbynameexample {
            public function getdefinitionbynameexample() {
                var classreference:class = getdefinitionbyname(“com.customtypes.string”) as class;
                var instance:object = new classreference();
                instance.customparameter = “my parameter”;
            }
        }
    }

    尽管我们使用了import语句,但是"getdefinitionbyname()"还是会失败。原因上面已经说过了,在运行时编译源代码是不允许的。也许以后可以。在目前情况下,要实现上述功能,至少要在代码中初始化一个类的实例。也就是声明一个类的实例:

    var customtype : com.customtypes.string;

     



    云自无心水自闲 2007-02-10 14:32
    ]]>
    在flex应用中使用全局变量http://www.blogjava.net/usherlight/archive/2007/02/06/98259.html云自无心水自闲云自无心水自闲tue, 06 feb 2007 05:00:00 gmthttp://www.blogjava.net/usherlight/archive/2007/02/06/98259.htmlhttp://www.blogjava.net/usherlight/comments/98259.htmlhttp://www.blogjava.net/usherlight/archive/2007/02/06/98259.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/98259.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/98259.html 其实非常简单, 只需要在application类中定义一个public类型的变量就行了:

    
    
    	
    		
    	
    

    在其它的地方就可以使用

    application.application.foo

    来访问了. 如果需要, 也可以添加 bindable 属性.
    但是要注意到一个问题就是, 在使用的时候编译器不会进行类型的检查, 因此最好添加类型强制转换.

    当然, 全局变量实现的另一种方法是使用单例模式.




    云自无心水自闲 2007-02-06 13:00
    ]]>
    在flex应用中使用模块(modules) ihttp://www.blogjava.net/usherlight/archive/2007/02/06/98145.html云自无心水自闲云自无心水自闲mon, 05 feb 2007 16:05:00 gmthttp://www.blogjava.net/usherlight/archive/2007/02/06/98145.htmlhttp://www.blogjava.net/usherlight/comments/98145.htmlhttp://www.blogjava.net/usherlight/archive/2007/02/06/98145.html#feedback2http://www.blogjava.net/usherlight/comments/commentrss/98145.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/98145.html有许多方法可以把一个应用拆分成基于个独立下载的部分。甚至于将每个类都分成单独的文件,由classloader在需要的时候加载。但是如果这样效率是比较低下的,因为类的引用有着明显的“引用地域”;如果你引用了一个类,往往会马上牵涉到需要引用一大堆其他的类,如果把这些类全都打包在一起,效率会高得多。

    由编译器自动选择一个非常好的打包方法是比较困难的。很可能需要在应用开发时进行一些设定,并不时地监控类的引用。能够统计出最优的分拆方法:应用应该分成几个swf,哪些类应该放在哪个swf中。但是这种方法听起来更象是一种研究范畴,实际操作起来非常困难。

    让我们来看一些更具有操作性的方法。

    很多应用分解后,包含两种类型的功能:“启动后立即填充”和“启动后稍后填充”。

    有许许多多的应用是这种模式的。比如:游戏;你有一个游戏引擎和一些游戏场景。或者portals和porlets; 一些基础的共享功能和数据驱动的小应用。或者是一个大型的有着1500个页面的保险应用,运行特定功能是只会访问一小部分的页面。或者是充斥大量内容的应用,它可以独立的更新部分内容而不是强制用户每次浏览时都必须下载全部内容。

    我称这些相对独立的可以延迟加载的功能为“模块”(modules),称加载模块的应用为“shell”。

    在这里,我们先不看如何做,先来看一些

    shell需要能够与模块交互,同样模块也需要和shell交互。如果shell引用了modules的一个类,那么它会把它链接进来。同样,如果模块类引用了shell类,它也会把它链接进来。应用能正常运行只有两个方法:或者引用是相同而且共享的(这样就不需要下载两次),或者两者是不同的,而且没有任何关系(尽管两个类名字相同,但是它们被认为是无关的,而且不能交互)。

    最好的解决办法是让模块和shell通过接口交互。这样,shell不需要引用模块,而是引用模块会实现的一些接口。同样,模块不实现shell的类,而是允许调用的api接口。

    这样在shell变化的时候减少了重新编译模块的次数。具体实现的变化频率往往会比接口本身的变化高得多,而只要接口稳定,就不需要重新编译所有的东西。

    注意:需要使用extern(或者extern-library-path)选项来创建模块,这样可以自动剔除shell的类,因为模块是被加载到shell的子应用域中的,将shell的类剔除是安全的。这样模块可以真正直接引用shell中的类。


     



    云自无心水自闲 2007-02-06 00:05
    ]]>
    使用rsl(runtime shared libraries)来减小flex生成的swf文件的大小(vi) -- 使用rsl的完整示例http://www.blogjava.net/usherlight/archive/2007/02/04/97898.html云自无心水自闲云自无心水自闲sun, 04 feb 2007 15:36:00 gmthttp://www.blogjava.net/usherlight/archive/2007/02/04/97898.htmlhttp://www.blogjava.net/usherlight/comments/97898.htmlhttp://www.blogjava.net/usherlight/archive/2007/02/04/97898.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/97898.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/97898.html这个例子包括了应用中使用rsl的完整流程。使用命令行进行编译,但是你可以使用flexbuilder用相同的过程来创建使用rsl。

    记住swc文件是一个包含swf文件的二进制文件,而swf文件包含运行时的定义和附属元数据。你可以用压缩工具比如winzip来打开swc文件。
    在使用rsl之前,首先需要了解如何静态链接一个swc文件。

    在这个例子中,应用有一个app.mxml文件,使用productconfigurator.as和productview.as。文件目录如下:

    project/src/app.mxml
    project/libsrc/productconfigurator.as
    project/libsrc/productview.as
    project/lib/
    project/bin/


    编译这个应用时,可以使用source-path选项将/libsrc目录下的类链接进来,方法如下:

    cd project/src
    mxmlc -o=../bin/app.swf -source-path =../libsrc app.mxml

    这个命令添加productconfigurator和productview类到swf文件中。


    如果要创建库,可以用compc来创建swc文件,用下面的命令:

    cd project
    compc -source-path =libsrc -debug=false -o=lib/mylib.swc
    productconfigurator productview

    注意要将debug选项设置为false. 生成结果是project/lib/mylib.swc文件,包含productconfigurator和productview两个类。

    现在可以使用新创建的库来重新编译应用,用library-path选项来指定库,方法如下:

    cd project/src
    mxmlc -o=../bin/app.swf -library-path =../lib/mylib.swc app.mxml

    创建库以后,你可以用rsl来重新编译生成应用。完整的步骤如下:

       1. 指示编译器不要将库链接到应用中。
       2. 准备rsl,以便于在运行时使用。
       3. 指示编译器生成附加元数据用于加载rsl。


    第一步是指定编译生成应用时库中的哪些类需要排除在外。主要是使用external-library-path选项,如下面的例子所示:

    cd project/src
    mxmlc -o=../bin/app.swf -external-library-path =../lib/mylib.swc app.mxml

    如果你尝试运行app.swf,flash player会抛出一个运行时异常。因为productconfigurator和productview类还未定义。external-library-path配置选项告诉编译器编译这些库,但是忽略了定义。你也可以使用externs选项,但是一般来说,使用external-library-path更方便。

    下一步是准备rsl以便于能在运行时找到它。首先从swc文件中将library.swf解压出来。

    下面是如何解压的例子:

    cd project/lib
    unzip mylib.swc library.swf
    mv library.swf ../bin/myrsl.swf

    此例子中将library.swf更名为myrsl.swf,并把它移动到应用swf文件所在的目录。

    最后一步是使用rsl重新编译应用。主要是使用runtime-shared-libraries选项,方法如下:

    cd project/src
    mxmlc -o=../bin/app.swf -external-library-path =../lib/mylib.swc
    -runtime-shared-libraries=myrsl.swf app.mxml

    现在新的swf文件会在运行应用前动态加载rsl了。



    云自无心水自闲 2007-02-04 23:36
    ]]>
    使用rsl(runtime shared libraries)来减小flex生成的swf文件的大小(v) -- 使用rslhttp://www.blogjava.net/usherlight/archive/2007/02/01/97340.html云自无心水自闲云自无心水自闲thu, 01 feb 2007 11:17:00 gmthttp://www.blogjava.net/usherlight/archive/2007/02/01/97340.htmlhttp://www.blogjava.net/usherlight/comments/97340.htmlhttp://www.blogjava.net/usherlight/archive/2007/02/01/97340.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/97340.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/97340.html在编译应用时要使用rsl, 需要使用下列编译选项:

        * runtime-shared-libraries 提供运行运行时共享库的位置.
        * external-library-path|externs|load-externs 提供编译时库的位置. 编译器需要这个信息动态链接.


    使用runtime-shared-libraries选项来指定swf文件的位置, 这样应用能够在运行时加载rsl. 需要指定swf与部署位置的相对路径. 比如: 如果把library.swf文件放在web_root/libraries目录下, 而应用在web_root目录下, 那么文件的指定方法是: libraries/library.swf
    可以用这个选项指定多个库. 如果指定了多个库, 需要用逗号分隔.


    使用external-library-path选项来指定library在编译时的swc文件或者目录的位置. 编译器会在编译时根据这个选项进行链接的检查. 你还可以使用externs或者load-externs选项来指定其他单独的classes或者xml文件来定义库的内容.


    下面是一个编译myapp应用的命令行示例, 其中使用了2个库:

    mxmlc -runtime-shared-libraries=
    ../libraries/customcellrenderer/library.swf,
    ../libraries/customdatagrid/library.swf
    -external-library-path=../libraries/customcellrenderer,
    ../libraries/customdatagrid myapp.mxml

    库的顺序非常重要, 因为基础类必须先加载.


    你先可以使用配置文件, 示例如下:


       
            ../libraries/customcellrenderer
            ../libraries/customdatagrid
            ../libs/playerglobal.swc
       



        ../libraries/customcellrenderer/library.swf
        ../libraries/customdatagrid/library.swf


    runtime-shared-libraries选项值是library.swf文件是相对部署目录的路径. external-library-path选项是编译时swc文件的路径. 因此, 必须先知道库的部署路径.

     

    示例中, 编译时文件结构如下:

    c:/appfiles/myapp.mxml
    c:/libraries/customcellrenderer/customcellrenderer.swc
    c:/libraries/customdatagrid/customdatagrid.swc

    library.swf在编译进不是必需的. flex编译器不验证swf文件的存在与否, 但会把路径信息编译进行最后的应用代码中.


    文件的部署结构如下:

    web_root/myapp.swf
    web_root/libraries/customcellrenderer/library.swf
    web_root/libraries/customdatagrid/library.swf

     



    云自无心水自闲 2007-02-01 19:17
    ]]>
    使用rsl(runtime shared libraries)来减小flex生成的swf文件的大小(iv) -- 创建rslhttp://www.blogjava.net/usherlight/archive/2007/02/01/97286.html云自无心水自闲云自无心水自闲thu, 01 feb 2007 07:25:00 gmthttp://www.blogjava.net/usherlight/archive/2007/02/01/97286.htmlhttp://www.blogjava.net/usherlight/comments/97286.htmlhttp://www.blogjava.net/usherlight/archive/2007/02/01/97286.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/97286.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/97286.html创建库

    可以使用flex builder或者compc命令行来创建库. 库可以是一个swc文件, 或者是包含了library.swf和catalog.xml文件的目录. 一个库通常包含自定义组件和类. 然后就可以在rsl中使用这些库了.

    在flex bulder中, 通过使用flex library build path对话框来添加资源到库中.

    在命令行中, 使用include-classes和include-namespaces选项来添加文件到库中.

    下面的命令行示例说明了如何创建一个名字叫customcellrenderer的库:

    compc -source-path ../mycomponents/components/local
    -include-classes customcellrenderercomponent -directory=true -debug=false
    -output ../libraries/customcellrenderer

    所有包含的组件必须是静态链接的文件. 使用compc编译器创建库时, 不能使用include-file选项, 因为这个选项不是将library.swf文件静态链接到库中的.

    可以使用directory选项指定输出到一个目录而不是到一个swc文件中:



       
           
                mycomponents/components/local
           

       

        libraries/customcellrenderer
        true
        false
       
            customcellrenderercomponent
       

    输出会是一个目录,目录里包含两个文件
        * catalog.xml
        * library.swf

    创建library.swf文件后, 你可以编译应用并且指定文件的位置.



    云自无心水自闲 2007-02-01 15:25
    ]]>
    bruce eckel(thinking in java)的作者对flex的看法http://www.blogjava.net/usherlight/archive/2007/02/01/97120.html云自无心水自闲云自无心水自闲wed, 31 jan 2007 16:52:00 gmthttp://www.blogjava.net/usherlight/archive/2007/02/01/97120.htmlhttp://www.blogjava.net/usherlight/comments/97120.htmlhttp://www.blogjava.net/usherlight/archive/2007/02/01/97120.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/97120.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/97120.html ui的问题如何解决呢: awt, swing, swt, 或者是一些其他的比如: tkinter, wxpython之类的东西?
    bruce认为这些对于创建一个真正跨平台的应用是不够的.
    他认为最好的凯发天生赢家一触即发官网的解决方案就是flex!

    flex and flash provide a complete, unlimited, flexible tool to build user experiences. from the standpoint of a programmer’s time investment, you can learn a single language for building uis without worrying about running into problems or limitations later—issues like:

    • installation problems
    • constraints on what you can create
    • sudden steep climbs in the learning curve



    原文链接:

    computing thoughts
    hybridizing java
    by bruce eckel
    january 30, 2007



    云自无心水自闲 2007-02-01 00:52
    ]]>
    使用rsl(runtime shared libraries)来减小flex生成的swf文件的大小(iii) -- rsl的优缺点http://www.blogjava.net/usherlight/archive/2007/02/01/97117.html云自无心水自闲云自无心水自闲wed, 31 jan 2007 16:43:00 gmthttp://www.blogjava.net/usherlight/archive/2007/02/01/97117.htmlhttp://www.blogjava.net/usherlight/comments/97117.htmlhttp://www.blogjava.net/usherlight/archive/2007/02/01/97117.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/97117.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/97117.html rsl也需要谨慎使用

    rsl也不是对于所有的应用都是有益的. 需要对应用rsl前后的下载时间和启动时间都测试过, 才能得到正确的结论.

    rsl不能跨域共享. 如果客户在一个域中使用了rsl, 然后运行了另一个域的应用, 虽然这两个rsl是相同的, 但是需要下载两次.

    rsl通常会增加应用的启动时间. 这是应用不管整个库实际如何使用, 只是简单地全部加载整个库. 就这一点来说, rsl越小越好. 这与静态链接库的使用是不同的. 当你编译一个felx应用时, 编译器只解开需要的组件. 一般来说, 库的大小可以是任意的, 它只影响编译时间而不会影响下载的时间.

    如果在好几个应用中使用相同的组件库, 那么可以考虑合并这些库, 形成一个rsl. 但是如果库合并后, 每个应用只会用到其中的一小部分, 那么还不如多加载几个小rsl更高效.

    如果一些类重复打包在多个rsl中, 那么一定要注意同步更新的问题.

    rsl不能应用在基类是sprite或者movieclip的纯actionscript项目中. 因为rsl需要基类知道如何加载rsl, 比如: application或者simpleapplication.

    关于 framework.swc文件

    framework.swc是一个标准的swc文件. 缺省地它不能用作rsl. 整个framwork.swc文件不被链接到任何一个应用中. flex编译器只将那些应用用到的部分链接到生成最后的swf文件. 比如: 如果一个应用只使用了button, panel和textarea控件, 那么只有这几个控件和它们的依赖项被编译器链接.

    几乎所有的应用都需要framework.swc文件的一部分, 但是它并不适合作为rsl. 原因如上据说, rsl是整个链接, 不管实际使用多少的. 如果rsl包含了很多类, 而应用只使用了其中的一小部分, 那么这样的加载方式并不是最合理的. 这样使用会造成应用的启动时间大大增加.


    rsl的优点

    下面的一个例子说明了将几个的共享组件做成rsl的优点. 在这个例子中, 组件库的大小是150k, 编译后的应用的大小是100k.
     

    使用了rsl, rsl只被下载一次. 那么合计下载量是350k, 节约了30%. 如果再添加第3个, 第4个应用的话, 每次都能150k的下载量.

    一般来说, 在一个域中使用同一个rsl的应用越多, 那么好处就越大.



    云自无心水自闲 2007-02-01 00:43
    ]]>
    使用rsl(runtime shared libraries)来减小flex生成的swf文件的大小(ii) -- 介绍链接(linking)http://www.blogjava.net/usherlight/archive/2007/01/27/96333.html云自无心水自闲云自无心水自闲sat, 27 jan 2007 15:42:00 gmthttp://www.blogjava.net/usherlight/archive/2007/01/27/96333.htmlhttp://www.blogjava.net/usherlight/comments/96333.htmlhttp://www.blogjava.net/usherlight/archive/2007/01/27/96333.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/96333.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/96333.html理解链接可以帮助你理解rsl是怎样工作的. flex编译器支持静态链接和动态链接. 静态链接是最通常的方法. 但是动态链接使你借助于rsl来实现swf文件的缩水以及应用的下载次数.

    当你使用静态链接时, 编译器将应用中所有引用的类和依赖生成到最终的swf文件中, 这个文件会比较大, 下载也会比较慢, 但是下载完毕后, 运行会比较快, 因为swf文件中已经包含了所有的代码.

    如果你的应用中使用了类库, 那么你需要使用类路径或者是添加swc文件. 如果是使用类路径, 编译器会将类路径中用到的那部分类打包生成到swf文件中. 如果是使用swc文件, 编译器会将整个swc文件打包到swf文件中.

    动态链接是这样的: 一个应用要使用的一部分类存在于一个外部的文件中, 运行时动态加载. 这样的话, 主swf文件可以小一些, 但是应用依赖于运行时加载的外部文件. rsl就是使用动态链接的.

    如果想使用动态链接类, 需要把它们编译成库. 然后编译器将库中的内容从swf文件剔除出去. 而且必须在编译时提供链接检查.

    为指定哪些文件是动态链接的,需要使用外部库路径选项,外部选项或者外部加载编译选项. 这些选项告诉编译器从应用中去除此部分内容, 而预备在运行时调用. 外部选项为动态链接指定了单独的类. 外部加载选项指定了一个xml文件, 描述了动态链接的类.

    指定sl的外部资源的顺序是非常关键的, 因为被其他类调用的基础类必须被首先加载.

    你还要用runtime-shared-libraries选项来指定rsl的位置.

    你可以使用link-report这个编译选项来查看应用的链接信息.



    云自无心水自闲 2007-01-27 23:42
    ]]>
    使用rsl(runtime shared libraries)来减小flex生成的swf文件的大小(i) -- 介绍rslhttp://www.blogjava.net/usherlight/archive/2007/01/27/96324.html云自无心水自闲云自无心水自闲sat, 27 jan 2007 14:52:00 gmthttp://www.blogjava.net/usherlight/archive/2007/01/27/96324.htmlhttp://www.blogjava.net/usherlight/comments/96324.htmlhttp://www.blogjava.net/usherlight/archive/2007/01/27/96324.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/96324.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/96324.html减小应用swf文件大小的一个方法就是将一些共享的外部资源拆分出去, 成为一个独立的文件, 这样可以单独地加载缓存到客户端. 这些共享资源可以由多个应用在运行时进行加载, 但是传递到客户端的动作只会发生一次. 这些共享文件被称为运行时共享库(runtime shared libraries)或者简写为rsl.

    如果你有多个应用而且这些应用共享一些核心组件或者类, 那么作为rsl,用户只会唯一的一次加载这些资源. 只要应用在同一个域中, 这些应用共享同一个缓存的rsl, 这样应用文件的大小就减小了. 使用rsl的应用越多, 效果越好, 如果只有一个应用, 总的文件大小不但不减小,反而会增大.

    你既可以使用flex builder通过项目选项来创建flex的library项目,也可以使用compc这样的命令行. 编译好rsl以后, 可以在编译应用时把library的位置传递给编译器.

    下面是适合使用rsl的典型用例:
        * 大型应用, 需要使用通用组件库加载多个小型应用. 最顶级的应用和下级应用可以共享存储在rsl中的组件.

        * 在一个服务器上的使用通用组件库的系列应用. 当用户操作第一个应用时, 用户下载应用的swf文件和rsl. 当操作第二个应用时, 用户就只需要下载应用本身的swf文件就行了.
        
        * 一个独立的应用使用rsl的意义在于: 如果这个应用本身会频繁的修改, 而有一部分组件是极少改动的. 在这种情况下, 使用rsl的好处是: 组件下载一次, 而应用可以多次下载.

     



    云自无心水自闲 2007-01-27 22:52
    ]]>
    编写actionscript3.0中需要注意的10个问题http://www.blogjava.net/usherlight/archive/2007/01/26/96236.html云自无心水自闲云自无心水自闲fri, 26 jan 2007 15:58:00 gmthttp://www.blogjava.net/usherlight/archive/2007/01/26/96236.htmlhttp://www.blogjava.net/usherlight/comments/96236.htmlhttp://www.blogjava.net/usherlight/archive/2007/01/26/96236.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/96236.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/96236.html总结起来需要注意的原则就是:尽量在编译的阶段发现错误,因为这时发现并解决错误远远要比在运行时出错解决起来容易的多。可是实际情况中很多人经常会违反这一原则,下面是我列举的10个技巧:

    1) 永远不要使用'object' 来存储数据. 因为这是一种绕开编译器检查的做法,完全不符合面向对象的思想。如果要用hashmap或者相应的数组,那么可以用dictionary。否则,请自已定义一个类,而不要使用object来作为数据的存储器。

    2) 不要用object来作为对象的类型。这是欺骗编译器的方法。如果必须这样用,最好在存取属性或者调用函数时,先进行强制性的类型转换,至少这是给编译器的一个提示,也帮助其他人理解你的代码。

    3) 也不要用*类型。

    4) 不要将actionscript的类声明为动态。

    5) 注意application.application (和其他的无类型的框架属性). 这个属性有一些古怪.  他应该是applicaton类型的,因为他指向的实例必须是application的子类. 但实际上他的类型是'object', 无法应用编译时的检查。如果你一定要用,最好也进行类型的强制性转换。:

    myapplication( application.application ).functioncall();

    6) 封装你的xml。使用xml与server进行数据的交互非常方便,但是尽量避免使用xml作为核心数据模型。从服务器收到数据后,尽量把xml转换为强类型的对象模型。在flex应用内部使用xml是绕开编译器的作法。

    7) 不要使用dynamicevent.

    8) 不要使用mx:model。如上所述,请尽量使用自定义的强类型的类.

    9) 不要使用cairngorm中的data属性,而应该继承扩展cairngormevent来传递数据。

    10) 不要把编译器的严格模式关掉



    云自无心水自闲 2007-01-26 23:58
    ]]>
    changes between cairngorm 2.1 and cairngorm 2.2 betahttp://www.blogjava.net/usherlight/archive/2007/01/25/96040.html云自无心水自闲云自无心水自闲thu, 25 jan 2007 13:08:00 gmthttp://www.blogjava.net/usherlight/archive/2007/01/25/96040.htmlhttp://www.blogjava.net/usherlight/comments/96040.htmlhttp://www.blogjava.net/usherlight/archive/2007/01/25/96040.html#feedback2http://www.blogjava.net/usherlight/comments/commentrss/96040.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/96040.htmlcairngorm is being packaged. cairngorm 2.1 introduced a dependency on fds.swc, which isn't part of the standard flex sdk - it is part of fds. so, we've repackaged cairngorm into the core cairngorm and cairngorm enterprise - this also starts aligning cairngorm with steven webster's presentation at max when he spoke about the cairngorm roadmap. we're also now going to to distribute cairngorm in binary form (swc), as a source zip and a documentation zip.

    * removed dependency on flex data services (fds.swc) - externalised to cairngorm enterprise
    * flex sdk swcs are no longer linked into cairngorm.swc (produces a smaller cairngorm.swc)
    * added support for setting remote credentials
    * fixed bug with web services not loading the wsdl (no need to call loadwsdl() explicitly)
    * modellocator interface has been deprecated. added com.adobe.cairngorm.model.imodellocator
    * added deprecation metadata for compiler support

    对于我来说,关注的只有一点:modellocator被改成imodellocator了。
    其他的只是cairngorm的打包方式而已。
    cairngorm2.1中依赖于fds.swc,而fds.swc不是flex sdk中的东西,是fds的一部分。
    在2.2中会将cairngorm拆成两部分:core cairngorm和cairngorm enterprise
    和fds.swc相关的部分放入cairngorm enterprise中。

    云自无心水自闲 2007-01-25 21:08
    ]]>
    flex 2.0.1 不仅仅是一个简单的升级http://www.blogjava.net/usherlight/archive/2007/01/21/95121.html云自无心水自闲云自无心水自闲sun, 21 jan 2007 05:54:00 gmthttp://www.blogjava.net/usherlight/archive/2007/01/21/95121.htmlhttp://www.blogjava.net/usherlight/comments/95121.htmlhttp://www.blogjava.net/usherlight/archive/2007/01/21/95121.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/95121.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/95121.html首先在这个版本中,修正了数百个bug

    1. 添加对mac的支持
    2. 支持eclipse 3.2,而不是仅仅支持3.1
    3. 运行时的css支持
    4. 增加了一个mercury的插件,支持自动测试
    5. 其他一些很棒的功能:包括flashtype的字体和asdoc的支持。

    云自无心水自闲 2007-01-21 13:54
    ]]>
    flex2中遍历tree节点http://www.blogjava.net/usherlight/archive/2007/01/07/92213.html云自无心水自闲云自无心水自闲sun, 07 jan 2007 06:37:00 gmthttp://www.blogjava.net/usherlight/archive/2007/01/07/92213.htmlhttp://www.blogjava.net/usherlight/comments/92213.htmlhttp://www.blogjava.net/usherlight/archive/2007/01/07/92213.html#feedback1http://www.blogjava.net/usherlight/comments/commentrss/92213.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/92213.html 这个函数只是一个示例函数,演示如何遍历一个tree。
    此函数严格说起来其实是两个函数:上半部分用于回溯父节点,下半部分递归遍历子节点
    /**
     * this method will traverse a tree's model independent of it's
     * type.
     *
     *

    note :: this method may look long and arduous but, rest assured
     * it has all the checks to perform like a champ. also, you 'could'
     * refactor part of this method but, for the sake of explanation, i
     * kept it all in one place.


     *
     *

    remember, i had coupled the model to this method by tracing
     * @label, obviously you do not need to do this. the intention of
     * this example is to show you that the datadescriptor seperates
     * the models type and is awesome. it enables you to create a tight
     * method like this without type checks on the model.


     *
     * @param tree the tree instance that will be examined by the method.
     * @param item an item found in the dataprovider of the tree passed in.
     * @param startatparent a boolean that determines if the method upon
     * initialization will back up one leve3l to the item passed in and
     * start it's recursion at the item's parent node.
     */

    public function walktree(tree:tree, item:object, startatparent:boolean = false):void
    {
        // get the tree's data descriptor
        var descriptor:itreedatadescriptor = tree.datadescriptor;
        var cursor:iviewcursor;
       
        var parentitem:object;
        var childitem:object;
        var childitems:object;
       
        // if the item is null, stop
        if(item == null)
            return;
           
        // do we back up one level to the item's parent
        if(startatparent)
        {
            // get the parent
            parentitem = tree.getparentitem(item);
            // is the parent real
            if(parentitem)
            {
                trace("|-- parent node ", parentitem[tree.labelfield]);
                // if the parent is a branch
                if(descriptor.isbranch(parentitem))
                {
                    // if the branch has children to run through
                    if(descriptor.haschildren(parentitem))
                    {
                        // get the children of the branch
                        // this part of the algorithm contains the item
                        // passed
                        childitems = descriptor.getchildren(parentitem);
                    }
                }
                // if the branch has valid child items
                if(childitems)
                {
                    // create our back step cursor
                    cursor = childitems.createcursor();
                    // loop through the items parent's children (item)
                    while(!cursor.afterlast)
                    {
                        // get the current child item
                        childitem = cursor.current;

                        var label:string = childitem[tree.labelfield];
                        var branch:boolean = descriptor.isbranch(childitem);
                       
                        // good place for a custom method()
                        trace("sibling nodes :: ", label, "is branch :: ", branch);
                       
                        // if the child item is a branch
                        if(descriptor.isbranch(childitem))
                            // traverse the childs branch all the way down
                            // before returning
                            walktree(tree, childitem);
                        // do it again!
                        cursor.movenext();
                    }
                }
            }
        }
        else// we don't want the parent or this is the second iteration
        {
            // if we are a branch
            if(descriptor.isbranch(item))
            {
                // if the branch has children to run through
                if(descriptor.haschildren(item))
                {
                    // get the children of the branch
                    childitems = descriptor.getchildren(item);
                }
               
                // if the child items exist
                if(childitems)
                {
                    // create our cursor pointer
                    cursor = childitems.createcursor();
                    // loop through all of the children
                    // if one of these children are a branch we will recurse
                    while(!cursor.afterlast)
                    {
                        // get the current child item
                        childitem = cursor.current;

                        var label:string =  childitem[tree.labelfield];
                        var branch:boolean = descriptor.isbranch(childitem);
                       
                        // good place for a custom method()
                        trace("-- sub node :: ", label, "is branch :: ", branch);

                        // if the child item is a branch
                        if(descriptor.isbranch(childitem))
                            // traverse the childs branch all the way down
                            // before returning
                            walktree(tree, childitem);
                        // check the next child
                        cursor.movenext();
                    }
                }
            }
        }
    }
     



     



    云自无心水自闲 2007-01-07 14:37
    ]]>
    cairngorm中model数据变化后如何自动调用一个自定义函数?http://www.blogjava.net/usherlight/archive/2007/01/07/92181.html云自无心水自闲云自无心水自闲sat, 06 jan 2007 18:15:00 gmthttp://www.blogjava.net/usherlight/archive/2007/01/07/92181.htmlhttp://www.blogjava.net/usherlight/comments/92181.htmlhttp://www.blogjava.net/usherlight/archive/2007/01/07/92181.html#feedback1http://www.blogjava.net/usherlight/comments/commentrss/92181.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/92181.html 

    在flex的开发过程中,尤其是在使用cairngorm的时候,总会遇到需要在model的属性值改变后,需要调用一个指定的函数。传统的解决方法是使用一个setter方法,在这个方法中首先对属性赋值,然后调用指定的函数,比如:

    ---------------------------
    [changeevent("deleteenabledchange")]
    public function get deleteenabled() : boolean {
    return _deletebuttonvisible;
    }

    public function set deleteenabled(value : boolean) : void {
    _deletebuttonvisible = value;
    simplebutton(deletebutton)._visible = false;
    dispatchevent(new event("deleteenabledchange", this));
    }
    --------------

    但是现在我们有一个更简洁的解决之道
    首先添加这样一个类
    package com.adobe.ac.util
    {
       public class observe
       {
          public var handler : function;
     
          public function set source( source : * ) : void
          {
             handler.call();
          }
       }
    }
    然后就可以使用这个作为标签了。
                  handler="{ this.myfunction }"/>
    使用了这样的一个标签后,今后嘦是对model.myproperty进行赋值,就会调用myfunction
    这个号称世上最小的标签是不是很好用啊?



    云自无心水自闲 2007-01-07 02:15
    ]]>
    cairngorm示例--业务逻辑如何管理视图(iii)http://www.blogjava.net/usherlight/archive/2006/12/29/90621.html云自无心水自闲云自无心水自闲thu, 28 dec 2006 16:36:00 gmthttp://www.blogjava.net/usherlight/archive/2006/12/29/90621.htmlhttp://www.blogjava.net/usherlight/comments/90621.htmlhttp://www.blogjava.net/usherlight/archive/2006/12/29/90621.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/90621.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/90621.html现在我们将增加验证、格式化和一些其他的功能。
    第四次迭代--添加功能
    现在我们回过头来看那个单视图的应用,增加一点真实性,我们模拟一下远程服务有一点延时。我们在delegate中使用flash.utils.settimeout来模拟延时。
    通常,当远程服务在处理时,ui会展现一个进度条,禁用一部分控件,让用户明白不能再派发新的请求。在我们的例子中在远程服务在处理的时候,我们会禁用“get quote”按钮。完成这一点很容易,只需要在model对象的stockquote类中增加一个成员ispending,把它定义为一个bool形,这样可以直接应用于绑定。

     

    [bindable]
    public  var ispending : boolean;

     

    增加验证
    我们现在添加对股票报价的验证功能,对于这一点,我们可以使用mx.validators.stringvalidator来完成这一功能。应用中这两个参数共同控制按钮的有效性。这样可以在model对象中设置一个isvalid属性,用于组合这两参数。

    private  function validate() :  void
    {
        isvalid 
    =  ( issymbolvalid  &&   ! ispending );
    }

    issymbolvalid是一个属性,存放stringvalidator的结果。
    在stockmarketpod.mxml中添加mx:stringvalidator这个tag

    < mx:stringvalidator 
        
    minlength ="2"  triggerevent ="change"  
        source
    ="{ symboltextinput }"  property ="text"
        valid
    ="stockquote.validatesymbol( true );"  
        invalid
    ="stockquote.validatesymbol( false );" />


    从视图中直接调用model对象不符合mvc原则,因为视图原则上只能派发事件。但在这个例子中,这样已经足够好了。

    增加格式化
    我们将股票报价以金额的方式进行展示,在stockmarketpod.mxml中增加一个formatter

    < mx:currencyformatter 
        
    id ="standardeuroformatter"   
        currencysymbol
    ="$"  precision ="2" />
    将formatter的结果进行绑定
    < mx:label  text ="{ standardeuroformatter.format( stockquote.laststockquote ) }" />


    现在看一下完整的stockquote类

    package  com.adobe.cairngorm.samples.dashboard.model
    {
        
    public   class  stockquote
        
    {
            [bindable]
            
    public  var laststockquote : number;
            [bindable]
            
    public  var isvalid : boolean;
            [bindable]
            
    public  var statusmessage : string;
                    
            
    private  var _ispending : boolean;
            
    private  var issymbolvalid : boolean;
                    
            [bindable]
            
    public  function get ispending() : boolean
            
    {
                
    return  _ispending;
            }

            
            
    public  function set ispending( value : boolean ) :  void
            
    {
                _ispending 
    =  value;
                validate();
            }

                
            
    public  function validatesymbol( isvalid : boolean ) :  void
            
    {
                issymbolvalid 
    =  isvalid;
                validate();
            }

            
            
    private  function validate() :  void
            
    {
                isvalid 
    =  ( issymbolvalid  &&   ! ispending );
            }
            
        }

    }

    其中ispending属性的值由getstockquotecommand控制

    private  var model : modellocator  =  modellocator.getinstance();
    private  var stockquote : stockquote  =  model.stockquote;
             
    public  function execute( event : cairngormevent ) :  void
    {
        stockquote.ispending 
    =   true ;
                 
        var stockquoteevent : getstockquoteevent 
    =  getstockquoteevent( event );          
        var symbol : string 
    =  stockquoteevent.symbol;
        var delegate : stockmarketdelegate 
    =   new  stockmarketdelegate(  this  );
        delegate.getquoteforsymbol( symbol );    
    }

            
    public  function onresult( event :  *   =   null  ) :  void
    {
        
    // for demo purpose: event would normally be an event object of remote service result.            
        stockquote.laststockquote  =  event as number;            
        stockquote.ispending 
    =   false ;
        stockquote.statusmessage 
    =   "" ;
    }

            
    public  function onfault( event :  *   =   null  ) :  void
    {
        stockquote.laststockquote 
    =  nan;
        stockquote.statusmessage 
    =   " quote retrieval error. " ;
        stockquote.ispending 
    =   false ;
    }

    最后看一下stockmarketpod.mxml的全部代码

    xml version="1.0" encoding="utf-8" ?>
    < mx:panel 
        
    xmlns:mx ="http://www.adobe.com/2006/mxml"
        xmlns:util
    ="com.adobe.cairngorm.samples.dashboard.util.*" >
            
        
    < mx:script >
            

                import com.adobe.cairngorm.control.cairngormeventdispatcher;
                import com.adobe.cairngorm.samples.dashboard.model.stockquote;
                import com.adobe.cairngorm.samples.dashboard.events.getstockquoteevent;    
                
                [bindable]
                public var stockquote : stockquote;
                
                private function getquoteforsymbol() : void
                {
                    var event : getstockquoteevent = new getstockquoteevent( symboltextinput.text );
                    cairngormeventdispatcher.getinstance().dispatchevent( event );
                }
            
    ]]>
        
    mx:script >
        
        
    < mx:currencyformatter 
                    
    id ="standardeuroformatter"   
            currencysymbol
    ="$"  precision ="2" />
            
        
    < mx:stringvalidator 
            
    minlength ="2"  triggerevent ="change"  
            source
    ="{ symboltextinput }"  property ="text"
            valid
    ="stockquote.validatesymbol( true );"  
            invalid
    ="stockquote.validatesymbol( false );" />
        
        
    < mx:form >
        
            
    < mx:formitem  label ="symbol" >
                
    < mx:textinput 
                    
    id ="symboltextinput" />
                
    < mx:button 
                    
    label ="get quote"  
                    enabled
    ="{ stockquote.isvalid }"  
                    click
    ="getquoteforsymbol();" />
            
    mx:formitem >
                    
            
    < mx:formitem  label ="price quote" >
                
    < mx:label  text ="{ standardeuroformatter.format( stockquote.laststockquote ) }" />
                
    < mx:label  text ="{ stockquote.statusmessage }" />
            
    mx:formitem >
            
        
    mx:form >     
    mx:panel >


    此视图中我们不需要使用modellocator,而是使用stockquote作为参数传入stockmarketpod.mxml
    引用视图的代码

    < mx:script >
        

            import com.adobe.cairngorm.samples.dashboard.model.modellocator;
            import com.adobe.cairngorm.samples.dashboard.model.stockquote;
                                        
            [bindable]
            private var model : modellocator = modellocator.getinstance();
            [bindable]
            private var stockquote : stockquote = model.stockquote;    
        
    ]]>
    mx:script >
     
    < view:stockmarketpod 
        
    stockquote ="{ stockquote }"  
        title
    ="stockmarket pod" />

     

    只传递需要的信息给视图是一个比较好的做法,而尽量少使用modellocator这样的全局变量,这样也使用视图重用性更高。



    云自无心水自闲 2006-12-29 00:36
    ]]>
    网站地图