[Flex][Flex2開発ガイド] 3章 MXMLのシンタックス

この章でMXMLの基本をマスターするようですね。
ここをちゃんとやっておけばとりあえずMXMLは読めるようになるのかな?

基本的なシンタックス

MXMLタグは、ActionScript3のクラス、そのプロパティに対応するらしい。
これは、前回の中間ActionScriptファイルを見れば分かりますね。

MXMLファイルの命名

MXMLのファイル名は下記のルールに従うらしい。

  • ActionScriptの識別子として有効であること。英字or_(下線)で始まり、英数字と_だけで構成されること。
  • 存在するActionScriptコンポーネントid、"application"と一致してはならない。mx名前空間に含まれるMXMLタグの名前もNG。
  • ファイル名は拡張子:"mxml"をつけること

1つ目、3つ目はそうだよねーって感じなので、2つめだけ試してエラーを確認してみますか。

まずは、idと一致した場合、

<?xml version="1.0" encoding="UTF-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    xmlns:explorer="*" width="100%" height="100%" pageTitle="hoge">

    <mx:Button id="hoge"></mx:Button>

</mx:Application>

これをコンパイルすると、

mxmlc:
    [mxmlc] Loading configuration file C:\Flex\flex3sdk_b1_061107\frameworks\flex-config.xml
    [mxmlc] This beta will expire on Wed Oct 31 00:00:00 JST 2007.
    [mxmlc] C:\Flex\workspaces\workspace_study\3.MXMLのシンタックス\src\main\mxml\hoge.mxml(5): Error: 'hoge': identifier and class may not have the same name.
    [mxmlc] <mx:Button id="hoge"></mx:Button>

エラーですねー。

じゃ、次はapplcationと同じにしてみましょう。上のhoge.mxmlをapplication.mxmlに変更してコンパイルすると・・・

mxmlc:
    [mxmlc] Loading configuration file C:\Flex\flex3sdk_b1_061107\frameworks\flex-config.xml
    [mxmlc] This beta will expire on Wed Oct 31 00:00:00 JST 2007.
    [mxmlc] build/application.swf (139044 bytes)
BUILD SUCCESSFUL

ん?!コンパイルできちゃいました?
なぜなんだろう??疑問ですねー。ま、通常こんな名前は付けないので、私としては問題ないのですがね。

次にapplicationではなく、mx名前空間に含まれるMXMLタグの名前"Button"で試してみましょう。
やり方もapplicationの場合と同じです。

mxmlc:
    [mxmlc] Loading configuration file C:\Flex\flex3sdk_b1_061107\frameworks\flex-config.xml
    [mxmlc] This beta will expire on Wed Oct 31 00:00:00 JST 2007.
    [mxmlc] build/Button.swf (139049 bytes)
BUILD SUCCESSFUL


おや、これもOKですか?
よく分かりません。ま、試してるのがFlex3 SDKだからいけないのでしょうか?

あと、ActionScriptについてはまだ私のスキルが追いつかないので・・・*1

ActionScriptクラスを表すタグの使用

ActionScriptクラスに対応するMXMLタグのお話。同じ命名規則
で、タグのプロパティはクラスのプロパティ、イベントに対応するっと。

コンポーネントプロパティの設定

プロパティの2通りの書き方ですね。

<?xml version="1.0" encoding="UTF-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    xmlns:explorer="*" width="100%" height="100%"
    pageTitle="Property">

    <!-- Labelのプロパティはタグ属性で指定することができる -->
    <mx:Label id="label1" width="50" text="label1"></mx:Label>

    <!-- また、子タグで指定することもできる -->
    <mx:Label id="label2">
        <mx:width>100</mx:width>
        <mx:text>label2</mx:text>
    </mx:Label>

    <!-- まぜてもOK -->
    <mx:Label id="label3" width="200">
        <mx:text>label3</mx:text>
    </mx:Label>

</mx:Application>

ここで指定するActionScriptのクラスのプロパティ名称と子タグ、
タグ属性は一致する必要があるみたいですね。

