Flex 4 Design View Extensibility Kit-カスタムコンポーネントをIDE上でレイアウトする-

FlexのカスタムコンポーネントをそのままFlash Builderに取り込むと、デザインビュー上でうまく配置できないことがあります。
(でも、実行すると正しく描画される)

特にmxのCanvasやAccordion等、Container系コンポーネントを拡張したカスタムコンポーネントFlash Builder上で配置して、さらにその上からボタン等の他のコンポーネントを配置しても、見た目上、配置されません。mxmlソースコードをみると、確かに配置されていますが。

この対処には、Design View Extensibility Kitを使って、Flash Builder上でレイアウトするための専用クラスを用意する必要があります。

※作成したカスタムコンポーネントが、コンポーネントライフサイクルにしたがって正しく作成されていない等、そもそも正しく描画されない場合は、Extensilibity Kitを使っても、うまく描画されません

Design View Extensibility Kit for Flex 4
http://coldfusionmx.com.br/devnet/flex/flashbuilder_extensibility/DesignViewExtKitReadme.htm

design.xmlの中に記述されているdesignExtensionタグで指定されるクラスが、Flash Builder上でレイアウトするための拡張クラスです。
例えば、mxのCanvasには、「com.adobe.flexide.extensions.components.mx.containers.CanvasExtension」クラスが指定されています。このように拡張クラスを指定しておかないと、IDE上でレイアウトがうまくいきません。

		<component name="mx.containers.Canvas" displayName="%Canvas.display.value" category="halolayout" filteredViewCategory="">
			<defaultAttribute name="width" value="200"/>
			<defaultAttribute name="height" value="200"/>
			<designExtension class="com.adobe.flexide.extensions.components.mx.containers.CanvasExtension"/>
			<mxmlProperties>
				<textfield id="label" name="%propertyLabel.label"/>
			</mxmlProperties>
		</component>

com.adobe.flexide.extensionsはSDKFlash Builderの中を探してもみつかりません。上記URLページにあるDownloadリンクから、「DV4ExtensionKit.fxp」をダウンロードしてください。このファイルの中に含まれています。
拡張子はfxpですが、zip形式として解凍できます。
上記ファイルには、サンプルソースコードが含まれていますので、それをみれば使い方がわかるでしょう。
カスタムコンポーネント上に子コンポーネントを配置したときの、サイズの再計算・再描画等が出来るようになります。

ちなみに、TabNavigatorやDataGridを配置したときに、NavigatorContentやDataGridColumn等の子コンポーネントが自動的に挿入されますが、これはdesign.xml内でinserterClassを指定して、そのクラスが挿入処理を行っています。このinserterClassはさきほどのExtensionKitには含まれておらず、Flash Builderに含まれています。com.adobe.flexbuilder.mxml.editorの中にあります。

Flexコンポーネントライフサイクル

【注意】書きかけです

カスタムコンポーネントを正しく作るためには、コンポーネントのライフサイクルを正確に理解しておく必要がある、という話をどこかで聞いたので、ライフサイクルと実装の対応関係を整理してみました。

ライフサイクル全体像

ライフサイクルは「生成」「初期化」「更新」「破棄」のフェーズに分かれます。というか分けてみました。
初期化フェーズと更新フェーズで登場する「無効化」と「検証」ステップがポイントです。

フルサイズの画像はこちら

では、各ステップを順番にみていきます。

生成フェーズ

コンポーネントにとって、新しい人生のスタートとなるフェーズです。

コンストラクション

コンポーネントインスタンス化するステップです。
通常はsuper()を呼んだり、イベントリスナーを追加したりします。

アタッチメント

当該コンポーネントをディスプレイリストに追加して、親を設定します。
アタッチはaddChild()もしくはaddChildAt()メソッド、またはMXMLを通して行われます(MXMLは自動的にaddChildを呼びます)。

初期化フェーズ

アタッチメントが完了すると初期化フェーズに突入します。
初期化フェーズでは、preinitializeイベント、initializeイベント、creationCompleteイベントが発火されます。

preinitializeイベント

