Adobe Flex 3 ヘルプ

高度なプログラムスキンの作成

親コンポーネントへのアクセス

プログラムスキンクラスからプログラムスキンの親への参照を取得できます。この参照を使用すると、親コンポーネントのプロパティへのアクセスや、親コンポーネントに対するメソッドの呼び出しが可能になります。

スキンの parent プロパティを使用することにより、updateDisplayList() メソッドから親にアクセスできます。このスキンはまだ親コントロールに追加されていないため、スキンのコンストラクタ内で親コンポーネントにアクセスすることはできません。親コンポーネントが addChild() メソッドを呼び出して、スキンを子として追加すると、そのスキンの parent プロパティの値が設定されます。

プログラムスキンを使用してコンポーネントのインスタンスを作成するときは、次の順序で各種イベントが発生します。

  1. 親コンポーネントのインスタンスを作成します。
  2. スキンクラスのインスタンスを作成します。
  3. 親コンポーネントで addChild() メソッドを呼び出して、スキンクラスを追加します。

スキンの親への参照を取得するには、スキンの parent プロパティを UIComponent 型にキャストする必要があります。スキンは、この読み取り専用のプロパティを IFlexDisplayObject インターフェイスから継承します。また、is 演算子を使用して、親が UIComponent 型であることも確認する必要があります。これは、キャストを完了できないと、Flex によってランタイムエラーがスローされるからです。

次の例では、親コントロールのクラス名を取得し、親コンポーネントのタイプに応じて境界線を描画し塗ります。

package {

import flash.display.GradientType;
import flash.display.Graphics;
import mx.skins.Border;
import mx.styles.StyleManager;
import mx.utils.ColorUtil;
import mx.skins.halo.HaloColors;
import mx.core.UIComponent;

public class IconSkin extends Border {

  public function IconSkin() {
     //super();
  }
    
  override public function get measuredWidth():Number {
     return 14;
  }

  override public function get measuredHeight():Number {
     return 14;
  }
  
  override protected function updateDisplayList(w:Number, h:Number):void {
     super.updateDisplayList(w, h);

     // User-defined styles
     var borderColor:uint = getStyle("borderColor");
     var fillAlphas:Array = getStyle("fillAlphas");
     var fillColors:Array = getStyle("fillColors");
     StyleManager.getColorNames(fillColors);
     var highlightAlphas:Array = getStyle("highlightAlphas");       
     var themeColor:uint = getStyle("themeColor");
     
     var r:Number = width / 2;
     
     var upFillColors:Array;
     var upFillAlphas:Array;

     var disFillColors:Array;
     var disFillAlphas:Array;

     var g:Graphics = graphics;
     g.clear();
     
     var myParent:String;
     
     switch (name) {            
        case "upIcon": {
           upFillColors = [ fillColors[0], fillColors[1] ];
           upFillAlphas = [ fillAlphas[0], fillAlphas[1] ];

           if (parent is UIComponent) {
            myParent = String(UIComponent(parent).className);
           }
           if (myParent=="RadioButton") {
            // RadioButton border
            g.beginGradientFill(GradientType.LINEAR, 
                [ borderColor, 0x000000 ], 
                [100,100], [0,0xFF], 
                verticalGradientMatrix(0,0,w,h));
            g.drawCircle(r,r,r);
            g.drawCircle(r,r,(r-1));
            g.endFill();

            // RadioButton fill
            g.beginGradientFill(GradientType.LINEAR, 
                upFillColors, 
                upFillAlphas, 
                [0,0xFF], 
                verticalGradientMatrix(1,1,w-2,h-2));
            g.drawCircle(r,r,(r-1));
            g.endFill();
           } else if (myParent=="CheckBox") {
            // CheckBox border
            drawRoundRect(0,0,w,h,0, 
                [borderColor, 0x000000], 1, 
                verticalGradientMatrix(0,0,w,h), 
                GradientType.LINEAR, 
                null, {x: 1,y:1,w:w-2,h:h-2,r:0});

            // CheckBox fill
            drawRoundRect(1, 1, w-2, h-2, 0, 
                upFillColors, upFillAlphas, 
                verticalGradientMatrix(1,1,w-2,h-2)); 
           }

           // top highlight
           drawRoundRect(1, 1, w-2, 
                (h-2)/2, {tl:r,tr:r,bl:0,br:0},
                [0xFFFFFF, 0xFFFFFF], 
                highlightAlphas, 
                verticalGradientMatrix(0,0,w-2,(h-2)/2)); 
        }
        
        // Insert other cases such as downIcon and overIcon here.
        
     }
  }
}

}

