云自无心水自闲

天平山上白云泉,云自无心水自闲。何必奔冲山下去,更添波浪向人间!
posts - 288, comments - 524, trackbacks - 0, articles - 6
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

The major change to this release is how Cairngorm 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中。

posted @ 2007-01-25 21:08 云自无心水自闲 阅读(1194) | 评论 (2)编辑 收藏

首先在这个版本中,修正了数百个Bug

1. 添加对Mac的支持
2. 支持Eclipse 3.2,而不是仅仅支持3.1
3. 运行时的CSS支持
4. 增加了一个Mercury的插件,支持自动测试
5. 其他一些很棒的功能:包括FlashType的字体和ASDoc的支持。

posted @ 2007-01-21 13:54 云自无心水自闲 阅读(500) | 评论 (0)编辑 收藏

1. 要把database.properties和mail.properties拷贝到build/classes
2. 要在数据库中建立test用户
3. ant db-create建立数据库
4. ant db-prepare建立数据表
5. ant db-load 将数据插入到数据表中
6. 修改myapp\build\classes\META-INF目录中的applicationContext-hibernate.xml
添加
    <bean id="propertyConfigurer"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location"><value>database.properties</value></property>
    </bean>

    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName">
            <value>${hibernate.connection.driver_class}</value>
        </property>
        <property name="url">
            <value>${hibernate.connection.url}</value>
        </property>
        <property name="username">
            <value>${hibernate.connection.username}</value>
        </property>
        <property name="password">
            <value>${hibernate.connection.password}</value>
        </property>
    </bean>
7. 修改myapp\build\class\META-INF目录下的applicationContext-service.xml
将其中的mail.host, mail.username, mail.password, mail.default.from
三个变量修改成合适的值
8. ant deploy
9. 启动tomcat, http://localhost:8080/myapp
10. 输入mraible,密码tomcat,进入系统

posted @ 2007-01-17 01:50 云自无心水自闲 阅读(363) | 评论 (1)编辑 收藏

这个函数只是一个示例函数,演示如何遍历一个Tree。
此函数严格说起来其实是两个函数:上半部分用于回溯父节点,下半部分递归遍历子节点