このイベントでは、子が作成される前に親のプロパティを設定する等の処理を行います。
この時点ではまだ子は作成されていません。つまり、コンストラクタで子を作成するのはおかしいわけです。
(このイベントの用途はあまり無いかも)

createChildren呼出し(子の作成)

このステップでは子を作成するためのcreateChildren()メソッドが呼び出されます。createChildrenを実装してください。

initializeイベント

initializeイベントは、当該コンポーネントとその全ての子が作成された後、コンポーネントのサイズを確定する前に発火されるイベントです。
レイアウトが確定する前に、コンポーネントの設定を行う場合に使います。

無効化

無効化はコンポーネントの仕組みにおいて、キーコンセプトとなる重要なステップです。
次回描画時に、検証ステップに対応するメソッドを呼び出してください、とマーキングする処理を行います。

無効化メソッド 検証メソッド
invalidateProperties() commitProperties()
invalidateSize() measure()
invalidateDisplayList() layoutChrome()、updateDisplayList()

※invalidateDisplayList()はlayoutChromeとupdateDisplayListが対応していますが、先に呼ばれるのはlayoutChromeです。

例えば、無効化ステップでinvalidateProperties()を呼び出した場合、次回描画時に、Flexによって当該コンポーネントのcommitProperties()が呼び出されます。

検証

検証は長い長いステップです。細かく分けると「コミット」「測定」「レイアウト」に分かれますが、特にレイアウトステップについては、これでもかというぐらい長いです。

  • コミット

コンポーネントのプロパティに対する変更を調整するためのステップです。
通常、画面上の表示方法に影響するプロパティに対する調整を行います。

  • 測定

サイズを測ります。明示的にサイズが指定されている場合、このステップは実質省略され、measure()メソッドが呼び出されません。ということは、明示的にサイズ指定を行った方がほとんどの場合、計算コストが低いということになります。

  • レイアウト
    • layoutChrome

ContainerもしくはContainerサブクラスが持つメソッドで、コンテナ周囲の境界線領域を定義します。

    • updateDisplayList

コンポーネントの子のサイズと位置を設定
・スキンやグラフィックエレメントの描画

creationCompleteイベント

コンポーネントのレイアウトが完了し、必要に応じてコンポーネントが表示されたときに送出されます。
コンポーネント作成時のサイズや位置の正確な値を必要とする処理を行うのに使用します。

更新フェーズ

更新要求待ち

ボーッとしている状態。

更新要求

テキストを変更したとか、なんかいろいろ。

無効化

初期化フェーズの無効化と同じ。

検証

初期化フェーズの検証と同じ。

破棄フェーズ

さらばコンポーネント。お前のことは忘れないよ。

デタッチメント

お前はうちの子ではない、といって勘当されるステップです。悲しいですね。

ガベージコレクト

んでもって、誰からも気にされていない場合、ゴミとして捨てられます。悲しいですね。

Flex 4 日本語ドキュメント

AdobeのFlex4関連資料が日本語化されてきているようです。

Flex 4 APIリファレンス
http://help.adobe.com/ja_JP/AS3LCR/Flex_4.0/index.html
Flash Builder 4 リファレンス
http://help.adobe.com/ja_JP/Flex/4.0/UsingFlashBuilder/index.html

Using Flex4は英語のままでした
http://help.adobe.com/ja_JP/Flex/4.0/UsingSDK/index.html

Flex 4 リリース

待望のFlex 4が正式にリリースされました。当初、2010年初頭リリース予定とされていたので、延期になるのかと心配していました。

Flex4から、チャートコンポーネントとAdvancedDataGridがオープンソース化されました。(Flex3の頃はFlex Builder 3 Professionalに付属していた有償コンポーネントでした)
datavisualization.swcってのがそうらしいです。
ソースコードは、flex_sdk_4.0.0.14159/frameworks/projects/datavisualizationのところにあります。
ちなみにbeta2(4.0.0.10485)の頃はオープンソース化されていないので、beta2に上記ソースコードは含まれていません。


Flexデベロッパーセンターに、日本語化されたFlex4の記事がアップされています。
http://www.adobe.com/jp/devnet/flex/