数字と文字列かは、いい感じで判別してくれるみたいですね。

デフォルトプロパティの設定

Flexコンポーネントにはデフォルトプロパティに指定されているプロパティがあるらしい。
これは必須でないので、デフォルトプロパティが指定されてないものもある。

コンポーネントにデフォルトプロパティが指定されていると、
MXMLの記述が少しだけ簡単(直感的?)になるということですね。
ま、デフォルトプロパティが存在するコンポーネントでどんな風に書けるのか試してみましょう。

まずは、コンポーネントを探します。ActionScriptのリファレンスを見てみましょう。
リファレンスの中にある"Default MXML Property"という記述で探せると思います?!

うーん、思ったより出てこないですね。Labelとかにもついているのかと思いきや、
デフォルトプロパティは設定されていないんですね。

仕方ないのでドキュメント通りのComboBoxで試してみましょう。

<?xml version="1.0" encoding="UTF-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    xmlns:explorer="*" width="100%" height="100%"
    pageTitle="default property">

    <!-- いつもどおり、子タグで指定 -->
    <mx:ComboBox id="combo1">
        <mx:dataProvider>
            <mx:ArrayCollection>
                <mx:String>foo</mx:String>
                <mx:String>bar</mx:String>
            </mx:ArrayCollection>
        </mx:dataProvider>
    </mx:ComboBox>

    <!-- デフォルトは子タグを省略することができる -->
    <mx:ComboBox id="combo2">
        <mx:ArrayCollection>
            <mx:String>foo</mx:String>
            <mx:String>bar</mx:String>
        </mx:ArrayCollection>
    </mx:ComboBox>

</mx:Application>

なんてことはないですね。ただ、私なら省略しないと思うので、不要かな?!

円記号のエスケープ

この章でもっとも重要だと思われるところですね。
何しててもエスケープの問題は必ず出てきます。

まずは、"{"や"}"をプロパティにセットしたい場合はというと、

<?xml version="1.0" encoding="UTF-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    xmlns:explorer="*" width="100%" height="100%"
    pageTitle="Escape1">

    <mx:Label text="中括弧を表示=> \{ \}"></mx:Label>

</mx:Application>

円記号(バックスラッシュ)"\"でエスケープしてあげればいいんですね。
実際にどんなActionScriptになったかというと、

  • Escape1-generated.asの抜粋
private var _documentDescriptor_ : mx.core.UIComponentDescriptor = 
new mx.core.UIComponentDescriptor({
  type: mx.core.Application
  ,
  propertiesFactory: function():Object { return {
    childDescriptors: [
      new mx.core.UIComponentDescriptor({
        type: mx.controls.Label
        ,
        propertiesFactory: function():Object { return {
          text: "中括弧を表示=> { }"
        }}
      })
    ]
  }}
})

見事に円記号(バックスラッシュ)は取れていますね。

じゃ、円記号はどのように出力されるのでしょう。

<?xml version="1.0" encoding="UTF-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    xmlns:explorer="*" width="100%" height="100%"
    pageTitle="Escape1">

    <mx:Label text="円記号(バックスラッシュ)を表示=> \"></mx:Label>

</mx:Application>

なんか、一つでいいみたい。このときのActionScript

  • Escape2-generated.asの抜粋
private var _documentDescriptor_ : mx.core.UIComponentDescriptor = 
new mx.core.UIComponentDescriptor({
  type: mx.core.Application
  ,
  propertiesFactory: function():Object { return {
    childDescriptors: [
      new mx.core.UIComponentDescriptor({
        type: mx.controls.Label
        ,
        propertiesFactory: function():Object { return {
          text: "円記号(バックスラッシュ)を表示=> \\"
        }}
      })
    ]
  }}
})

お?円記号(バックスラッシュ)が2つになってますね。
これはActionScriptでは"\\"を"\"の文字と認識するためだそうです。

そのため、mxmlcmxmlActionScriptにするとき、
"\{"とかの場合は"{"がActionScriptでは無害なので、"\"をとったActionScriptを作成するのでしょう。

