Adobe Flex에서 Visual Component에 스타일을 입히기 위해 MXML형태의 <mx:Style></mx:Style>을 자주 사용할 것이다.

 

<mx:Style>을 이해하기 앞서 먼저 Flex의 컴파일 과정에 대해서 언급하겠다. 알다시피 Flex의 결과물은 Flash 컨텐츠인 SWF파일이다. Flex로 만들어진 결과물은 컴파일 단계에서 모두 ActionScript 3.0으로 변환(Generate)되고 변환된 ActionScript 3.0 파일을 가지고 SWF가 만들어진다. 즉, Flex에서 유용하게 사용되는 MXML은 UI 디자인의 편의성을 제공하기 위해 사용되는 것이지 실제 컴파일 단계에서는 직접적으로 사용되지 않는 언어이다. 

 

<mx:Style> 변환에 대한 이해

 

MXML에서 <mx:Style>로 싸여진 것도 ActionScript 3.0 으로 변환한다는 것을 이제 짐작할 수 있을 것이다. 실제로 어떻게 ActionScript 3.0으로 변환되는지 확인하기 위해 Flex Builder에서 Flex Project를 만들고 생성된 프로젝트의 컴파일러 옵션에 –keep-generated-actionscript를 넣어주자. 이 옵션은 Flex 컴파일시 사용되는 mxmlc에 지정하는 옵션이다. 더 많은 옵션은 “About the application compiler options”를 참고하면 되겠다.

 

 

 

위 옵션대로 넣어주면 프로젝트의 src폴더에 generated 폴더가 생성된다.

 

 

 

generated 폴더를 살펴보면 아래 그림처럼 ActionScript 3.0 파일이 생성된 것을 확인할 수 있다.

 

 

 

아래 코드 처럼 Application에 어떤 visual component도 삽입하지 않은 상태에서 GenerateCSSTest-generated.as 파일을 살펴보자. (프로젝트명을 GenerateCSSTest로 했기 대문에 GenerateCSSTest-generated.as 가 된 것이다.)

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
</mx:Application>

 

아래 코드는 MXML로 만들어진 Application을 ActionScript 3.0으로 변환된 GenerateCSSTest 클래스이다.(GenerateCSSTest-generated.as). 우리가 집중적으로 살펴보아야 할 부분은 <mx:Style>이 어떻게 사용되는가 알아내는 것이므로 코드상에서 _GenerateCSSTest_StylesInit() 부분에서 관련성을 찾아낼 수 있을 것이다. 이 애플리케이션이 실행하게 되면 GenerateCSSTest 생성자에서 _GenerateCSSTest_StylesInit()를 호출하므로 <mx:Style>에서 적용한 CSS가 여기서 적용될 것이다라는 것을 예측할 수 있다.

public class GenerateCSSTest
    extends mx.core.Application
{

    //    instance variables

    //    type-import dummies

    //    Container document descriptor
private var _documentDescriptor_ : mx.core.UIComponentDescriptor =
new mx.core.UIComponentDescriptor({
  type: mx.core.Application
})

    //    constructor (Flex display object)
    /**
     * @private
     **/
    public function GenerateCSSTest()
    {
        super();

        mx_internal::_document = this;

        //    our style settings

        //    ambient styles
        mx_internal::_GenerateCSSTest_StylesInit();

        //    properties
        this.layout = "vertical";

        //    events

    }

    //    initialize()
    /**
     * @private
     **/
    override public function initialize():void
    {
         mx_internal::setDocumentDescriptor(_documentDescriptor_);

        super.initialize();
    }

    //    scripts
    //    end scripts

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

    //    initialize style defs for GenerateCSSTest

    mx_internal static var _GenerateCSSTest_StylesInit_done:Boolean = false;

    mx_internal function _GenerateCSSTest_StylesInit():void
    {
        //    only add our style defs to the StyleManager once
        if (mx_internal::_GenerateCSSTest_StylesInit_done)
            return;
        else
            mx_internal::_GenerateCSSTest_StylesInit_done = true;

        var style:CSSStyleDeclaration;
        var effects:Array;

        StyleManager.mx_internal::initProtoChainRoots();
    }

    //    embed carrier vars
    //    end embed carrier vars

//    end class def
}

 