スタイル対応プロパティの作成

多くの場合、スキンの背景色、境界線の太さ、角の丸みなどのスタイルプロパティを定義するプログラムスキンを定義します。これらのプロパティをスタイル対応にすることで、ユーザーは CSS ファイルで、または Flex アプリケーション内の setStyle() メソッドを使用して、この値を変更できます。インラインシンタックスを使用してプログラムスキンに定義されているスタイルの設定は変更できません。

カスタムプロパティをスタイル対応にするには、updateDisplayList() メソッドに getStyle() メソッドの呼び出しを追加し、そのメソッドのパラメータとして目的のカスタムプロパティを指定します。Flex がスキンをレンダリングするときは、このプロパティに対して getStyle() が呼び出され、CSS または表示リスト内で設定が検出されます。それにより、スキンを描画するときにスタイルプロパティの値を使用できます。

getStyle() メソッドへのこの呼び出しをチェックにラップし、スタイルが存在するかどうかを確認します。プロパティが設定されていない場合、getStyle() の結果は予期できない結果になることがあります。

次の例では、プロパティに値を割り当てる前に、そのプロパティが定義されているかどうかを確認します。

if (getStyle("lineThickness")) {
    _lineThickness = getStyle("lineThickness");
}

スキンのスタイル対応プロパティには、デフォルト値を定義する必要があります。通常、この操作は、スキンのコンストラクタ関数内で行います。デフォルト値を設定しないと、Flex アプリケーションでこのスタイルが定義されない場合のスタイルプロパティは、NaN または undefined に設定されます。これが原因で、ランタイムエラーが発生することがあります。

次の MyButtonSkin プログラムスキンクラスの例では、スタイル対応の _lineThickness プロパティおよび _backgroundFillColor プロパティのデフォルト値を、スキンのコンストラクタで定義します。次に、getStyle() メソッドの呼び出しを updateDisplayList() メソッドに追加し、これらのプロパティをスタイル対応にします。

package { // Use unnamed package if this skin is not in its own package.
  // skins/ButtonStylesSkin.as

  // Import necessary classes here.
  import flash.display.Graphics;
  import mx.skins.Border;
  import mx.skins.ProgrammaticSkin;
  import mx.styles.StyleManager;

  public class ButtonStylesSkin extends ProgrammaticSkin {

     public var _backgroundFillColor:Number;
     public var _lineThickness:Number;

     // Constructor.
     public function ButtonStylesSkin() {
        // Set default values.
        _backgroundFillColor = 0xFFFFFF;
        _lineThickness=2;
     }

     override protected function updateDisplayList(w:Number, h:Number):void {
        if (getStyle("lineThickness")) {
           // Get value of lineThickness style property.
           _lineThickness = getStyle("lineThickness");
        }
        if (getStyle("backgroundFillColor")) {
           // Get value of backgroundFillColor style property.
           _backgroundFillColor = getStyle("backgroundFillColor");
        }

        // Draw the box using the new values.
        var g:Graphics = graphics;
        g.clear();
        g.beginFill(_backgroundFillColor,1.0);
        g.lineStyle(_lineThickness, 0xFF0000);
        g.drawRect(0, 0, w, h);
        g.endFill();
        g.moveTo(0, 0);
        g.lineTo(w, h);
        g.moveTo(0, h);
        g.lineTo(w, 0);
     }
  }
} // Close unnamed package.