/**
 * This method will traverse a Tree's model independent of it's
 * type.
 *
 * <p>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.</p>
 *
 * <p>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.</p>
 *
 * @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();
                }
            }
        }
    }
}
 



 

posted @ 2007-01-07 14:37 云自无心水自闲 阅读(3476) | 评论 (1)编辑 收藏

 

在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();
      }
   }
}
然后就可以使用这个作为标签了。
<util:Observe source="{ model.myProperty }"
              handler="{ this.myFunction }"/>
使用了这样的一个标签后,今后嘦是对model.myProperty进行赋值,就会调用myFunction
这个号称世上最小的标签是不是很好用啊?

posted @ 2007-01-07 02:15 云自无心水自闲 阅读(1081) | 评论 (4)编辑 收藏

现在我们将增加验证、格式化和一些其他的功能。
第四次迭代--添加功能
现在我们回过头来看那个单视图的应用,增加一点真实性,我们模拟一下远程服务有一点延时。我们在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 >
        
<![CDATA[
            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 >
    
<![CDATA[
        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这样的全局变量,这样也使用视图重用性更高。

posted @ 2006-12-29 00:36 云自无心水自闲 阅读(906) | 评论 (0)编辑 收藏

上次介绍了如何在业务逻辑中改变视图,这次讲解一种新方法。我们的股票市场显示图将扩展为多股票报价查询器。我们将看到业务逻辑是怎么调整每个视图的。而且我们还会接触到无状态命令是怎么使得事情变得简单。
第三次迭代--创建业务逻辑管理多视图
我们经常可以发现会有很多个类型一样的视图,其背后的功能也非常类似。每个视图显示一个Model对象。这些视图可以在开始时从管理对象处请求一个Model对象。比如:我们的StockMarketDashboard.mxml可以进行这样的添加:

< view:StockMarketPod 
    
quoteId ="quote1"  
    title
="Stockmarket first pod" />
< view:StockMarketPod 
    
quoteId ="quote2"  
    title
="Stockmarket second pod" />
< view:StockMarketPod 
    
quoteId ="quote3"  
    title
="Stockmarket third pod" />
< view:StockMarketPod 
    
quoteId ="quote4"  
    title
="Stockmarket fourth pod" />

注意:视图需要传递一些唯一的标识,我们将这些标识添加到StockQuote类。

package  org.nevis.cairngorm.samples.dashboard.model
{
    
public   class  StockQuote
    
{
        [Bindable]
        
public  var lastStockQuote : Number;
        [Bindable]
        
public  var stockQuoteError : String;        
    }

}


管理对象StockQuoteManager,在ModelLocator实例中初始化。但是StockQuoteManager会是一个怎样的对象呢?
通常我使用Hashmap来实现,其键值就是视图中的唯一标识符。在构造函数中我们可以初始化这个Hashmap,Flex2中我们使用flash.utils.Dictionary

public  function StockQuoteManager() 
{
    stockQuotes 
=   new  Dictionary();
}


getStockQuote方法返回一个stockQuote对象

public  function getStockQuote( quoteId : String ) : StockQuote
{
    var key : String 
=  quoteId;
    
if ( stockQuotes[ key ]  ==   null  )
    
{
        var stockQuote : StockQuote 
=   new  StockQuote();
        stockQuotes[ key ] 
=  stockQuote;
    }

    
return  StockQuote( stockQuotes[ key ] );
}


StockMarketPod.mxml几乎没有什么改动。只需要将那个唯一的标识符发送给命令,因为命令需要从管理对象处取得StockQuote对象。所以GetStockQuoteEvent类多了一个quoteId属性。
在GetStockQuoteCommand中,需要将唯一标识符保存在一个成员变量中

private  var model : ModelLocator  =  ModelLocator.getInstance();
private  var quoteId : String;
         
public  function execute( event : CairngormEvent ) :  void
{
    var stockQuoteEvent : GetStockQuoteEvent 
=  GetStockQuoteEvent( event );             
    var symbol : String 
=  stockQuoteEvent.symbol;
    quoteId 
=  stockQuoteEvent.quoteId;
    var delegate : StockMarketDelegate 
=   new  StockMarketDelegate(  this  );
    delegate.getQuoteForSymbol( symbol );
}

        
public  function onResult( event : ResultEvent  =   null  ) :  void
{
    
// simulate a result from service
    var lastStockQuote : Number  =  Math.random()  *   50   +   5 ;
    var stockQuote : StockQuote 
=  model.stockQuoteManager.getStockQuote( quoteId );
    stockQuote.lastStockQuote 
=  lastStockQuote;
    stockQuote.stockQuoteError 
=   "" ;
}

        
public  function onFault( event : FaultEvent  =   null  ) :  void
{
    var stockQuote : StockQuote 
=  model.stockQuoteManager.getStockQuote( quoteId );
    stockQuote.lastStockQuote 
=  NaN;
    stockQuote.stockQuoteError 
=   " An error occured. " ;
}

注意一下,在上面的代码中我们使用的是无状态命令,在Cairngorm的说明中,无状态命令是每次Cairngorm事件的响应都创建一个新的命令实例的方式。因此,在这种方式中我们可以放心地把变量存储在成员变量中,而不用担心被其他人改变。

posted @ 2006-12-28 00:50 云自无心水自闲 阅读(704) | 评论 (0)编辑 收藏

当服务端或者客户端的逻辑变化后,有很多种方法来更新视图。我比较推荐使用ModelLocator策略,主要是使用Flex的绑定功能。
通常你的视图与ModelLocator的属性绑定,这些属性可以由命令或者其他的业务逻辑或者其他视图所改变。而一旦这些属性发生了变化,所有与它们绑定的视图都随之变化。
因为很多的Cairngorm的例子都想做得浅显易懂,因此经常是简单地将这些属性做为ModelLocator中的一个暴露给外界的成员变量。而当Cairngorm的应用变得庞大的时候,这往往是不够的。在此我将会专门针对这个问题展示一个例子。这个例子是一个股票市场的显示表。
第一次迭代:将应用运转起来
首先看一下Cairngorm所主张的MVC模式。目前股票市场显示表将只包含一些简单的UI控制。点击“GetQuote”来派发Cairngorm事件,调用命令来请求一个新报价。StockMarketPod.mxml中在Button的Click事件中派发Cairngorm事件。

< mx:Button  label ="Get Quote"  click ="getQuoteForSymbol();" />

相应的脚本代码:

 
import org.nevis.cairngorm.samples.dashboard.events.GetStockQuoteEvent;                                    
private function getQuoteForSymbol() : void
{
    var event : GetStockQuoteEvent 
= new GetStockQuoteEvent( symbolTextInput.text );
    dispatchEvent( event );
}

GetStockQuoteCommand响应并处理这个Cairngorm事件,请求一个业务代理类来报价。

public function execute( event : CairngormEvent ) : void
{
    var symbol : String 
= GetStockQuoteEvent( event ).symbol;
    var delegate : StockMarketDelegate 
= new StockMarketDelegate( this );
    delegate.getQuoteForSymbol( symbol );
}


在实际情况中,需要进行一个远程的服务器端的调用,在Demo中,为简化起见,我注释掉了远程调用的相关代码。这里StockMarketDelegate.as只是对命令进行回调。

public function StockMarketDelegate( responder : Responder )
{
    
//disabled for demo
    
//this.service = ServiceLocator.getInstance().getService( "stockMarketDelegate" );
    this.responder = responder;
}

        
public function getQuoteForSymbol( symbol : String ) : void
{
    
//disabled for demo
    
//var call : AsyncToken = service.getQuoteForSymbol( symbol );
    
//call.resultHandler = responder.onResult;
    
//call.faultHandler = responder.onFault;
    if( symbol == "fail" )
    
{
        responder.onFault();
    }

    
else
    
{
        responder.onResult();
    }

}

我们的StockMarketPod视图只需要两条消息,
1. 股票的报价
2. 错误消息
因为现在是第一次迭代过程中,处理比较简单,因此使用ModelLocator的成员来解决。

public var lastStockQuote : Number;
public var stockQuoteError : String;


在此Demo中,GetStockQuoteCommand命令模拟返回相应的结果。

public function onResult( event : ResultEvent = null ) : void
{
    
//simulate a result from service
    var stockQuote : Number = Math.random() * 50 + 5;
    model.lastStockQuote 
= stockQuote;
    model.stockQuoteError 
= "";
 }

        
public function onFault( event : FaultEvent = null ) : void
{
    model.lastStockQuote 
= NaN;
    model.stockQuoteError 
= "An error occured.";
}

StockMarketPod视图绑定这些成员并进行一些格式化的处理。

<mx:FormItem label="Symbol">
    
<mx:Label text="{ formatQuote( model.lastStockQuote ) }"/>
</mx:FormItem>
<mx:FormItem>
    
<mx:Label text="{ model.stockQuoteError }"/>
</mx:FormItem>

格式化函数的脚本

private function formatQuote( quote : Number ) : String
{
    
return ( isNaN( quote ) ) ? "" : String( quote );
}


现在我们来进行重构并将一些功能从视图中抽取出来到一个可以进行单元测试的工具类中。

第二次迭代,创建符合需求的业务逻辑
现在我们已经有一个可以运行的最简单的应用。当你的应用变得庞大后,将会有很多的限制。你会发现你的ModelLocator非常的臃肿,以致于有时候,你都找不到你所要的成员。甚至会有命名冲突的事情发生。
一个普通的重构方法是封装你的用例图中的成员成为一个业务对象。这个业务对象能够表达业务上下文中需要的视图信息。你可以把业务对象设计得最适合用例图的粒度。在一个大型的应用中,你可能会设计一系列的业务对象来表达你的用例。你的视图将会绑定这些对象或者这些对象的属性上。通过这种方法,ModelLocator与其目标之间的联系更容易,开发者更容易掌握业务逻辑所包含的内容。
在这个Demo中,我们可以把astStockQuote和stockQuoteError这两个成员封装到一个业务对象中。

package org.nevis.cairngorm.samples.dashboard.model
{
    
public class StockQuote
    
{
        [Bindable]
        
public var lastStockQuote : Number;
        [Bindable]
        
public var stockQuoteError : String;
    }

}


这样在ModelLocator中,我们只需要定义一个成员
public var stockQuote : StockQuote = new StockQuote ();
我们的视图也相应修改为:

<mx:FormItem label="Symbol">
    
<mx:Label text="{ formatQuote( model.stockQuote.lastStockQuote ) }"/>
</mx:FormItem>
<mx:FormItem>
    
<mx:Label text="{ model.stockQuote.stockQuoteError }"/>
</mx:FormItem>

posted @ 2006-12-27 01:31 云自无心水自闲 阅读(1784) | 评论 (0)编辑 收藏

1、www.FlashDevelop.com网站最近发布了FlashDevelop2.0.2,其中增加了对Flex2的支持。
2、下面介绍一下使用的方法。我用的是一个笔记本,只有一个C盘,所有安装路径都在C盘。
3、首先是下载FlashDevelop2.0.2(以下简称FD),我安装在c:\program files\flashdevelop目录下。
还要注意下载安装JDK5,和.net framework1.1(这个程序是用C#开发的)
4、再下载Flex2 SDK,从www.flex.org的左上角可以找到,好象要在Adobe公司里注册一下。
下载完毕后,解压缩,我是放在c:\flex_2_sdk目录下。
  运行FD,按F9进入程序设置,找到ASCompletion.Flex2SDK.Path这个选项,把它的值设为SDK的路径。
我这里就是C:\Flex_2_SDK
5、下载AS3 Intrinsic Classes URL Address我把它解压缩在C:\Program Files\FlashDevelop\Library目录下
6、下载
AS3 top-level declaration解压缩在C:\Program Files\FlashDevelop
在FD中的程序设置(Program Setting)中设置
ASCompletion.Macromedia.Classpath的值为此路径,
设置
ASCompletion.MTASC.UseStdClasses的值为False
7、下载
the MXML definition file这解压缩在C:\Program Files\FlashDevelop\Data目录下

到此步骤,FD的安装基本告一段落。

下面就可以新建项目了,为方便起见
8、下载项目模板 http://www.bit-101.com/flashdevelop/ProjectTemplates.zip,解压缩到C:\Program Files\FlashDevelop\Data\ProjectTemplates目录下。
9、重新启动FD,新建项目,选择Flex模板。在右边会看到deploy、html_template, src三个目录和build.properties, build.xml两个文件,src目录下有一个app.mxml的空文件。
至此,项目的目录框架搭建完成。下面就是要编译生成SWF文件了。

10、对于编译生成SWF文件有好几种方式,在此介绍两种,一种是FD开发者提供了,使用MSASC,一种是使用Ant。第一种速度奇块,但是设置比较复杂,第二种速度较慢,比较方便。
11、如果使用第一种,就需要在每个文件的头部添加东西
AS文件头添加
/**
* @mxmlc -default-size 400 300 -incremental=true
*/
mxml文件头添加
<!-- @mxmlc -default-size 400 300 -incremental=true -->
12、如果是用第二种方法,首先要装Ant,这个大家可能都有。
13、然后修改Build.properties文件,把里面的一些路径改一下。比如:flex2.dir
14、然后到C:\Program Files\FlashDevelop\Settings目录下找到Toolbar.xml
添加一行
<button label="ANT Build" click="PluginCommand" image="54" tag="Run;SaveAll;ant" shortcut="F7" />
15、重新启动FD,在工具条上看见多了一个图标,直接点这个按钮,或者按F7,就可以调用Ant生成SWF文件了。而且Swf文件的显示就是在FD集成环境里面的。第一种方式是在外部启动一个IE显示Swf的。

posted @ 2006-12-23 02:42 云自无心水自闲 阅读(5185) | 评论 (0)编辑 收藏

现在最新的版本是2.02, 主页: http://www.ariaware.com
 
结构框架图:



images\ebx_144215778.jpg

看得出: 这个框架与Cairngorm非常的相似, 但是进行了相当的简化.

Controller + Command + ServiceLocator 这三驾马车还在.
Cairngrom中的Model, EventDispatcher, Delegate都不存在了.
ViewHelper和ViewLocator被ArpForm所取代.
对于初学者来说,这个简化版的可能更容易被接受吧.

posted @ 2006-12-16 02:02 云自无心水自闲 阅读(1181) | 评论 (0)编辑 收藏

仅列出标题
共29页: First 上一页 20 21 22 23 24 25 26 27 28 下一页 Last