顯示具有 Flex/ActionScript Metadata 標籤的文章。 顯示所有文章
顯示具有 Flex/ActionScript Metadata 標籤的文章。 顯示所有文章

2011年5月26日 星期四

IconFile metadata tag


原文引用自adobe flex4.5 help手冊:
原文:


  • Use the  [IconFile]  metadata tag to identify the filename for the icon that represents the component in the Insert bar of Flash Builder.
功用說明:
  • 讓自己設計的組件使用指定的小圖示顯示於FlashBulider的Components View中。
  • 可以使用的資源有PNG、GIF、JPG。


使用範例:
//測試的Class
package com.test.icon
{
 import spark.components.Button;
 import spark.components.Group;
 import spark.components.TextArea;
 import spark.layouts.VerticalLayout;
 import spark.layouts.supportClasses.LayoutBase;
 
 [IconFile("MyPanel.png")]
 public class MyPanel extends Group
 {  
  public function MyPanel()
  {
   super();
   this.layout = new  VerticalLayout();
  }
  
  override protected function createChildren():void
  {
   super.createChildren();
   if(button == null){
    this.button = new Button();
    this.button.label = "AS";
   }
   
   if(textArea == null){
    this.textArea = new TextArea();
   }   
   this.addElement(button);
   this.addElement(textArea);
  } 
  
  override protected function commitProperties():void
  {
   super.commitProperties();
   if(textAreaChanged==true && textArea!=null)
   {
    textArea.percentWidth = 100;
   }
   if(btnChanged == true && button!=null)
   {
    button.width = 80;  
   }
  }
  
  override protected function measure():void
  {
   super.measure();
  }
  
  override public function set layout(value:LayoutBase):void
  {
   if(super.layout != value)
   {
    super.layout = value;   
   }
  }
  
  private var textAreaChanged:Boolean;
  private var _textArea:TextArea;
  public function get textArea():TextArea
  {
   return _textArea;
  }
  public function set textArea(value:TextArea):void
  {
   if( _textArea != value)
   {
    _textArea = value;
    textAreaChanged = true;
    invalidateProperties();
   }
  }
  
  private var btnChanged:Boolean;
  private var _button:Button;
  public function get button():Button
  {
   return _button;
  }
  public function set button(value:Button):void
  {
   if( _button != value)
   {
    _button = value;
    btnChanged = true;
    invalidateProperties();
   }
  }  
 }
}

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
      xmlns:s="library://ns.adobe.com/flex/spark" 
      xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
      xmlns:icon="com.test.icon.*"
      >
 
 <icon:MyPanel width="300">
  <icon:button>
   <s:Button label="MXML"/>
  </icon:button>
 </icon:MyPanel> 
</s:Application>


結果我怎麼試Icon他就是出不來,我懷疑是不是path錯誤,改了絕對路徑、相對路徑都不行,然後我找尋flex4.5 SDK內的Button.png來驗證Flex本身的Icon圖片放在哪,結果發現是與Class同目錄,因此我也照做,還是不行,最後開了一個獨立的lib庫項目,在專案中引入lib項目就OK了。

因此實際檔案結構如下:
//獨立的lib庫


//Flex測試用的專案



//Flex測試專案中,將將lib加入(使用添加項目)。

如此就可以在組件窗口看到設定的ICON

  • 注意,使用IconFile必須將Class至於獨立的庫項目才能成功。
  • 由查詢SDK中的Button.png得知,預設的圖片使用解析度是18 * 18。

2011年5月25日 星期三

Alternative metadata tag


原文引用自Adobe Flex4.5_help手冊:
原文:

If you want to replace one class with another, mark the class to be replaced with the  [Alternative]  metadata tag. The
[Alternative]  metadata tag specifies the replacement class, and a version number that indicates when the
replacement occurred.

功用說明:
[Alternative]這個metadata標籤用於建議替代的類別與版本,如mx的Button會出現建議使用spark的Button,而在FlashBulider選用Class時可以看到如下圖訊息。










使用範例:
//舊的Cat Class
package com.jef
{
 [Alternative(replacement="com.jt.Cat", since="1.0")]
 /***/ //使用asDoc的註解,說明的asDoc才會出現
 public class Cat
 {
  public function Cat()
  {
  }
 }
}

//新的Cat Class
package com.jt
{
 public class Cat
 {
  public function Cat()
  {
  }
 }
}