Flex4のドキュメントはまだ日本語化されていないようです。
http://www.adobe.com/support/documentation/jp/flex/

Flash Builder 4 beta 2のコンポーネントビューをカスタマイズする

Flex Builder のコンポーネントビューが気に入らないので、カスタマイズしてみました。このカスタマイズはAdobeのサポート対象外になる可能性があるかもしれないのでご注意ください。
対象はFlash Builder 4 beta 2 for Mac OS Xですが、Flex Builderでも同じような方法が適用できるはずです。

コンポーネントビューに表示するコンポーネントを制限する

Flex Builderのコンポーネントビューには、標準で利用できるコンポーネントが配置されていて、デザインビューにドラッグ&ドロップで配置できます。
ところが、実際の開発では、画面デザインを統一するため、特定のコンポーネントのみ使ってもらい、余計なコンポーネントは使わないようにしたい、ということがあります。

そこで、コンポーネントビューから特定のコントロールを除外してみます。
ただし、コンポーネントビューから除外するだけで、ソースコード上からは利用可能です。
ソースコード上での利用を抑止するためには、コンパイラで頑張るか、チェック用のプリコンパイラを作る等の方法で対処する必要があります。

今回は、標準コントロールのうち、Flex4から追加された「DataGroup」をコンポーネントビューから除外してみます。



コンポーネントコンポーネントビューに表示するための設定は、以下の場所に記述されています。

/Applications/Adobe Flash Builder Beta 2/plugins/com.adobe.flexbuilder.codemodel_4.0.0.253292/resources/design

上記ディレクトリの中にあるxmlファイルに、コンポーネントのクラス名やコンポーネントのカテゴリが記述されています。このファイルは一般に「design.xml」と呼ばれているものです。

今回除外する「DataGroup」はsparkパッケージのコンポーネントなので、「flex4.xml」を編集します。

/Applications/Adobe Flash Builder Beta 2/plugins/com.adobe.flexbuilder.codemodel_4.0.0.253292/resources/design/flex4.xml

ファイルを開くと、タグの中にタグがたくさん記述されています。この中にname="spark.components.DataGroup"の属性を持つタグがあるので、「削除」します。コメントアウトではうまくいきません。(私だけ??)

        <component name="spark.components.DataGroup" displayName="%DataGroup.display.value"
                   category="gumbolayout" filteredViewCategory="layout_combined">
            <defaultAttribute name="width" value="200"/>
            <defaultAttribute name="height" value="200"/>
            <designExtension class="com.adobe.flexide.extensions.components.spark.components.DataGroupExtension" />
            <mxmlProperties>
                <!-- no common properties -->
            </mxmlProperties>
        </component>

flex4.xmlを保存して、Flash Builder 4を起動します。
コンポーネントビューを表示すると、リストから「DataGroup」が除外されています。


sparkやmx等のコンポーネントパッケージとxmlの対応関係はcodemodel.jarの中にあるDesignクラスにハードコーディングで記述されています。

/Applications/Adobe Flash Builder Beta 2/plugins/com.adobe.flexbuilder.codemodel_4.0.0.253292/codemodel.jar