이제 아래 코드처럼 Application안에 Button과 TextArea 컴포넌트를 삽입하고 각각에 대해서 Type Selector와 Class Selector로 CSS를 <mx:Style> 태그안에 적용해보자.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
    <mx:Button label="버튼1"/>
    <mx:TextArea text="Flex가 쪼아~" styleName="myTextArea"/>
    <mx:Style>
        Button
        {
            fontSize:12pt;
        }
        .myTextArea
        {
            fontSize:14pt;
            color:red;
        }
    </mx:Style>
</mx:Application>

 

아래코드는 위처럼 Application에 2가지 컴포넌트와 스타일을 적용했을 때 만들어진 GenerateCSSText 클래스 ActionScript 3.0 코드이다. 파란색 부분은 아무것도 안넣을 때와 비교할 때 추가된 부분이다. MXML로 컴포넌트를 삽입하면 상단 파란색 부분처럼 UIComponentDescriptor의 인스턴스인 _documentDescriptor_에 자동으로 등록시켜준다. 각 컴포넌트에 설정된 속성인 label, text, styleName도 추가되어 있는 것을 볼 수 있다. _documentDescriptor_는 initialize()함수 실행시 적용된다.

 

또한 그 아래로 가보면 우리가 관심을 가지고 있는 <mx:Style>에 작성된 CSS가 어떻게 적용되었나 알 수 있다. 

 

여기 있는 코드는 2개의 CSS Selector를 등록하고 있다.

 

첫번째로 Class Selector인 “.myTextArea” 이다. StyleManager.getStyleDeclaration()을 통해 기존에 “.myTextArea”가 등록되어 있는지 조사한다. 만약 등록이 안되어 있다면 StyleManager.setStyleDeclaration()을 통해 CSSStyleDeclaration의 인스턴스형으로 “.myTextArea”를 등록한다. 그런 다음 <mx:Style>에 지정한 fontSize와 color를 적용하기 위해 CSSStyleDeclaration의 factory함수를 정의한다. 이렇게 해두면 자동적으로 StyleManager에 등록된 Class Selector인 “.myTextArea”를 생성하게 되며 StyleManager는 styleName이 “.myTextArea”로 적용된 컴포넌트는 전부 찾아 적용해준다.

 

같은 방법으로 Type Selector인 “Button”을 등록한다. StyleManager은 Button 컴포넌트로 만들어진 인스턴스를 찾아 fontSize:12pt를 적용해준다.

이처럼 <mx:Style></mx:Style>안에 적용된 CSS는 ActionScript 3.0으로 만들어져 StyleManager 클래스가 담당하도록 Flex 컴파일러가 변경시켜준다. 이것이 핵심이다.

public class GenerateCSSTest
    extends mx.core.Application
{

    //    instance variables

    //    type-import dummies

    //    Container document descriptor
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.Button
        ,
        propertiesFactory: function():Object { return {
          label: "버튼1"
        }}
      })
    ,
      new mx.core.UIComponentDescriptor({
        type: mx.controls.TextArea
        ,
        propertiesFactory: function():Object { return {
          text: "Flex가 쪼아~",
          styleName: "myTextArea"
        }}
      })
    ]
  }}
})

    //    constructor (Flex display object)
    /**
     * @private
     **/
    public function GenerateCSSTest()
    {
        super();

        mx_internal::_document = this;

        //    our style settings

        //    ambient styles
        mx_internal::_GenerateCSSTest_StylesInit();

        //    properties
        this.layout = "vertical";

        //    events

    }

    //    initialize()
    /**
     * @private
     **/
    override public function initialize():void
    {
         mx_internal::setDocumentDescriptor(_documentDescriptor_);

        super.initialize();
    }

    //    scripts
    //    end scripts

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

    //    initialize style defs for GenerateCSSTest

    mx_internal static var _GenerateCSSTest_StylesInit_done:Boolean = false;

    mx_internal function _GenerateCSSTest_StylesInit():void
    {
        //    only add our style defs to the StyleManager once
        if (mx_internal::_GenerateCSSTest_StylesInit_done)
            return;
        else
            mx_internal::_GenerateCSSTest_StylesInit_done = true;

        var style:CSSStyleDeclaration;
        var effects:Array;

        // myTextArea
        style = StyleManager.getStyleDeclaration(".myTextArea");
        if (!style)
        {
            style = new CSSStyleDeclaration();
            StyleManager.setStyleDeclaration(".myTextArea", style, false);
        }
        if (style.factory == null)
        {
            style.factory = function():void
            {
                this.color = 0xFF0000;
                this.fontSize = 14;
            };
        }
        // Button
        style = StyleManager.getStyleDeclaration("Button");
        if (!style)
        {
            style = new CSSStyleDeclaration();
            StyleManager.setStyleDeclaration("Button", style, false);
        }
        if (style.factory == null)
        {
            style.factory = function():void
            {
                this.fontSize = 12;
            };
        }

        StyleManager.mx_internal::initProtoChainRoots();
    }

    //    embed carrier vars
    //    end embed carrier vars