しかし、"\"については、ActionScriptエスケープ記号になっているので、
ActionScripto的に"\"と解釈する"\\"に変換してるんですね。

じゃ、あと気になるのはScriptタグの中ではどうなのか?改行とかは?ってところでしょうか?

まずはActionScriptタグ。

<?xml version="1.0" encoding="UTF-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    xmlns:explorer="*" width="100%" height="100%"
    pageTitle="Escape3">
    
    <mx:Script>
        [Bindable]
        public var text1:String = "円記号=>\\";
    </mx:Script>

    <mx:Label text="{text1}"></mx:Label>

</mx:Application>

Scriptタグの中は、そのままActionScriptに入れられるので、
ActionScriptの記述方法に従えばいいみたいですね。

ちなみに生成されるActionScriptは、

  • Escape3-generated.asの抜粋
		super.initialize();
	}


        [Bindable]
        public var text1:String = "円記号=>\\";
    



    //	supporting function definitions for properties, events, styles, effects

	//	binding mgmt
    private var _bindings:Array;

では、次に改行。どうもこの改行、MXMLでは一筋縄ではいかないようです。
ドキュメントには、改行を下のコードでかいてくれって言ってます。

&#13;

もう一つの方法は、Scriptタグで"\n"として、それを使ってくれと・・・。
この記述を子タグとかタグ属性で指定できないっぽいですねー。

<?xml version="1.0" encoding="UTF-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    xmlns:explorer="*" width="100%" height="100%" pageTitle="Escape4">

    <mx:TextArea text="改行\n改行"></mx:TextArea>

    <mx:TextArea text="改行&#13;改行"></mx:TextArea>

</mx:Application>

この例でも、上のほうはそのまま"改行\n改行"って表示されています。
いつも慣れた形("\n")で改行を使いたいならば、
Scriptタグを使ってバインドして使いなさいってことですかね。

MXMLでのスタイルプロパティとエフェクトプロパティの設定

どうもこの2つのプロパティはActionScriptクラスのプロパティではないって言うことだそうです。
で、Scriptタグの中で簡単に設定しても反映されないよってことらしい。
Scriptタグで行うには、setStyle(スタイル名,値)といったように指定しなければならないみたい。

  • StyleAndEffect.mxml
<?xml version="1.0" encoding="UTF-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    xmlns:explorer="*" width="100%" height="100%"
    pageTitle="StyleAndEffect" creationComplete="init();">

    <mx:Script>
        public function init():void {
            // この指定はエラーになります。
            //label1.color = "blue";
            label2.setStyle("color", "blue");
        }
    </mx:Script>

    <mx:Label id="label1" text="label1"></mx:Label>

    <mx:Label id="label2" text="label2"></mx:Label>

    <mx:Label id="label3" text="label3" color="red"></mx:Label>

    <mx:Label id="label4" text="label4">
        <mx:color>yellow</mx:color>
    </mx:Label>

</mx:Application>

ただ、タグ属性、子タグでは問題ないみたい。

MXMLでのイベントプロパティの設定

イベントプロパティにハンドラとなるメソッドをかいておけばいいみたい。
たとえば、上のStyleAndEffectではイベントプロパティ:creationCompleteにハンドラをかいています。

また、ActionScriptに記述する際は、スタイルプロパティとかと同じで、
addEventListener(イベントプロパティ名, メソッド)といったようにするそうです。
この例は今後、いやでも見ると思うので、ここではパスさせてください。

URL値の指定

CSSとかを指定するときなど、URLを記述することがあります。
その場合、以下のようにいくつかの指定ができるみたいです。

絶対URL
http://hoge.com/hoge.cssといったように記述
コンテキストルートに対する相対パス1
@ContextRoot()/dir/hoge.xml
コンテキストルートに対する相対パス1
/dir/hoge.xml
現在の位置からの相対パス
../dir/hoge.xml

その他

RegExpとかあったんだけど、いまいち使い道が分からん。
どういうことを想定しているんだろう?!

*1:あとで試す