com.adobe.flexbuilder.codemodel.internal.design.Design

  private Document readHardcodedDesignXml(IClassPathEntry entry)
  {
    IActionScriptProjectSettings context = entry.getContext();
    if (context != null) {
      IFlexSDK flexSDK = context.getFlexSDK();
      if (flexSDK != null) {
        IPath sdkLocation = flexSDK.getLocation();
        IPath absoluteSwcPath = entry.getResolvedPath();
        IPath relativeSwcPath = PathUtils.absoluteToRelative(absoluteSwcPath, sdkLocation);
        if (!(relativeSwcPath.isAbsolute())) {
          String swcFilename = absoluteSwcPath.lastSegment();
          int sdkMajorVersion = flexSDK.getVersion().getMajor();

          String xmlFile = null;
          String propertiesFilename = null;
          if ("spark.swc".equals(swcFilename)) {
            xmlFile = "flex4.xml";
            propertiesFilename = "flex4.xml".replaceAll("\\.xml$", ".properties");
          } else if ("framework.swc".equals(swcFilename)) {
            xmlFile = (sdkMajorVersion == 3) ? "framework.xml" : "framework4.xml";
            propertiesFilename = "framework.xml".replaceAll("\\.xml$", ".properties");
          } else if (("charts.swc".equals(swcFilename)) || ("datavisualization.swc".equals(swcFilename))) {
            xmlFile = (sdkMajorVersion == 3) ? "datavisualization.xml" : "datavisualization4.xml";
            propertiesFilename = "datavisualization.xml".replaceAll("\\.xml$", ".properties");
          } else if ("airframework.swc".equals(swcFilename)) {
            xmlFile = (sdkMajorVersion == 3) ? "airframework.xml" : "airframework4.xml";
            propertiesFilename = "airframework.xml".replaceAll("\\.xml$", ".properties");
          } else if ("utilities.swc".equals(swcFilename)) {
            xmlFile = "utilities.xml";
            propertiesFilename = "utilities.xml".replaceAll("\\.xml$", ".properties");
          }

          if (xmlFile != null) return readDesignXmlFile(xmlFile, propertiesFilename);
        }
      }
    }

    return null;
  }

コンポーネントの表示名を変更する

コンポーネントビューに表示されるコンポーネント名は、ButtonやTextInput等、英名(物理名)になっています。
コンポーネントの表示名は国際化に対応しているので、画面のデザイン担当者には和名(論理名)で見せたい、というような場合、propertiesファイルをいじることで対応できます。

デフォルトのpropertiesは、さきほどのdesign.xmlが格納されたディレクトリと同じ場所に、xmlと対応する形で格納されています。
/Applications/Adobe Flash Builder Beta 2/plugins/com.adobe.flexbuilder.codemodel_4.0.0.253292/resources/design

flex4.xml ⇔ flex4.properties

日本語ロケールのpropertiesは以下の場所にあります。

/Applications/Adobe Flash Builder Beta 2/plugins/com.adobe.flexbuilder.codemodel.nl1_4.0.0.253292/nl/ja_JP/resources/design
ファイル名:flex4.properties

(変更前)
FxTextInput.display.value = TextInput


(変更後)
FxTextInput.display.value = \u30C6\u30AD\u30B9\u30C8\u5165\u529B

コンポーネントビューの実体

ちなみに、Flash Builderのコンポーネントビューの実体はcom.adobe.flexbuilder.mxml.editor.views.components.ComponentsViewクラスになります。
jarファイルは以下の場所にあります。

/Applications/Adobe Flash Builder Beta 2/plugins/com.adobe.flexbuilder.mxml.editor_4.0.0.253292/mxml.jar

Mac OS X上のFlash Builder 4 beta 2 に SVN (Subversive)プラグインをインストールする

Flash Builder 4 beta 2の単体版にSVNプラグインをインストールします。ここでは、Eclipse Foundation公認のSubversiveをインストールします。
Flash Builderといっても、eclipse (ganymede)上にsubversiveをインストールするのと何ら変わりはないです。

1. [メニュー] -> [ヘルプ] -> [ソフトウェア更新] -> [検索とインストール]
2. インストール/更新ウィンドウにて、「インストールする新規フィーチャーを検索」
3.Subvesiveの更新サイトを追加する
http://download.eclipse.org/technology/subversive/0.7/update-site/
4.インストール対象を選択する
下記の2つを除外する。
Subversive SVN JDT Ignore Extensions
Subversive SVN Integration for the Mylyn Project

同様の手順で、SVNコネクタをインストールする。
1. [メニュー] -> [ヘルプ] -> [ソフトウェア更新] -> [検索とインストール]
2. インストール/更新ウィンドウにて、「インストールする新規フィーチャーを検索」
3.SVNコネクタの更新サイトを追加する
http://download.eclipse.org/technology/subversive/0.7/update-site/
4.インストール対象を選択する
Subversive SN Connectors 2.2.1
SVNKit 1.3.0 Implementation
Native JavaHL 1.6 Implementation