//    end class def
}

 

본문에서는 StyleManager 자체의 구조를 설명하는 것은 너무 방대할 것이므로 생략한다. 개인적으로 Flex의 스타일 적용 방식은 매우 유연하고 사용하기 편하다고 생각한다. 그만큼 Flex SDK에 있는 StyleManager가 잘 만들어져 있다는 것을 의미하기도 한다. 시간이 허락된다면 StyleManager를 분석해서 배치된 Visual Component에 어떻게 스타일이 적용되는지 알아보는 것도 흥미롭고 유익한 일일 것이다.

 

컴파일러 옵션인 –keep-generated-actionscript은 MXML을 ActionScript 3.0으로 변환한 코드를 가시적으로 볼 수 있게 함으로써 Flex가 어떻게 동작하는가 아는데 중요한 가이드 역할을 하고 있는 셈이다.

 

컴포넌트의 기본 스타일은 어떻게 적용되는가?

 

이쯤되면 궁금한 점이 또 생긴다.

 

<mx:Style>로 적용하지 않은 컴포넌트들은 어떻게 CSS가 먹히는 것일까? 본인은 처음에 해당 컴포넌트 클래스에 StyleManager를 이용하여 CSS를 만들었을 것이라 생각했다. 하지만 그게 아니였다. Flex SDK에 있는 Button.as를 살펴보길 바란다.(Window XP에 Flex Builder 3 Professonal을 설치한 경우에는 C:\Program Files\Adobe\Flex Builder 3\sdks\3.2.0\frameworks\projects\framework\src\mx\controls에 Button.as 가 있다.) 직접 보면 알겠지만 Button.as안에는 StyleManager에 관련된 내용이 전혀 존재하지 않는다. 그럼 Flex 컴포넌트들의 기본 스타일은 도대체 어떻게 적용되는 것인가?

답은 generated 폴더 안에 있다.

 

generated 폴더 내부에는 Button에 기본 스타일을 적용을 정의한 _ButtonStyle.as 뿐 아니라 _gloabalStyle.as, _ApplicationStyle.as, _dateGridStylesStyle.as 등이 있다.

아래는 _ButtonStyle.as이다. Button의 스킨인 mx.skins.halo.ButtonSkin이 여기서 적용된다. 또한 textAlign도 여기서 적용되는 것을 볼 수 있다. 즉 사용한 컴포넌트에 CSS를 적용하지 않더라도 기본 스타일이 이들 코드를 통해 적용됨을 알 수 있다.

 

앞선 예제에서 Application에서 <mx:Style>에 “Button” Type Selector로 fontSize=12pt가 적용되었으므로 이 로직이 실행이 되고 난 다음에 fontSize=12pt가 적용됨을 감각적으로 알 수 있을 것이다.

public class _ButtonStyle
{

    public static function init(fbs:IFlexModuleFactory):void
    {
        var style:CSSStyleDeclaration = StyleManager.getStyleDeclaration("Button");
        if (!style)
        {
            style = new CSSStyleDeclaration();
            StyleManager.setStyleDeclaration("Button", style, false);
        }
        if (style.defaultFactory == null)
        {
            style.defaultFactory = function():void
            {
                this.paddingTop = 2;
                this.textAlign = "center";
                this.skin = mx.skins.halo.ButtonSkin;
                this.paddingLeft = 10;
                this.fontWeight = "bold";
                this.cornerRadius = 4;
                this.paddingRight = 10;
                this.verticalGap = 2;
                this.horizontalGap = 2;
                this.paddingBottom = 2;
            };
        }
    }
}

 

방금 언급한 Style관련 ActionScript 3.0 코드들(_ButtonStyle.as, _gloabalStyle.as, _ApplicationStyle.as, _dateGridStylesStyle.as 등)은 Flex SDK의 SystemManager 클래스에 등록되어 사용된다. generated 폴더를 살펴보면 SystemManager 클래스를 확장한 _GenerateCSSTest_mx_managers_SystemManager 클래스의 ActionScript 3.0 코드가 존재한다. 아래 코드를 살펴보자.