//Flex mxml
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
      xmlns:s="library://ns.adobe.com/flex/spark" 
      xmlns:mx="library://ns.adobe.com/flex/mx" 
      minWidth="955" minHeight="600"
      applicationComplete="completeHandler(event)"
      >
 <fx:Script>
  <![CDATA[
   import com.jef.Cat;   
   import mx.events.FlexEvent;   
   protected function completeHandler(event:FlexEvent):void
   { 
    var cat:Cat;
   }   
  ]]>
 </fx:Script> 
</s:Application>

出現提示如下:










Alternative與Deprecated不同,Alternative原本的Class還可使用,只是有更新版本建議使用,而Deprecated則是說明該Class已經廢棄不要再使用。

2011年5月21日 星期六

Flex Remote mapping value Object (Flex 值物件映射)


Mapping Value Object
上次我們在Linux中測試過BlazeDS AMF的remote功能,現在我們來試試看在BlazeDS中的Remote Server回傳的Value Object 來映射 Flex端的Value Object。

ActionScript可使用flash.net.registerClassAlias來做Mapping Value Object:
  • registerClassAlias( "remote端 value object Class path" ,  flash端 value object Class path);
Flex中可使用MetaData tags(後設標籤) 來做Mapping Value Object:
  • [RemoteClass(alias="value object Class path")]
Remote端配置:
Setp1.撰寫Remote端的值物件SongData

//JAVA SongData (值物件)
package com.jt.valueObject;
public class SongData 
{ 
 public SongData()
 {
  super();
 }

 private String _name;
 public String getName() 
 {
  return _name;
 }
 public void setName(String name) 
 {
  _name = name;
 }

 private String _vocalist; 
 public String getVocalist() 
 {
  return _vocalist;
 }
 public void setVocalist(String vocalist) 
 {
  _vocalist = vocalist;
 }

 private String _type; 
 public String getType() 
 {
  return _type;
 }
 public void setType(String type) 
 {
  _type = type;
 }

 private int _length;
 public int getLength() 
 {
  return _length;
 }
 public void setLength(int length) 
 {
  _length = length;
 } 
}


Step2.撰寫Remote Service的類別SongService
//JAVA SongService (服務呼叫API)
package com.jt.remote;
import com.jt.valueObject.SongData;
public class SongService 
{
 public SongService()
 {
  super();
 }
 
 public SongData getSongData()
 {
  SongData data = new SongData();
  data.setName("誰公平");
  data.setVocalist("李威");
  data.setType("Top");
  data.setLength(30000);
  return data;  
 }
}


檔案結構如下圖:










Step3.編譯SongService.java與SongData.java
  • 在你使用Eclipse會幫你編譯這兩隻檔案,你也可以使用命令模式java-d編譯檔案。
  • 命令模式在所在路徑在src時 :
    • javac -d ../classes com/jt/remote/SongService.java
    • javac -d ../classes com/jt/valueObject/SongData.java
Step4.將SongData.class與SongService.class配置到BlazeDS的位置上

  • 將SongService.class放至/opt/tomcat6/webapps/blazedsAMF/WEB-INF/classes/com/jt/remote
  • 將SongData.class放至/opt/tomcat6/webapps/blazedsAMF/WEB-INF/classes/com/jt/valueObject
PS.這是照之前Linux上配置BlazeDS的設定,因此路徑會是這樣,實際請依你的配置路徑,在WEB-INF/classes底下的路徑就是你JAVA的package設定。


Step5.設定BlazeDS的配置檔remoting-config.xml
  • 如果你是跟著我Linux配置BlazeDS文章的話路徑會在opt/tomcat6/webapps/blazedsAMF/WEB-INF/flex/remoting-config.xml
  • sudo gedit opt/tomcat6/webapps/blazedsAMF/WEB-INF/flex/remoting-config.xml
在檔案內容中加入:
<destination id="Remote_GetSong">
  <properties>  
     <source>com.jt.remote.SongService</source>
  </properties>
</destination>