Flex アプリケーションでは、CSS または setStyle() メソッドを使用して、スタイル対応プロパティの値を設定できます。

次の例では、すべての Button コントロールのスタイル対応プロパティの値を、CSS で設定します。

<?xml version="1.0"?>
<!-- skins/ApplyButtonStylesSkin.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" width="600" height="600">
  <mx:Style>
     Button {
        upSkin:ClassReference('ButtonStylesSkin');
        downSkin:ClassReference('ButtonStylesSkin');
        overSkin:ClassReference('ButtonStylesSkin');
        disabledSkin:ClassReference('ButtonStylesSkin');
        lineThickness:4;
        backgroundFillColor:#CCCCCC;
     }
  </mx:Style>

  <mx:Script><![CDATA[
     public function changeLineThickness(e:Event):void {
        var t:int = Number(b1.getStyle("lineThickness"));
        if (t == 4) {
           b1.setStyle("lineThickness",1);
        } else {
           b1.setStyle("lineThickness",4);
        }
     }
  ]]></mx:Script>

  <mx:Button id="b1" label="Change Line Thickness" click="changeLineThickness(event)"/>
  
  <mx:Button id="b2"/>
</mx:Application>

前の例で実行する SWF ファイルは以下のとおりです。

Flex アプリケーションで、setStyle() メソッドを使用してスタイルプロパティの値を設定する場合、前の例のようにスタイル対応プロパティの値を、コンポーネントの単一のインスタンスにのみ設定できるほか、そのすべてのインスタンスに対して設定することもできます。次の例では、setStyle() メソッドを使用し、コントロールのすべてのインスタンスに対してスタイル対応プロパティの値を設定します。この場合のインスタンスは、すべての Button コントロールです。

<?xml version="1.0"?>
<!-- skins/ApplyGlobalButtonStylesSkin.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" width="600" height="600">
  <mx:Style>
     Button {
        upSkin:ClassReference('ButtonStylesSkin');
        downSkin:ClassReference('ButtonStylesSkin');
        overSkin:ClassReference('ButtonStylesSkin');
        disabledSkin:ClassReference('ButtonStylesSkin');
        lineThickness:4;
        backgroundFillColor:#CCCCCC;
     }
  </mx:Style>

  <mx:Script><![CDATA[
     public function changeLineThickness(e:Event):void {
        var t:int = Number(b1.getStyle("lineThickness"));
        if (t == 4) {
           StyleManager.getStyleDeclaration("Button").setStyle("lineThickness", 1);
        } else {
           StyleManager.getStyleDeclaration("Button").setStyle("lineThickness", 4);
        }
     }
  ]]></mx:Script>

  <mx:Button id="b1" label="Change Line Thickness" click="changeLineThickness(event)"/>
  
</mx:Application>

前の例で実行する SWF ファイルは以下のとおりです。

CSS または setStyle() メソッドのいずれかを使用してこれらのプロパティの値を設定しない場合は、スキンのコンストラクタで設定したプロパティのデフォルト値が使用されます。

colorfontSize などの既存のスタイルプロパティの値を取得するには、プロパティの存在のチェックに getStyle() メソッドへの呼び出しをラップする必要はありません。その理由は、すべてのコンポーネントスタイルのデフォルト値を定義する CSSStyleDeclaration が Flex によって作成されるからです。既存のスタイルプロパティが、未定義ということはありえません。カスタムスキンに追加したスタイルプロパティは、この CSSStyleDeclaration には追加されません。コンポーネントは、そのプロパティがスタイルプロパティであることを認識していないからです。

スタイル対応として定義したカスタムスキンプロパティは継承されません。そのため、このコンポーネントのサブクラスや子は、このプロパティの値を継承しません。

 

このページに新しいコメントが追加された場合に、電子メールでの通知を希望する。 | コメントレポート