public class _GenerateCSSTest_mx_managers_SystemManager
    extends mx.managers.SystemManager
    implements IFlexModuleFactory
{
    public function _GenerateCSSTest_mx_managers_SystemManager()
    {

        super();
    }

    override     public function create(… params):Object
    {
        if (params.length > 0 && !(params[0] is String))
            return super.create.apply(this, params);

        var mainClassName:String = params.length == 0 ? "GenerateCSSTest" : String(params[0]);
        var mainClass:Class = Class(getDefinitionByName(mainClassName));
        if (!mainClass)
            return null;

        var instance:Object = new mainClass();
        if (instance is IFlexModule)
            (IFlexModule(instance)).moduleFactory = this;
        return instance;
    }

    override    public function info():Object
    {
        return {
            compiledLocales: [ "en_US" ],
            compiledResourceBundleNames: [ "containers", "core", "effects", "skins", "styles" ],
            currentDomain: ApplicationDomain.currentDomain,
            layout: "vertical",
            mainClassName: "GenerateCSSTest",
            mixins: [ "_GenerateCSSTest_FlexInit", "_alertButtonStyleStyle", "_ScrollBarStyle", "_activeTabStyleStyle", "_textAreaHScrollBarStyleStyle", "_ToolTipStyle", "_advancedDataGridStylesStyle", "_comboDropdownStyle", "_ContainerStyle", "_textAreaVScrollBarStyleStyle", "_linkButtonStyleStyle", "_globalStyle", "_windowStatusStyle", "_windowStylesStyle", "_activeButtonStyleStyle", "_errorTipStyle", "_richTextEditorTextAreaStyleStyle", "_CursorManagerStyle", "_todayStyleStyle", "_dateFieldPopupStyle", "_plainStyle", "_dataGridStylesStyle", "_ApplicationStyle", "_headerDateTextStyle", "_ButtonStyle", "_popUpMenuStyle", "_swatchPanelTextFieldStyle", "_opaquePanelStyle", "_weekDayStyleStyle", "_headerDragProxyStyleStyle" ]

        }
    }
}

info() 메소드를 override해서 mixins에 CSS를 적용한 클래스의 이름들을 전부 Array형태로 담고 있다. SystemManger는 이 mixins에 등록된 클래스들을 전부 스캔하며 CSS를 적용한다.

 

아래코드는 StyleManager 내부의 일부 코드이다. 앞서 설명한 SystemManager를 확장한_GenerateCSSTest_mx_managers_SystemManager 클래스는 info()를 override했기 때문에 해당 mixins값을 전부 얻어올 수 있다. 이 값의 길이만큼 loop를 돌면서 getDefinitionByName()메소드를 통해 해당 클래스 정의되어 있는지 알아내어 그 클래스의 init()함수를 호출한다. _ButtonStyle.as에 init()메소드에 StyleManager를 가지고 Button의 Type Selector를 등록했다는 것을 확인할 수 있었다. 결국 StyleManager로 Style을 적용한 클래스들의 init()함수를 모두 호출함으로써 기본 CSS가 애플리케이션에 적용되는 것이다.

        var mixinList:Array = info()["mixins"];
        if (mixinList && mixinList.length > 0)
        {
            var n:int = mixinList.length;
            for (var i:int = 0; i < n; ++i)
            {
                // trace("initializing mixin " + mixinList[i]);
                var c:Class = Class(getDefinitionByName(mixinList[i]));
                c["init"](this);
            }
        }

 

 

상속되는 CSS 속성은 어떻게 적용될까?

 

CSS 속성중에는 상속되는 것과 상속되지 않는 것이 있다. 가령 fontSize, color, fontFamily 등은 상속이 된다. 한 예로 아래코드처럼 Application에 color를 blue로 지정해보자. color는 상속되는 CSS속성이기 때문에 Button에 color가 지정되어 있지 않음에도 불구하고 파란색 글자색이 적용된다.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
    <mx:Button label="버튼1"/>
    <mx:TextArea text="Flex가 쪼아~" styleName="myTextArea"/>
    <mx:Style>
        Application
        {
            color:blue;
        }

        Button
        {
            fontSize:12pt;
        }
        .myTextArea
        {
            fontSize:14pt;
            color:red;
        }
    </mx:Style>
</mx:Application>

 

 