Step6.撰寫Flex程式來測試Mapping
//Flex的值物件SongData ,請參考JAVA中的SongData做比較
package com.jt.valueObject
{ 
 //mapping,alias是指java中valueObject Class的所在路徑。
        [RemoteClass(alias="com.jt.valueObject.SongData")]
 public class SongData
 {
  public function SongData()
  {
   super();
  }
  
  private var _name:String;
  public function get name():String
  {
   return _name;
  }
  public function set name(value:String):void
  {
   if( _name != value)
   {
    _name = value;
   }
  }
  
  private var _vocalist:String;
  public function get vocalist():String
  {
   return _vocalist;
  }
  public function set vocalist(value:String):void
  {
   if( _vocalist != value)
   {
    _vocalist = value;
   }
  }
  
  private var _type:String;
  public function get type():String
  {
   return _type;
  }
  public function set type(value:String):void
  {
   if( _type != value)
   {
    _type = value;
   }
  }
  
  private var _length:int;
  public function get length():int
  {
   return _length;
  }
  public function set length(value:int):void
  {
   if( _length != value)
   {
    _length = value;
   }
  }  
 }
}

//Flex的應用程式
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
      xmlns:s="library://ns.adobe.com/flex/spark" 
      xmlns:mx="library://ns.adobe.com/flex/mx" 
      minWidth="955" minHeight="600"
      applicationComplete="completeHandler(event)"
      >
 <s:layout>
  <s:HorizontalLayout/>
 </s:layout>
 <fx:Script>
  <![CDATA[
   import com.jt.valueObject.SongData;
   
   import flash.net.registerClassAlias;
   
   import mx.events.FlexEvent;
   import mx.messaging.ChannelSet;
   import mx.messaging.channels.AMFChannel;
   import mx.rpc.events.FaultEvent;
   import mx.rpc.events.ResultEvent;
   import mx.rpc.remoting.Operation;
   import mx.rpc.remoting.RemoteObject;
   
   //Remote Operation
   private var _channelSet:ChannelSet;
   private var _amfChannel:AMFChannel;
   
   private var _remoteObject:RemoteObject;  
   private var _operation:Operation;  
   private var _data:Object;   
   
   protected function completeHandler(event:FlexEvent):void
   { 
    
    //as3方式設定mapping (java值物件路徑 , as3值物件類)
    //registerClassAlias("com.jt.valueObject.SongData", SongData);
    initRemoteData();
    initRemoteOpertion();   
    initBtnListener();  
   }   
   private function initRemoteData():void
   {
    _data  = createRemoteData();    
   }   
   protected function createRemoteData():Object
   {    
    var data:Object = new Object();  
    //blazeds的AMF Server Service服務位址
    data.uri = "http://127.0.0.1:8400/blazedsAMF/messagebroker/amf";            
    data.channelSetID = "my-amf"; 
    //服務程式來源path(由classes之後算起) 
    data.source = "com.jt.remote.SongService"; 
    //操作method名稱 
    data.name = "getSongData";  
    data.destination = "Remote_GetSong"; 
    return data;
   }   
   
   private function initRemoteOpertion():void
   {
    initChannelSet();
    initAMFChannel();
    addChannel();
    initRemoteObject();
    initOperation();
    afterInitOPeration();
   }   
   private function initChannelSet():void
   {    
    _channelSet = new ChannelSet(); 
   }
   private function initAMFChannel():void
   {
    _amfChannel = new AMFChannel(_data.channelSetID , _data.uri); 
   }
   private function addChannel():void
   {
    _channelSet.addChannel(_amfChannel); 
   }
   private function initRemoteObject():void
   {    
    _remoteObject = new RemoteObject();
    _remoteObject.destination = _data.destination;
    _remoteObject.channelSet = _channelSet; 
    _remoteObject.source  = _data.source;    
   }
   
   private function initOperation():void
   {    
    _operation = new Operation();
    _operation.name = _data.name;      
   }
   private function afterInitOPeration():void
   {
    _remoteObject.operations  = {getSongData:_operation};    
    _remoteObject.addEventListener(ResultEvent.RESULT , onResult);
    _remoteObject.addEventListener(FaultEvent.FAULT , onFault);      
   }    
   
   protected function onResult(e:ResultEvent):void
   { 
    var v:SongData; //有這行 ,後設標籤的mapping就會成功, 如果沒有這行 就沒辦法mapping,很怪異。    
    output.text = e.result.toString();
   }
   
   protected function onFault(e:FaultEvent):void
   { 
    output.text = "Remote失敗";
   }   
   
   private function initBtnListener():void
   {
    btn.addEventListener(MouseEvent.MOUSE_DOWN , callGetSongData);    
   }   
   protected function callGetSongData(event:MouseEvent):void
   { 
    _remoteObject.getSongData();    
   }     
  ]]>
 </fx:Script> 
 <s:Panel width="300" height="200" title="ValueTest">
  <s:layout>
   <s:VerticalLayout/>
  </s:layout>  
   <s:TextArea id="output" width="100%" height="100%"/>        
 </s:Panel>
 <s:Button id="btn" label="call getSongData"/> 
