액션스크립트 3.0 컴포넌트 개발하기
ActionScript 커스텀 컴포넌트는 패키지 내에서 정의해야 한다. 패키지는 어플리케이션의 디렉토리 구조
내에서 컴포넌트의 디렉토리 위치를 나타낸다. 또한 패키지 내부에 사용될 클래스들을 임포트하며,
임포트 구문과 컴포넌트 클래스 선언문 사이에 전달하고자 하는 이벤트를 정의한다.
1. 컴포넌트 클래스 정의
컴포넌트의 클래스 정의는 항상
public 키워드를 사용해 외부에서의 사용이 자유롭도록 해야 한다.액션스크립트 컴포넌트는 기본적으로 UI
Component 클래스나 UI Component 클래스의 하위 클래스를 상속 받아서 정의될 수
있다. 예를 들어 버튼 기능을 갖고 있는 컴포넌트를 제작하기 원한다면 Button
클래스나 SimpleButton 클래스를 상속 받아서 확장하면 된다.
이번 과정에서 제작하게
될 컴포넌트는 여러 컴포넌트들을 수직으로 내포할 수 있는 VBox 클래스를 상속받아
확장하게 된다.
2. 기본 컴포넌트 구조
기본
컴포넌트 구조는 생성자 메쏘드와 5개의 메쏘드로 이뤄진다. 특정 메쏘드는 요구사항에 따라
기능이 필요하지 않다면 구현하지 않아도 무관하다. 이제 각 메쏘드들의 기능과 수행
프로세스들을 살펴보자.
생성자 메쏘드는 public으로 선언되어야 하고 인자를 취하지 않는다. 또한 생성자 메쏘드는 클래스 속성의 최초 값을 설정하는데 사용된다. 예를 들어, 속성 및 스타일에 대한 디폴트 값을 설정하거나 배열과 같은 데이터 구조를 초기화하는데 사용될 수 있다. 생성자 메쏘드는 액션스크립트 컴포넌트를 어플리케이션 안에서 생성하고자 할 때 호출된다.
FLEX는 addChild() 메쏘드가 호출될 때 createChildren() 메쏘드를 호출해 컴포넌트를 상위 컨테이너에 추가시킨다. 비주얼한 자식 객체들을 생성하고 addChild() 메쏘드를 호출하는 방법으로 구현된다. Create Children() 메쏘드에 대해서는 무효화 메쏘드가 없다. 즉, 컴포넌트가 상위 컨테이너에 추가된 이후로는 이 메쏘드를 다시 호출할 필요가 없음을 의미한다. 무효화 메쏘드에 대한 자세한 정보는 어도비 사이트의 라이브 도큐먼트를 참고하기 바란다.
컴포넌트 속성에 대한 변경 사항을 조율할 수 있다. commitProperties() 메쏘드는 컴포넌트가
화면에 보여지는 방식에 영향을 주는 속성들과 함께 사용된다.
FLEX는 invalidateProperties() 무효화
메쏘드의 호출이 있을 때 commitProperties() 메쏘드의 호출을 계획한다. commitProperties() 메쏘드는 invalidateProperties()
메쏘드의 호출이 있고 나서 다음 render 이벤트 발생시 수행된다. addChild() 메쏘드를
사용해 컨테이너에 컴포넌트를 추가하는 경우 FLEX는 자동으로 invalidateProperties() 메쏘드를 호출한다.
픽셀
값으로 컴포넌트의 디폴트 크기를 정하고 선택적으로 컴포넌트의 디폴트 최소 크기를 설정한다.
FLEX는 invalidateSize() 무효화 메쏘드 호출이 있을 때 measure() 메쏘드의 호출을 계획한다.
measure() 메쏘드는 invalideateSize() 메쏘드의 호출이 있은 후 다음 render 이벤트 발생시
실행된다.
addChild() 메쏘드를 사용해 컨테이너에 컴포넌트를 추가하는 경우 FLEX는 자동으로
invalidate Size() 메쏘드를 호출한다.
주의할 점은 FLEX는 explicitWidth 속성과 explicitHeight 속성의
값이 NaN인 경우에만 이 메쏘드를 호출한다. 즉, 사용자가 =
MX />
모든 이전 속성과 스타일 셋팅을 바탕으로 컴포넌트
자식의 크기와 위치를 정하고 컴포넌트가 사용하는 스킨과 그래픽 요소를 드로잉 한다.
updateDisplayList() 메쏘드의 역할은 디스플레이할 컴포넌트 요소들의 크기와 위치를 정하는 것이다.
컴포넌트는
updateDisplayList() 메쏘드가 호출되기 전까지는 스크린에 나타나지 않는다. FLEX는 invalidateDisplayList() 무효화 메쏘드의
호출이 있을 때 updateDisplayList() 메쏘드의 호출을 계획한다.
updateDisplayList() 메쏘드는 invalidateDisplayList()
메쏘드의 호출이 있은 후 다음 render 이벤트 발생시 실행된다. addChild() 메쏘드를
사용해 컨테이너에 컴포넌트를 추가하는 경우 FLEX는 자동으로 invalidateDiplayList() 메쏘드를 호출한다.
Container 클래스와 Container
클래스의 몇몇 서브 클래스는 layoutChrome() 메쏘드를 사용해 컨테이너 주변의 외곽 공간을
정의한다. FLEX는 invalidateDisplayList() 무효화 메쏘드 호출시 layout Chrome() 메쏘드의 호출을 계획한다.
layoutChrome() 메쏘드는 invalidateDisplayList() 메쏘드의 호출이 있은 후 다음 render 이벤트
발생시 수행된다. addChild() 메쏘드를 사용해 컨테이너에 컴포넌트를 추가하는 경우 FLEX는 자동으로
invalidateDisplayList() 메쏘드를 호출한다.
이제 기본 컴포넌트 구조를 이해했으므로 액션스크립트 3.0
컴포넌트 구현과정을 살펴보도록 하자. 참고로 우리가 만들게 될 MultiCheckBox 컴포넌트의 기능을
구현하기 위해 위에 나열한 모든 메쏘드를 구현할 필요는 없다.
[요구 사항]
기준 정보에 따른 검색 기능은 거의 모든
프로젝트에서 요구된다. 또한 기준 정보는 그룹핑 되어 있는 경우가 대부분이다. 예를
들어, 사용자정보, 제품정보, 거래선정보 등과 같이 그룹핑 되어 있다. 하나의 그룹핑
되어 있는 기준정보에 해당하는 여러 선택 가능한 정보들이 있는데 이 들을
다중 선택할 수 있는 컴포넌트가 필요하다.
FLEX에는 CheckBox 컴포넌트가 존재하지만
기준정보의 각 그룹마다 매번 반복 구현해야 하는 불편함이 있으므로, 그룹핑 된
기준정보를 다중으로 선택 가능한 컴포넌트가 필요하다.
[기능 정의]
1. 헤더와 바디를 상하로 구분해 기준정보의 제목을 컴포넌트 헤더 부분에
지정하도록 한다.
2. 데이터를 바인딩시키면 자동으로 컴포넌트 바디 부분에 체크박스가 순서대로
나열되도록 한다.
3. 체크박스가 나열되는 방향을 가로("horizontal") 또는 세로("vertical")로 정렬 시키도록
속성을 제공한다.
4. 나열되는 첫번째 체크박스는 항상 All로 지정한다.
5. 컴포넌트의
크기는 픽셀 값뿐 아니라 퍼센트 값을 사용해 지정할 수 있도록 한다.
6. All 체크박스를 클릭하면 다른 체크박스들의 체크가 해제되도록 한다.
7. All
체크박스가 체크된 상태에서 다른 체크박스들 중 하나를 클릭하면 All 체크박스의 선택을
해제한다.
8. 특정 하나의 체크박스만 선택된 상태에서 다시 그 체크박스를 클릭하면
자신은 선택 해제가 되고 All 체크박스가 선택되도록 한다.
9. 사용자 이벤트를
정의한 후 체크박스를 클릭했을 때 이벤트를 dispatch 하고 사용자가 리스닝 해
핸들링 할 수 있도록 한다.
10. 최종적으로 검색 버튼을 클릭 했을
기준 정보에 나열된 체크 박스들 중 선택된 항목들에 대해 문자열로 반환하는
메쏘드를 제공한다.
패키지는 편의상 kr.co.riasoft.controls로 지정한다. 컴포넌트 이름은 MultiCheckBox라고 설정하고, 패키지 디렉토리에 MultiCheckBox.as 클래스파일을 생성한다.
MultiCheckBox 컴포넌트는 상하로
헤더와 바디를 가지고 있다. 헤더는 타이틀을 보여주게 될 Label이 HBox에 내포된다.
바디는 체크박스를 담게 될 Tile 컴포넌트가 위치하게 된다. Tile을 선택한 이유는
추가될 하위 컴포넌트들 사이즈에 따라 자동으로 배치시키고 스크롤 핸들링을 해주기 때문이다.
또한 ‘기능정의 3’을 만족시키기 위해 Tile의 기본 기능을 사용하면 따로 구현하지
않아도 되기 때문이다.
MultiCheckBox 컴포넌트는 mx.containers.VBox를 상속받아 헤더와 바디를 내포하게 된다.
[패키지 정의 및 클래스 임포트]
컴포넌트가 위치할
폴더(패키지)를 다음과 같이 정의한다.
package kr.co.riasoft.controls
컴포넌트
내부에서 사용하게 될 클래스들을 다음과 같이 임포트한다. 임포트하는 클래스들을 지정할 때
flash, mx, 사용자 패키지 순으로 구분하는 것이 가독성에 도움이 된다.
import flash.events.MouseEvent;
import flash.events.Event;
import flash.geom.Rectangle;
import mx.containers.VBox;
import
mx.containers.HBox;
import mx.containers.Tile;
import mx.controls.Label;
import mx.controls.Spacer;
import mx.controls.Button;
import mx.controls.CheckBox;
import mx.collections.*;
import mx.utils.*;
import kr.co.riasoft.events.SelectedCheckBoxEvent;
[이벤트
메타데이타 정의]
이전 MXML 컴포넌트 개발하기 기사에서 MonthChooser.mxml의 코드를 참고해
보자.
[Event("selected")]
위와 같이 메타데이타를
정의해 이벤트를 전달했던 것을 기억할 것이다. 액션스크립트 3.0 컴포넌트에서 다음과 같이
[Event(name="이벤트타입", type="사용자정의이벤트클래스")] 형태로 메타데이타를 정의한다. 이 구문은 임포트 후, class 정의
바로 상위 라인에 위치하게 된다.
[Event(name="selected", type="kr.co.riasoft.events.SelectedCheckBoxEvent")]
[createChildren () 메쏘드 구현하기]
내부 컴포넌트들을 생성하기 전에 각 컴포넌트들에
대해 전역 변수가 선언되어 있어야 한다.
다른 메쏘드에서 쉽게 접근할 수
있도록 하기 위함이다.
private var HBoxHeader :HBox;
private var
LabelTitle :Label;
private var formTile :Tile;
HBoxHeader 변수는 HBox
타입으로서 컴포넌트의 헤더 컨테이너이다. LabelTitle 변수는 Label 타입으로서 헤더의 타이틀이다. formTile
변수는 Tile 타입으로서 CheckBox들을 담게 될 컨테이너이다.
각 하위 컴포넌트들에 대해
new 연산자를 사용해 생성하고 HBoxHeader에 LabelTitle을 addChild () 메쏘드로 추가하고 컴포넌트에
HBoxHeader와 formTile을 addChild () 메쏘드로 추가한다. 각 하위 컴포넌트들에 대해 알맞게
사이즈와 스타일을 적용시킨다.
MultiCheckBox 컴포넌트는 formTile에만 스크롤이 필요하기 때문에 스크롤이 필요
없다. 따라서 horizontalScrollPolicy 속성과 verticalScrollPolicy 속성을 "off"로 지정하였다. 또한 외곽과 배경을
정리하기 위해 다음과 같은 스타일을 적용하였다.
setStyle ( "backgroundColor",
0xFFFFFF );
setStyle ( "borderStyle", "solid" );
setStyle ( "dropShadowEnabled", true
);
setStyle ( "horizontalAlign", "center" );
setStyle ( "fontSize", 12 );
setStyle ( "paddingLeft", 5 );
setStyle ( "paddingTop", 5 );
setStyle
( "paddingRight", 5 );
setStyle ( "paddingBottom", 5 );
HBoxHeader의 넓이는 100%를 지정해 컴포넌트 크기에 따라 자동으로 조정되도록 했고 외곽과
배경 처리를 위해 스타일을 다음과 같이 적용했다.
HBoxHeader.percentWidth =
100;
HBoxHeader.setStyle ( "paddingLeft", 5 );
HBoxHeader.setStyle ( "paddingTop", 2 );
HBoxHeader.setStyle ( "paddingRight", 5 );
HBoxHeader.setStyle ( "paddingBottom", 2 );
HBoxHeader.setStyle
( "verticalAlign", "middle" );
HBoxHeader.setStyle ( "backgroundColor", 0xFFFFFF );
HBoxHeader.setStyle (
"borderStyle", "solid" );
formTile에 대한 높이와 넓이도 컴포넌트가 리사이즈
될 때마다 자동으로 계산되도록 100%로 지정했고 외곽과 배경
[
출처 : http://www.adobeflex.co.kr/iwt/board/board.php?tn=pds_tech&bc=7&id=77&mode=view ]