Button에는 파란색이 적용된 반면 TextArea에는 그대로 빨간색이 적용된 이유는 CSS적용 우선순위 때문이다. 부모(Application)에 적용한 CSS속성값에 자식(TextArea)에서 다시 적용하면 부모에서 적용한 것은 무시된다. 다른 이야기지만 이러한 일을 전부 StyleManager에서 하고 있다는게 대단해보인다. Flex SDK의 강력함이 엿보인다. 만약 Flex SDK를 사용하지 않고 순수하게 ActionScript 3.0으로 코딩해야하는 경우에 CSS를 적용해야한다면… 앞이 깜깜할 뿐이다. 다 만들어야하니 말이다. ^^;

 

이처럼 Flex의 CSS는 상속이 되는 속성들이 있는데 이들 속성도 generated 폴더에 살펴보면 어떻게 등록되어 사용되는지 살펴볼 수 있다. _GenerateCSSTest_FlexInit.as를 살펴보자.

public class _GenerateCSSTest_FlexInit
{
   public function _GenerateCSSTest_FlexInit()
   {
       super();
   }
   public static function init(fbs:IFlexModuleFactory):void
   {
      EffectManager.mx_internal::registerEffectTrigger("addedEffect", "added");
      EffectManager.mx_internal::registerEffectTrigger("creationCompleteEffect", "creationComplete");
      EffectManager.mx_internal::registerEffectTrigger("focusInEffect", "focusIn");
      EffectManager.mx_internal::registerEffectTrigger("focusOutEffect", "focusOut");
      EffectManager.mx_internal::registerEffectTrigger("hideEffect", "hide");
      EffectManager.mx_internal::registerEffectTrigger("mouseDownEffect", "mouseDown");
      EffectManager.mx_internal::registerEffectTrigger("mouseUpEffect", "mouseUp");
      EffectManager.mx_internal::registerEffectTrigger("moveEffect", "move");
      EffectManager.mx_internal::registerEffectTrigger("removedEffect", "removed");
      EffectManager.mx_internal::registerEffectTrigger("resizeEffect", "resize");
      EffectManager.mx_internal::registerEffectTrigger("rollOutEffect", "rollOut");
      EffectManager.mx_internal::registerEffectTrigger("rollOverEffect", "rollOver");
      EffectManager.mx_internal::registerEffectTrigger("showEffect", "show");
      var styleNames:Array = ["fontWeight", "modalTransparencyBlur", "textRollOverColor", "backgroundDisabledColor", "textIndent", "barColor", "fontSize", "kerning", "textAlign", "fontStyle", "modalTransparencyDuration", "textSelectedColor", "modalTransparency", "fontGridFitType", "disabledColor", "fontAntiAliasType", "modalTransparencyColor", "leading", "dropShadowColor", "themeColor", "letterSpacing", "fontFamily", "color", "fontThickness", "errorColor", "fontSharpness", "textDecoration"];

      import mx.styles.StyleManager;

      for (var i:int = 0; i < styleNames.length; i++)
      {
         StyleManager.registerInheritingStyle(styleNames[i]);
      }
   }
}  // FlexInit

앞의 코드에서 볼 수 있듯이 상속되는 Style속성들은 StyleManager의 registerInheritingStyle() 메소드를 통해 등록된다. 아하! 라고 외쳤다면 여러분도 Flex SDK의 StyleManager의 강력함에 찬사를 보내고 있는 것일지도 모르겠다. ^^

참고로 _GenerateCSSTest_FlexInit 클래스는 _GenerateCSSTest_mx_managers_SystemManager의 info() 메소드의 mixins에 등록되어 있어서 SystemManager에서 _GenerateCSSTest_FlexInit 클래스의 info() 메소드를 자동으로 호출하게 된다.

 

 

나만의 Visual Component에 기본 CSS는 어떻게 적용할까?

 

Flex SDK에서 제공하는 Button이나 CheckBox와 같은 컴포넌트는 컴파일시 기본 CSS를 만들어주는 것을 앞서 확인할 수 있었다. 그럼 UIComponent를 확장해서 만든 Visual Component는 어떻게 기본 CSS를 적용할 수 있을까? 생각보다 어렵지 않다. 다음 코드를 보자.