</s:Application>


  • 執行應用程式前記得,要把tomcat運作起來
  • 我們在onResult(e:ResultEvent)中下斷點以便觀察e.result
  • 執行應用程式
  • 點擊瀏覽畫面上的Button
我們可以看到,e.result為一個SongData,代表mapping成功









然後我們將onResult(e:ResultEvent)中的var v:SongData;給註解掉,然後再執行一次應用程式,你會發現e.result竟然變成ObjectProxy了,代表mapping失敗。





至於為什麼會這樣,目前還不知道,但若使用flash.net.registerClassAlias來做mapping則沒有這樣的問題。

registerClassAlias的用法:
  • registerClassAlias("com.jt.valueObject.SongData", SongData);
第一個參數是Remote端中,值物件的所在路徑。
第二個參數是Flex端中,值物件的類。

registerClassAlias方式是flashPlayer API因此flash、Flex都可使用。

你可以將應用程式中的registerClassAlias("com.jt.valueObject.SongData", SongData);拿掉註解,然後將SongData的[RemoteClass(alias="com.jt.valueObject.SongData")]註解掉,測試一下。

2010年8月20日 星期五

Deprecated metadata tag



用法:
[Deprecated("string_describing_deprecation")]
[Deprecated(message="string_describing_deprecation")]
[Deprecated(replacement="string_specifying_replacement")]
[Deprecated(replacement="string_specifying_replacement", since="version_of_replacement")]

原文(引用自adobe flex4 help):
A class or class element marked as deprecated is one which is considered obsolete, and whose use is discouraged in the current release. While the class or class element still works, its use can generate compiler warnings

一個類別或是類別中的項目被標記成Deprecated表示此項目是過時的、廢棄的、不建議使用的,不鼓勵使用在當前的釋出版本。雖然被宣告廢棄的Class或Class中的項目仍然工作,但能讓編譯器產生警告提醒。

The mxmlc command-line compiler supports the show-deprecation-warnings compiler option, which, when true, configures the compiler to issue deprecation warnings when your application uses deprecated elements. The default value is true.

Insert the [Deprecated] metadata tag before a property, method, or class definition to mark that element as deprecated. The [Deprecated] metadata tag has the following options for its syntax when used with a class, property or method:
 
功用:

  • 標記已經廢棄的Class以免誤用,若使用編譯器會出現警告提醒。
範例:
//宣告method已經廢棄,並提示改用建議的method
package com
{
 import spark.components.Group;
 public class MyDeprecatedGroup extends Group
 {
  public function MyDeprecatedGroup()
  {
   super();
  }  
  private var _topGap:Number; 
  //宣告topGap廢棄,並建議使用topPixels
  [Deprecated(replacement="MyDeprecatedGroup.topPixels")] 
  public function set topGap(value:Number):void
  {
   _topGap = value;
  }
  public function get topGap():Number
  {
   return _topGap;
  }
 }
}  
//Application
<?xml version="1.0" encoding="utf-8"?> 
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
xmlns:s="library://ns.adobe.com/flex/spark" 
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
applicationComplete="application1_applicationCompleteHandler(event)" xmlns:com="com.*"
>
<fx:Script\>
<![CDATA[ 
]]>
</fx:Script>
<com:MyDeprecatedGroup>
 <com:topGap>1.0</com:topGap>  
</com:MyDeprecatedGroup>
</s:Application>   
訊息警告如下圖:
 
 
 
 
 
 

  • Event,Effect,Style,metadata tags也支援 deprecation功能

文件
The [Event], [Effect] and [Style] metadata tags also support deprecation. These tags support the following options for syntax:
 
在Event,Effect,Style的metadata tags中,也都支持deprecation的宣告,用法如下
 
用法
[Event(... , deprecatedMessage="string_describing_deprecation")]
[Event(... , deprecatedReplacement="change2")]
[Event(... , deprecatedReplacement="string_specifying_replacement", deprecatedSince="version_of_replacement")]

DefaultProperty metadata tag


用法:
[DefaultProperty("propertyName")]

原文:
The [DefaultProperty] metadata tag defines the name of the default property of the component when you use the component in an MXML file.

功用說明:
[DefaultProperty]標籤用來定義組件中的預設屬性,對應於MXML標籤檔上使用。

範例:
//這個範例將預設屬性改成selected,原本在toggleButtong上的預設屬性是label。
//myButton.as
package com
{

 import spark.components.ToggleButton;

 [DefaultProperty("selected")]
 public class myButton extends ToggleButton
 {
  public function myButton()
  {
   super();
  }
//mxml設定進來的值在此可以抓到並處理
  override public function set selected(value:Boolean):void
  {
   if(value != super.selected)
   super.selected = value;
  } 

 }

}
//mxml檔中使用ToggleButton與myButton來驗證結果
<s:Group layout="{new VerticalLayout()}">
<s:ToggleButton>true</s:ToggleButton> //預設屬性是label因此會出現true
<com:myButton>true</com:myButton>     //預設屬性是selected因此出現按下
</s:Group>












例外使用的狀況:
The one place where Flex prohibits the use of a default property is when you use the ActionScript class as the root tag of an MXML component. In this situation, you must use child tags to define the property, as the following example shows

主要是說,若是mxml做為根標籤,就無法直接在標籤中輸入文字使用預設值,而是須將改預設值名稱當成mxml標籤來呼叫使用。

當然這就是在說將Class做成mxml組件檔時的情境,範例如下:
//myButtonC.mxml
<?xml version="1.0" encoding="utf-8"?>
<com:myButton xmlns:fx="http://ns.adobe.com/mxml/2009" 
xmlns:s="library://ns.adobe.com/flex/spark" 
xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:com="com.*">
<!--當成root標籤使用時,預設屬性設定改用標籤呼叫設定。-->
 <com:selected>true</com:selected>
</com:myButton> 

而這個組件放於Application上時,依然可以直接設定預設值如下:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
xmlns:s="library://ns.adobe.com/flex/spark" 
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
xmlns:com="com.*"
> 
<fx:Script>
<![CDATA[ 
import spark.layouts.VerticalLayout;
]]>
</fx:Script>
<s:Group layout="{new VerticalLayout()}">
<com:myButtonC>true</com:myButtonC>
</s:Group>
</s:Application>


參考
http://help.adobe.com/zh_CN/flex/using/WS2db454920e96a9e51e63e3d11c0bf680e1-7ffe.html

//查詢Creating a default property
http://help.adobe.com/zh_CN/flex/using/WS2db454920e96a9e51e63e3d11c0bf69084-79f7.html#WS2db454920e96a9e51e63e3d11c0bf69084-79fa

英文原文引用自adobe flex4 help文件

2010年8月19日 星期四

ArrayElementType Metadata tag


原文:
Using Flex4說明手冊中關於ArrayElementType的說明:
When you define an Array variable in ActionScript, you specify Array as the data type of the variable. However, you cannot specify the data type of the elements of the Array.

當你於ActionScript中定義一個Array變數,你指定Array為資料型態,然而你無法指定Array內項目的資料型態。
(在AS3中Vector可以指定陣列中項目的資料型態,Array本身沒有此項功能)

功用:
To allow the Flex MXML compiler to perform type checking on Array elements, you can use the [ArrayElementType] metadata tag to specify the allowed data type of the Array elements, as the following example shows:

你可以藉由ArrayElementType這個metadata tag讓MXML compiler來檢查Array的項目元素是否為ArrayElementType指定資料格式的項目。

使用範例:
//Class
package com
{ 
 import spark.components.Group;
 public class myGroup extends Group
 {
  public function myGroup()
  {
   super(); 
  } 
  //標籤宣告
  [ArrayElementType("Number")]
  public var myArray:Array; 
 }
}

//mxml檔案中
<com:myGroup id="mg">
<com:myArray>
<fx:int>1.0</fx:int>   //此處會有編譯錯誤警告,因為使用<int>
</com:myArray>
</com:myGroup>   
note:
在mxml中若是對myArray使用非Number的項目就會出像錯誤警告,但是此項功能僅對於MXML標籤有作用,若你使用ActionScript來對myArray來操作,並加入非Number資料型態的項目並不會出像編譯警告。
  •  ArrayElementType("Number")]的宣告對ActionScript直接操作是無效的
//在application Complete事件發生後去操作myArray,並給予非Number的項目,是可以通過編譯的
protected function application1_applicationCompleteHandler(event:FlexEvent):void 
{
 mg.myArray.push( "test" );
}