package
{
import com.jidolstar.ui.frames.skins.FrameSkin;
import mx.core.UIComponent;
import mx.styles.CSSStyleDeclaration;
import mx.styles.StyleManager;

[Style(name="frameSkin", type="Class", inherit="no")]
[Style(name="backgroundColor",type="Number",format="Color",inherit="no")]
[Style(name="backgroundAlpha",type="Number",inherit="no")]
[Style(name="borderColor",type="Number",format="Color",inherit="no")]
[Style(name="borderAlpha",type="Number",inherit="no")]
[Style(name="borderThickness",type="Number",nherit="no")]
[Style(name="paddingLeft",type="Number",nherit="no")]
[Style(name="paddingRight",type="Number",nherit="no")]
[Style(name="paddingTop",type="Number",nherit="no")]
[Style(name="paddingBottom",type="Number",nherit="no")]
[Style(name="cornerRadius",type="Number",format="Color",inherit="no")]

public class MyComponent extends UIComponent
{
    private static var classConstructed:Boolean = classConstruct();
    private static function classConstruct():Boolean
    {
        // 기존에 TagBar이름의 type selector
        // 스타일 선언에 대한 인스턴스를 가져온다.
        var styleDeclaration:CSSStyleDeclaration
            = StyleManager.getStyleDeclaration("MyComponent ");

        // 이전에 스타일 선언이 되어있지 않은 경우라면
        // 스타일선언 인스턴스를 새로 하나 만든다.
        if (!styleDeclaration)
            styleDeclaration = new CSSStyleDeclaration();

        // defaultFactory를 이용해 스타일을 정의한다.
        styleDeclaration.defaultFactory = function ():void
        {
            this.frameSkin = FrameSkin;
            this.backgroundColor = 0xcccccc;
            this.backgroundAlpha = 1;
            this.borderColor = 0×009999;
            this.borderAlpha = 1;
            this.borderThickness = 4;
            this.paddingLeft = 10;
            this.paddingRight = 10;
            this.paddingTop = 10;
            this.paddingBottom = 10;
            this.cornerRadius = 10;
        }

        //선언된 스타일을 적용시킨다.
        StyleManager.setStyleDeclaration("MyComponent",
                  styleDeclaration, false);
        return true;
    }

    override public function styleChanged(styleProp:String):void
    {
        super.styleChanged( styleProp );
        invalidateProperties();
        invalidateDisplayList();
    }
}
}

 

위 코드는 구동되지 않는다. 하지만 어떻게 기본 CSS를 줄 수 있을지 해답을 제공하고 있다. 앞서 설명한 _ButtonStyle.as 에서 적용한 방법대로 private static 코드를 위처럼 만들면 된다. UIComponent를 확장한 MyComponent의 static 값인 classConstructed:Boolean = classConstruct() 부분이 처음 MyComponent가 엑세스 될 때 실행되므로 딱 한번만 CSS적용하는 static으로 정의된 classConstruct() 메소드가 실행된다. 이런 방법으로 기본 CSS를 컴포넌트에 적용시킬 수 있다. 이보다 더 좋은 방법이나 다른 방법이 있다면 소개해주길 바란다.

 

정리하며

 

지금까지 <mx:Style>에 적용한 CSS가 어떻게 ActionScript 3.0으로 변환되어 적용되는가 알아보았다. 여기서는 <mx:Style>만 짚고 넘어갔지만 Flex가 전체적으로 어떻게 돌아가는가 알기 위해서 generated 폴더에 변환된 ActionScript 3.0 파일을 전부 살펴보면서 분석해 봐야 한다. 중요하게 이해하고 넘어가야 하는 것은 Flex의 MXML은 쉽고 빠른 설계를 위해 사용되는 언어라는 점과 MXML은 모두 ActionScript 3.0으로 변환되어 컴파일 된다는 점이다. 그러므로 Flex는 MXML을 통해 ActionScript 3.0의 불편한 하드 코딩을 줄여주고 쉽게 스타일링, 데이터바인딩, 구조설계 등을 할 수 있게 해준 일종의 프레임워크로 이해해야 한다. C나 C++, Java등을 하고 Flex를 처음 접하는 사람들은 MXML과 ActionScript 3.0의 차이점을 알고 어떤 방식으로 Flex 애플리케이션이 돌아가는지 이해하는 과정이 필요한 시점이 반드시 올 것이다. Visual Component들이 어떻게 CSS가 적용되고 어떤 방식으로 Application이 구동되는지 어느 정도 이해해야 한 단계 높은 Flex 프로그래밍을 할 수 있다. 이것이 제대로 된 Flex Component를 설계하기 위한 필요조건이 아닐까?

 

참고글

 

+ Recent posts