에이레네님이 올리신 글을 보고 알게 된 포스트인데 상당히 좋은 내용이라서 번역하여 올려봅니다.
엉터리로 번역되었을 가능성 다분함.. 태클환영..;
이 글은 작성시 부터 여러 많은 개발자 분들이 내용에 오류가 있다고 지적해주셨습니다. 글의 내용에 대해서 지적해주시고 하는 것은 정말 감사드립니다. 제가 부족한 점이 많아 이해를 제대로 못하였거나, 글 작성에 문제가 있을 수 있기때문에 여러분의 덧글 하나하나가 정말 도움이 많이 되고 있습니다.
제가 본문을 수정하거나 혹은 이 글을 삭제하려고 했으나, 혹시 필요하신 분들이 있을 것 같아 본문을 수정하거나 삭제하지는 않겠습니다. 글을 다 읽으신 후 밑에 다른 분들의 덧글도 읽어보시면 더욱 좋은 것들을 배우실 수 있다고 생각합니다.
ActionScript 에서 int는 피하자구요!
Flex에 대해 알아갈수록, int에 대해서 알게 될수록, int를 사용하지 않게 되었습니다.
int가 정말 필요하지 않는 이상 int는 더 이상 사용하지 않을 것입니다.
이유 1 : Number가 int보다 실제적으로 더 빠릅니다.
놀랍게도, 사실입니다. ECMAScript Edition 4는 ECMAScript 이전 버전과 호환이 가능하게 설계되었습니다.
그래서 수학적으로 완전 무결하게 옳다라는 것을 보장하기가 어렵습니다.
어떤 방법이 더 빠를 것 같은가요? 제가 사용하는 컴퓨터에서는 int 를 사용하여 331ms 걸렸고, Number 는 291ms 걸렸습니다.
▲ 실제로 이 글을 읽는 분이 걸린 시간.
왜 그럴까요? 다음의 표현식을 보시죠.
만약 여러분이 j = 2^23 - 1 로 값을 시작했으면 어떠할 것 같습니까? 일부 프로그래밍 언어에서는 15번 더하자
마자 오버플로우 문제가 나타날 것입니다. 그러나 ECMAScript는 수의 개념이 좀 느슨합니다. 시스템에서 필요시 int에서
double로 변환되는 것을 지원하고 있습니다. 이 때문에 실질적으로 모든 수학적 계산은 내부적으로 int가 아니라 Number로 합니다.
Number로 모든 것이 완료되는 것을 감안해보면 int를 Number로 변환하는 비용과 그 만큼의 시간이 왜 int 를 사용하면 시간이 더 걸리는지에 대한 이유입니다.
다음은 Number는 실제로 int 보다 정확하게 정수 값을 저장시키기 때문에, int보다 Number 를 써야 되는 이유입니다.
이유 2 : Number는 더 많은 bit를 가집니다.
이 이유는 후에 확실하게 할게된 Number에 대한 놀라운 사실입니다. 어떻게 알게된 것인지 설명해보겠습니다.
Date
객체에는 1970년 1월 1일 자정 부터의 시간을 milliseconds 단위의 숫자로 반환하는 time 이라는 속성이 있습다.
그 값은 정수형 값이고 ActionScript에는 long 타입이 없기 때문에, 반환 타입이 진짜 int (아니면 아마도
uint) 라고 가정했습니다.
왜 버그가 나는 걸까요?
back of the envelope calculation 에서 1970년 1월 1일부터 2^32 milisecond 보다 더 값을 가지기 때문에 결과가 오버플로우 난다는 것을 알려주고 있습니다. 바보같은 실수죠.
위의 값으로 Date() 객체에 다시 넣어보면 각각 1970년 1월 26일, 2008년 4월 24일 이 출력됨. - 검쉰
그렇다면 int의 bit보다 더 큰 수를 써야할 때, ActionScript는 Long 타입이 없는 상태에서 어떻게 오버플로우나 이런 부정확한 값을 해결할 수 있을까요?
속을 살펴보면, Number는 아래에 있는 숫자형을 포함하고 있습니다.
- int
- uint
- IEEE double
저는 항상 정수의 계산를 위해 double 형태를 사용하는 것을 피했습니다. 왜냐하면 모든 자리수가 보존될 것이라고 전혀
확신할 수 없었기 때문입니다. 왜냐하면, 개인적인 견해로는 정확성 측면에서 보자면 double은 int 보다 더 큰 범위의 수를
저장하기 때문입니다.
결국엔 ActionScript 의 경우에, Number는 더 큰 수의 범위를 저장할 수 있습니다. 그리고 어떤 정수형보다 정확합니다. 그건 아마도 ActionScript 는 64bit 의 정수형 타입이 없기 때문인 것 같습니다.
IEEE double 포멧은 다음과 같이 구현되어 있습니다.
부호를 위한 1 bit, 지수를 위한 11 bit, 숫자부분을 위한 52 bit. 따라서, 정밀도의 손실 없이 int보다 더 큰 bit의 수를 확실히 저장할 수 있습니다.
언제 int를 사용해야 될까요?
다음은 int의 적당한 사용방법입니다.
- 메모리를 절약하고 싶을 때 (비록 아주아주 많은 양의 저장공간이 있다 하더라도 결국에는 좋지 않은 영향을 줄 것입니다)
- 정수 값으로 강제변환 시 (예를 들어 var i: int = j / 2)
- 클라이언트에서 서버쪽으로 정수값을 보낼 때 버그를 줄이기 위해서 (값 전달용 객체안에 int 필드가 있을 때).
이제 다 설명했으니, 저는 이제 제 코드의 대부분의 Number를 확인해 볼 것입니다.
참고 : 제가 추가로 좀 더 서술하자면, 위에서 int보다 Number가 더 빠르다는 것은 특정 상황에 대해서 그렇다는 것입니다.
int로 어떤 연산을 진행하는 것이 int보다 더 큰 Number로 연산을 진행하는 것 보다 더 빠른 것이 당연합니다. int가 Number보다 처리해야할 bit가 적으니까요. (var i:int = 0; i++; 이런경우) 다만, int형으로 연산중에 int형의 크기보다 더 큰 수를 처리해야하는 경우에 다른 언어에서는 잘못된 값이 출력이 됩니다만(이유 2에서 이런 문제를 지적하고 있습니다), AS3는 자동으로 Number 로 변환하여 연산을 진행합니다.
이런 이유에서 "int가 내부적으로 Number로 변환되는(int의 크기를 넘어서는 연산) 경우에는 Number로 진행하는 것이 더 빠르다." 라는 것이 이 포스트의 속도 문제에서의 핵심입니다.
원저자가 약간 int에 대한 매우 안좋은 감정이 있긴 한 모양입니다만, 이 글을 보신 분들은 때에 따라서 잘 사용하시면 좋겠죠?
'Dev > ActionScript' 카테고리의 다른 글
[ActionScript] Array를 왜 Hash로 쓰나요? Object 놔두고. (21) | 2009.07.01 |
---|---|
[Flex & Flash] ActionScript 3.0에서 BMP 파일 로드하기 (11) | 2009.06.18 |
[Flex&Flash] useCodePage = true 가 한글 깨짐 방지 코드라고? (26) | 2009.03.27 |
[Flex] with 를 아십니까? (12) | 2008.06.09 |
[Flex] for문 쓸때 조건문에 유의하자. (23) | 2008.05.09 |
그렇다면, 만약에 컴포넌트가 원형이어야 된다면 어떨까요? 라운드 처리된 곳도 빠져나가는데, 원형의 컴포넌트가 필요하다면?
원형을 벗어나는 영역은 화면에서 나타나지 않게 하면 간단하게 해결 할 수 있습니다. 이럴 때 mask를 쓰면 됩니다.
mask는 DisplayObject 의 속성으로 mask로 할당된 DisplayObject 의 영역만큼만 해당 컴포넌트를 보여주게 됩니다.
나머지는 화면에 나타나지 않게 되죠. 아래는 레퍼런스에 있는 마스크 예제입니다.
▲ 네모난 mask를 Drag 해보세요. mask 영역만큼만 TextField가 보입니다.
그럼 위에서 보신 mask를 이용하여 Canvas를 상속받은 myCircleCanvas라는 이름의 둥근 컴포넌트를 만들도록 하겠습니다.
위의 소스에서는 mask를 Sprite 객체를 이용하였습니다만, Flex에서는 Canvas에 Sprite 객체를 addChild 하면 오류가 나므로(Canvas가 상속하고 있는 Container에 addChild 시 IUIComponent가 구현되어있어야 하므로), UIComponent를 이용하도록 하겠습니다.
( 참고: 왜 Sprite는 Canvas에 addChild 안되는 걸까요? )
레퍼런스에서 마스크로 사용하였던 Sprite 나 현재 mask로 사용하는 UIComponent는
둘 다 DisplayObject를 상속하고 있으므로 mask 로 할당하여도 됩니다.
아래는 myCircleCanvas 클래스의 코드입니다.
컴포넌트의 구분을 위해 결과물에는 backgroundColor 값을 주었습니다.
결과물은 myCircleCanvas 객체에 Button을 올려놓은 모습입니다.
둥근 mask 영역 밖으로 벗어나는 Button의 영역은 화면에서 나타나지 않음을 확인하실 수 있습니다.
이상 mask를 이용하여 둥근 컴포넌트를 생성하는 것에 대해 간단하게 다루어 보았습니다.
'Dev > Flex' 카테고리의 다른 글
[Flex] 더블클릭(doubleClick)을 사용해보자. (6) | 2008.06.03 |
---|---|
[Flex] XML을 String 으로 만들기 (15) | 2008.05.28 |
[Flex] DataGrid 의 아이템을 클릭할때는 itemClick 이벤트를 사용하자. (Tip) (12) | 2008.04.22 |
[Flex] 수동으로 이벤트 발생시키기 - dispatchEvent() (7) | 2008.03.17 |
[Flex] 일정시간 후에 자동으로 종료되는 Alert (5) | 2008.01.24 |
잠 시 책 소개를 하자면, 초보 개발자 '나초보' 씨가 실력있는 선배 '김경험', '이튜닝' 같은 분들에게 하나씩 배워가는 스토리로 쓰여 있습니다. 참 읽기 편하네요. 저 역시 '나초보' 와 그닥 다를 바 없는 실력 형편없는 개발자인지라 공감도 많이 되고, 많이 읽으면서 배우고 있습니다. 저자이신 '이상민'님 정말 감사합니다. ;)
참 유용하니 꼭 읽어보시길 권해드립니다.
아무튼, 상당히 유용한 이야기들로 가득차 있는데요, 책 내용 중 간단하게 언급된 for문 관련 이야기중 ActionScript를 쓰는 개발자들에게도 유용할 것 같은 Tip 이라 포스팅해봅니다. (사실 저 같은 어리버리 개발자한테만 유용할지도?)
for문은 상당히 많이 쓰는 loop 중에 하나입니다.
하지만 프로그래머들이 흔히 간과할 수 있는 부분이 있습니다.
우선 for문에 대해서 알아봅시다.
for
루프를 사용하면, 특정의 범위의 값에 대한 변수의 반복 처리를 실행할 수가 있습니다. for
명령문(statement)에는, 3 개의 식을 지정할 필요가 있습니다. 해당 식은,
1. 초기치로 설정하는 변수
2. 루프가 언제 종료하는지를 지정하는 조건문(conditional statement )
3. 각 루프로 변수의 값을 변경하는 식 입니다.
예를 들어, 다음의 코드는 5 회 루프 합니다. 변수
i
는 0 으로 시작되어, 4 로 끝납니다. 출력은 0 ~ 4 의 수치가 되어, 각 수치는 개별의 행에 출력됩니다.
여기서 눈여겨 봐야할 것은 2번째 조건문 입니다.
만약 Array 에 값을 for 루프를 돌아 처리한다고 할 때, 흔히 아래와 같이 쓰게 됩니다.
이 때 2번째 조건 명령문에 들어있는 dataArray.length 가 문제가 됩니다. 루프를 도는 도중에 계속 호출되어 배열의 길이를 알아오기 때문입니다.
이 것은 다음과 같이 변경하여 좀 더 빠르게 바꿀 수 가 있습니다.
변수 dataArrayLength에 배열의 길이를 담은 후에 조건문에 대입하므로서 불필요하게 dataArray.length 를 매번 호출하지 않아도 되죠.
이와 비슷한 경우가 종종 있을 경우가 있습니다.
예를 들어 Canvas에 있는 자식 객체들의 수를 구하기 위해 Container 클래스에 정의된 numChildren 속성을 호출한다던지 말이죠.
아래의 코드는 클릭 이벤트가 발생하면 클릭된 Canvas의 자식 객체에 대해서 어떤 동작을 하는 코드입니다.
이제 실제 테스트를 해보겠습니다.
테스트해본 코드는 다음과 같고요, 그 아래 실제 결과물로 이 포스트를 읽는 분들이 테스트를 해보세요!
(참고 : creationComplete 시에 init() 을 실행시켜 dataArray 에는 10,000,000개의 데이터를 넣었습니다.)
저는 length 사용시: 953ms, length 미사용시: 187ms 걸렸습니다. ;)
알고도 그냥 지나칠 수 있는 부분이니까 습관을 들이도록 합시다. ;)
긴 글 읽으신다고 고생하셨습니다.
'Dev > ActionScript' 카테고리의 다른 글
[ActionScript] Array를 왜 Hash로 쓰나요? Object 놔두고. (21) | 2009.07.01 |
---|---|
[Flex & Flash] ActionScript 3.0에서 BMP 파일 로드하기 (11) | 2009.06.18 |
[Flex&Flash] useCodePage = true 가 한글 깨짐 방지 코드라고? (26) | 2009.03.27 |
[Flex] with 를 아십니까? (12) | 2008.06.09 |
[Flex] int나 uint보다 Number를 쓰세요! (29) | 2008.06.05 |
Flex 에서 MXML로 정의한 버튼이 다음과 같이 있다고 가정합니다.
이 버튼을 클릭할 때 어떠한 동작을 하고자 하면 해당 버튼에 다음과 같이 클릭 이벤트 핸들러를 등록시켜주면 됩니다.
public function alert(evt:MouseEvent):void
{
Alert.show("Hello, Flex!", "Alert");
}
MXML ---
<mx:Button id="btnAlert" label="Alert!" click="alert(event)" />
만약, 실제 버튼을 클릭하지 않고서 버튼을 클릭한 것과 같은 이벤트를 수동으로 발생시키려면 어떻게 해야할까요?
이럴때 필요한 것이 dispatchEvent 입니다.
dispatchEvent 의 구조는 다음과 같습니다.
event
:Event)자세한 설명은 수동에 의한 이벤트의 송출(Dispatch) 에서 참고하도록 하고 본 포스트에서는 생략하겠습니다.
아래에 보여드릴 소스는 캔버스를 MXML로 정의하여 이 캔버스를 클릭하였을때 버튼을 클릭한 것 과 같이 수동으로 이벤트를 발생시킴으로써 버튼을 클릭하였을 때와 같이 팝업이 뜨도록 하고 있습니다.
<mx:Script>
<![CDATA[
import mx.controls.Alert;
public function alert(evt:MouseEvent):void
{
Alert.show("Hello, Flex!", "Alert");
}
public function canvasClick(evt:MouseEvent):void
{
btnAlert.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
}
]]>
</mx:Script>
<mx:Canvas x="44" y="79" width="200" height="153" backgroundColor="#FF0000" borderStyle="solid"
cornerRadius="20" click="canvasClick(event)">
<mx:Label text="Click Here!" horizontalCenter="0" verticalCenter="0"/>
</mx:Canvas>
<mx:Button id="btnAlert" x="271" y="137" label="Alert!" click="alert(event)"/>
</mx:Application>
dispatchEvent 를 이용하여 마치 버튼을 클릭한 것 처럼 MouseEvent.CLICK 이벤트를 버튼에 dispatch 함으로써 버튼에서 클릭 이벤트 핸들러로 등록해놓은 alert() 메소드가 실행되게 됩니다.
물론 위의 예제에서는 단순히 클릭시에 Alert 을 띄우는 작업으로 그쳤기에 문제가 없었지만, 실제 클릭이벤트와 관련된 작업이 필요할 경우 새로 생성해준 마우스이벤트 (new MouseEvent(MouseEvent.CLICK)) 의 상세한 값들을 제어할 필요가 있습니다.
와.. 많다.;;;
'Dev > Flex' 카테고리의 다른 글
[Flex] Mask 를 이용한 둥근 컴포넌트 만들기 (19) | 2008.05.13 |
---|---|
[Flex] DataGrid 의 아이템을 클릭할때는 itemClick 이벤트를 사용하자. (Tip) (12) | 2008.04.22 |
[Flex] 일정시간 후에 자동으로 종료되는 Alert (5) | 2008.01.24 |
[FLEX] 왜 Sprite는 Canvas에 addChild 안되는 걸까? (7) | 2007.12.04 |
[FLEX] Coloring the Background of Cells (20) | 2007.11.20 |
지난 2월 19일 세미나에서 공지한 바와 같이, 이번 3월 18일에 Adobe RIA World 2008이 열린답니다.
Adobe Flex 공식사이트에서 공지가 올라왔네요.
이번에 참 볼거리가 많은 것 같아요.
|
동시통역 |
하나같이 다 좋은 세션이네요. 죄다 들을 방법은 없을까요? ^^;
회사에서 안보내주면 휴가라도 써서 가야겠습니다. ;)
'Dev > 행사 이모저모' 카테고리의 다른 글
[Flex&Flash] 사진으로 보는 Flash Platform 한글문제 공동대응팀 해오름 모임 (48) | 2009.04.12 |
---|---|
[Flex&Flash] Flash Platform 한글문제 공동대응팀 해오름 모임을 가집니다! (27) | 2009.04.01 |
[Flex] RIA Camp 2nd in Seoul 에 참석하고 왔습니다. (18) | 2008.09.30 |
제 1회 Flex Camp에 다녀왔습니다. ;) (38) | 2008.07.13 |
Who are RIA Developers? - Flex 3 & AIR 에 참석하고 왔습니다. (2) | 2008.02.19 |
150석 규모로 사전등록을 받았는데 공지뜬지 얼마되지 않아 마감되는 뜨거운! 열기를 느낄 수 있는 자리였던 것 같네요.
실제로 많은 분들이 오셔서 자리가 없어 뒤에 서서 세미나를 들으시는 모습도 볼 수 있었습니다.
어떠했는지는 여기를 클릭하셔서 보시면 되겠고요, 실제 세미나 자료도 올라가 있으니 참고하시기 바랍니다. (pdf로 배포해주시네요)
2월 25일에 AIR 정식버전이 발표된다고 하셨는데, 참 기대되는 이야기였습니다.
마지막 질의응답시간에는 몇가지 질문들이 나왔었는데, 한가지 기억나는건 대충 내용이
'어도비에서는 자바만 지원하는 것인지, 다른언어(php, ruby)등은 지원하지 않는지?'
였는데 서드파티 쪽은 알아보시라.. 하고 끝냈던 것이 기억나네요.
다른 AMF 서비스는 Ruby 같은 경우는 RubyAMF 가 있고, php는 AMFPHP, Zend AMF, AMFPHP가 존재하고요.
물론 Java로 된 OpenAMF 라는 AMF도 있고 .NET은 AMF.NET 이 존재합니다.
몇가지 AMF 서비스의 경우에 속도 테스트 한 결과는 지돌스타님의 글을 참고하시면 좋겠네요. ^^
그리고 나올때 설문지를 드리니 기념품을 주셨습니다. ;)
IT관리자를 위한 RIA 세미나 - 오전 , 웹 디자이너를 위한 RIA 세미나 - 오후
공지가 파묻힌 느낌이라 잘 모르시는 듯.
http://www.adobeflex.co.kr/iwt/board/board.php?tn=news&id=124&mode=view
참고하시면 되겠습니다.
'Dev > 행사 이모저모' 카테고리의 다른 글
[Flex&Flash] 사진으로 보는 Flash Platform 한글문제 공동대응팀 해오름 모임 (48) | 2009.04.12 |
---|---|
[Flex&Flash] Flash Platform 한글문제 공동대응팀 해오름 모임을 가집니다! (27) | 2009.04.01 |
[Flex] RIA Camp 2nd in Seoul 에 참석하고 왔습니다. (18) | 2008.09.30 |
제 1회 Flex Camp에 다녀왔습니다. ;) (38) | 2008.07.13 |
Flex 3와 AIR 런칭 행사인 Adobe RIA World 2008이 열립니다! (6) | 2008.02.28 |
단순히 잠깐 떠있다가 없어져도 되는 것인데 말이죠.
Alert에 다가 원하는 시간을 대입하면 Alert 출력 후에 입력한 시간이 지난 후 없어지도록 만들어보았습니다.
다음과 같이 간단하게 사용하시면 됩니다.
소스는 아래를 참고하시면 되겠습니다.
{
import flash.events.TimerEvent;
import flash.utils.Timer;
import mx.controls.Alert;
import mx.events.CloseEvent;
import mx.managers.PopUpManager;
public class AutoDestroyAlert
{
// 일정 시간동안만 Alert 보여주기. (경고용)
public static function show(text:String = "", title:String = "",
destroyTime:Number = 1000, iconClass:Class = null):Alert
{
var myAlert:Alert;
var myTimer:Timer;
// destroyTime 후 타이머 발생
function timerEventHandler(evt:TimerEvent):void
{
myTimer.stop();// 타이머 종료
mx.managers.PopUpManager.removePopUp(myAlert); // Alert 제거
}
myTimer = new Timer(destroyTime,1); // 타이머를 설정된 값에 맞게 Setting
myTimer.addEventListener(TimerEvent.TIMER, timerEventHandler); // 이벤트핸들러 등록
myTimer.start(); // 타이머 시작
return myAlert;
}
}
}
그럼 즐거운 개발 되시길!!!
'Dev > Flex' 카테고리의 다른 글
[Flex] DataGrid 의 아이템을 클릭할때는 itemClick 이벤트를 사용하자. (Tip) (12) | 2008.04.22 |
---|---|
[Flex] 수동으로 이벤트 발생시키기 - dispatchEvent() (7) | 2008.03.17 |
[FLEX] 왜 Sprite는 Canvas에 addChild 안되는 걸까? (7) | 2007.12.04 |
[FLEX] Coloring the Background of Cells (20) | 2007.11.20 |
[FLEX] XML의 값을 Boolean 값으로 캐스팅하는 방법? (1) | 2007.11.16 |
- Sprite는 무엇인가요?
먼저 Sprite는 무엇인지 잘 모르는 분들을 위해 설명을 곁들여보죠.
물론, Sprite를 FLEX에서 사용하고 싶다면 UIComponent에 addChild 하여서 사용하면 됩니다. (참고 : 지돌스타님 블로그)
하지만, UIComponent를 상속하고 있는 Canvas에는 왜 addChild가 되지 않는가 하는 것이 이 글의 주요 주제죠.
- Sprite을 Canvas에 addChild 하면 ?
여기서 분명한 것은 Sprite를 Canvas에 addChild하면
"TypeError: Error #1034: 유형 강제 변환에 실패했습니다. flash.display::Sprite@45cd351을(를) mx.core.IUIComponent(으)로 변환할 수 없습니다."
라고 컴파일시에 Error가 난다는 겁니다.
오류가 난 곳을 따라가보면 Canvas가 상속하고 있는 Container 클래스의 addingChild 메소드에서 나는 것을 알 수 있습니다.
{
// Throw an RTE if child is not an IUIComponent.
var uiChild:IUIComponent = IUIComponent(child); // 이 줄에서 오류가 납니다.
...
}
IUIComponent 타입인지 확인하고 있는데, Sprite는 IUIComponent type이 아니기때문에 오류가 나고 있는 것입니다.
- IUIComponent는 무엇인가요?
그럼 IUIComponent는 무엇일까요?
클래스 안에 있는 주석으로 다음과 같이 설명되고 있습니다.
FLEX의 Visual Component의 기본은 UIComponent 입니다.
IUIComponent 인터페이스는 이 UIComponent 가 구현하고 있는 인터페이스로서 위의 설명에 따르면,
Flex의 Container 나 List의 child들은 IUIComponent 인터페이스를 구현하고 있어야 된다고 합니다.
(아니면 위 에러메세지 처럼 IUIComponent 타입이 아니라서 오류나죠 ㅡㅂㅡ)
- 그렇다면 Canvas는?
위의 관계대로 만들어진 Canvas에는 IUIComponent가 구현된(다시 말해 UIComponent를 상속받는) 클래스들은
모두 addChild 될 수 있으나 그렇지 않은 클래스는 addChild 되지 못하게 됩니다.
Sprite는 IUIComponent 인터페이스를 구현하고 있지 않으므로
Container에는 addChild 할 수 없는 것입니다.
- Tip
Sprite를 Canvas 같은 Container 에 추가하여야 하는 일이 생긴다면 아래와 같이 클래스 만드셔서 addChild 하셔도 괜찮을 것 같네요. :)
{
import flash.display.Sprite;
import mx.core.UIComponent;
public class mySprite extends UIComponent
{
private var sprite:Sprite;
public function mySprite()
{
super();
sprite = new Sprite();
}
override protected function createChildren():void
{
super.createChildren();
this.addChild(sprite);
}
.....
}
}
참고자료 :
[팁] Sprite 사용법
Flex 2 Beta 3 : Sprites
'Dev > Flex' 카테고리의 다른 글
[Flex] 수동으로 이벤트 발생시키기 - dispatchEvent() (7) | 2008.03.17 |
---|---|
[Flex] 일정시간 후에 자동으로 종료되는 Alert (5) | 2008.01.24 |
[FLEX] Coloring the Background of Cells (20) | 2007.11.20 |
[FLEX] XML의 값을 Boolean 값으로 캐스팅하는 방법? (1) | 2007.11.16 |
[FLEX] 간단한 아이템 렌더러(Item Renderer)를 만들어보자 (4) | 2007.11.12 |
말이 안되게 타이프 해놓은 것도 있으니(ㅡㅡ;) 그러려니... 하여 주세요 ;)
아래의 결과물은 해당 포스트의 소스를 빌드하여 올려보았습니다.
1. 아이템렌더러(itemRenderer)를 이용하여 특정컬럼의 배경색을 바꾸기 (itemRenderer Tab)
2. 컬럼에 직접 배경색을 지정하기 (backgroundColor Tab)
3. drawColumnBackground function을 재정의하여 배경색에 alpha 값을 주기 (backgroundAlpha Tab)
4. drawRowBackground function을 재정의하여 row에 배경색을 주기 (Custom Row Background Tab)
1. 아이템 렌더러(itemRenderer)를 이용하여 특정 컬럼의 배경색을 바꾸기
(itemRenderer Tab 참고)
특정 Cell의 배경색을 바꾸려면 아이템렌더러(itemRenderer)가 필요합니다.
아이템렌더러(itemRenderer)는 데이터그리드(Datagrid)의 전체에 적용하거나 특정 컬럼에 적용이 가능합니다만,
아래의 아이템렌더러(itemRenderer) 예제에는 Year 컬럼에만 적용하도록 하겠습니다.
간단하게 Label을 상속받아 updateDisplayList function을 재정의 하여서
Year의 값을 판단(Year의 값이 2000년 이전이면 파란색, 2000년 이후이면 녹색) 하여
Label에 파란색 또는 녹색의 사각형을 그려 배경색을 나타내고 있습니다.
<mx:Script>
<![CDATA[
import flash.geom.Matrix;
import flash.display.GradientType;
import flash.display.Graphics;
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth,unscaledHeight);
var m:Matrix = new Matrix();
m.createGradientBox(unscaledWidth,unscaledHeight);
var g:Graphics = graphics;
var colors:Array = (data.col3 < 2000 ? [0x0000CC,0x0000FF] : [0x00CC00,0x00FF00]);
g.clear();
g.beginGradientFill(GradientType.LINEAR, colors, [0.2,0.6], [0,255], m);
g.drawRect(0, -2, unscaledWidth, unscaledHeight+4 );
g.endFill();
}
]]>
</mx:Script>
</mx:Label>
아래는 AS Class 로 동일하게 만들어본 아이템 렌더러입니다.
{
import flash.geom.Matrix;
import flash.display.GradientType;
import flash.display.Graphics;
import mx.controls.Label;
public class ColoredBackgroundItemRenderer extends Label
{
public function ColoredBackgroundItemRenderer()
{
super();
}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth,unscaledHeight);
var m:Matrix = new Matrix();
m.createGradientBox(unscaledWidth,unscaledHeight);
var g:Graphics = graphics;
var colors:Array = (data.col3 < 2000 ? [0x0000CC,0x0000FF] : [0x00CC00,0x00FF00]);
g.clear();
g.beginGradientFill(GradientType.LINEAR, colors, [0.2,0.6], [0,255], m);
g.drawRect(0, -2, unscaledWidth, unscaledHeight+4 );
g.endFill();
}
}
}
2. 컬럼에 직접 배경색을 지정하기
(backgroundColor Tab 참고)
단지 컬럼의 모든 Cell에 배경색을 지정하고 싶은 것이라면 아이템 렌더러를 만들 필요는 없습니다.
아래와 같이 데이터그리드(Datagrid) 컬럼에 있는 backgroundColor 속성을 이용하면 쉽게 가능합니다.
0xCC0000은 빨강색(■) 입니다. backgroundColor Tab에서 Make 컬럼에 적용되어 있습니다.
backgroundColor="red" 같은 경우도 가능합니다.
3. drawColumnBackground function을 재정의하여 배경색에 alpha 값을 주기
(backgroundAlpha Tab 참고)
데이터그리드(Datagrid) 컬럼은 투명도(Alpha)를 주는 속성이 없습니다.
하지만 데이터그리드(Datagrid)에 있는 drawColumnBackground function을 재정의하여 투명도를 줄 수 가 있습니다.
데이터그리드(Datagrid)를 상속받아서 만든 Class에서 아래와 같이 drawColumnBackground function을 재정의 합니다.
{
super.drawColumnBackground(s,columnIndex,color,column);
var background:Shape = Shape(s.getChildByName(columnIndex.toString()));
if( background )
{
background.alpha = 0.5;
}
}
하지만 위의 코드에서는 투명도가 0.5로 하드코딩 되어 있으므로 권장할 만한 코드가 안됩니다.
그래서 다음과 같이 Class 내에 투명도를 저장할 변수 columnBackgroundAlpha를 정의합니다.
그리고 재정의한 drawColumnBackground function의 코드를 변수 columnBackgroundAlpha에 의해
투명도를 변경할 수 있도록 다음과 같이 수정합니다.
외부에서 투명도는 아래와 같이 변경 할 수 있습니다.
4. drawRowBackground function을 재정의하여 row에 배경색을 주기
(Custom Row Background Tab 참고)
특정 컬럼이 아닌 한 줄(row)의 배경색을 바꾸려면 데이터그리드(Datagrid)를 상속받은 Class에서
아래와 같이 drawRowBackground function을 재정의 하여 배경색을 바꿀 수 있습니다.
year의 값이 2000년 이전이면 오렌지색, 2000년 이후면 흰색, 값이 없으면 녹색으로 출력하도록 하였습니다.
{
var dp:ArrayCollection = dataProvider as ArrayCollection;
var item:Object;
if( dataIndex < dp.length ) item = dp.getItemAt(dataIndex);
if( item != null && item.year < 20000 ) color = 0xFF8800;
else if( item != null && item.year>= 2000 ) color = 0xFFFFFF;
else color = 0x00CC00;
super.drawRowBackground(s,rowIndex,y,height,color,dataIndex);
}
하지만, 위의 코드는 색깔과 기준값들이 하드코딩되어 있어 권장할만한 코드가 못됩니다.
이 때, 배경색으로 쓰일 색을 외부에서 따로 구현할 수 있도록 하여 해결하도록 하겠습니다.
외부의 function을 쓰기 위해 Class에 아래와 같이 속성을 하나 추가하겠습니다.
그리고 아래와 같이 color값을 위에서 만든 Function에서 받아올 수 있도록 하여 줍니다.
{
if( rowColorFunction != null )
{
var dp:ArrayCollection = dataProvider as ArrayCollection;
var item:Object;
if( dataIndex < dp.length ) item = dp.getItemAt(dataIndex);
color = rowColorFunction( item, rowIndex, dataIndex, color );
}
super.drawRowBackground(s,rowIndex,y,height,color,dataIndex);
}
그리고 아래와 같이 rowColorFunction에 외부의 function을 지정하여 주고,
지정된 determineColor function은 아래와 같이 정의합니다.
{
if( item == null ) return 0x00CC00; // green are empty rows
if( item.year< 2000 ) return 0xFFCC00;
else if( item.year >= 2000 ) return 0xFFFFFF;
}
이제 정의 하였던 Class 외부에서 rowColorFunction에 알맞는 function을 정의하여 배경색을 변경 할 수 있게 되었습니다.
'Dev > Flex' 카테고리의 다른 글
[Flex] 일정시간 후에 자동으로 종료되는 Alert (5) | 2008.01.24 |
---|---|
[FLEX] 왜 Sprite는 Canvas에 addChild 안되는 걸까? (7) | 2007.12.04 |
[FLEX] XML의 값을 Boolean 값으로 캐스팅하는 방법? (1) | 2007.11.16 |
[FLEX] 간단한 아이템 렌더러(Item Renderer)를 만들어보자 (4) | 2007.11.12 |
[FLEX] Datagrid 에 Mouse Over 시에 나오는 색을 바꾸고 싶다면? (0) | 2007.11.09 |
데이터그리드를 이용하여 데이터를 출력할 때, 아이템 렌더러를 이용하면 자신의 의도대로 출력할 수 있어 참으로 유용합니다.
다음의 소스는 Money 라는 값을 출력하는데 이 것은 CurrencyFormatter를 이용하여 달러 표시로 출력하게 하여 보았습니다.
메인 App는 레퍼런스의 Datagrid에 예제를 약간 수정하여 사용하였습니다.
package
{
import mx.controls.Label;
import mx.formatters.CurrencyFormatter;
public class myItemRenderer extends Label
{
private var formatter:CurrencyFormatter;
public function myItemRenderer()
{
super();
formatter = new CurrencyFormatter(); // CurrencyFormatter
}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
this.text = formatter.format(data.money); // 출력될 값(data.money)에 CurrencyFormatter를 적용
}
}
}
Label을 상속받아서 CurrencyFormatter를 하나 추가하여 출력할 값(data.money)를 통화(Currency)형태로 출력하게 해주었습니다.
※ data - data를 살펴보면 Datagrid의 해당 Row의 모든 데이터가 들어있는 것을 확인할 수 있습니다.
...
<employee>
<name>Christina Coenraets</name>
<phone>555-219-2270</phone>
<email>ccoenraets@fictitious.com</email>
<money>10000</money>
<active>true</active>
</employee>
...
<mx:DataGrid id="dg" width="100%" height="100%" rowCount="5" dataProvider="{employees}">
<mx:columns>
<mx:DataGridColumn dataField="name" headerText="Name"/>
<mx:DataGridColumn dataField="phone" headerText="Phone"/>
<mx:DataGridColumn dataField="email" headerText="Email"/>
<mx:DataGridColumn dataField="money" headerText="Money" itemRenderer="{ new ClassFactory(myItemRenderer) }"/>
</mx:columns>
</mx:DataGrid>
...
DatagridColumn 에 itemRenderer로 위에서 만든 myItemRenderer를 물려주었습니다. ItemRenderer는 IFactory 형태로 받아드리므로 new ClassFactory(CLASS) 이런 식으로 클래스를 변환하여 연결하였습니다.
잘 되나 봅시다.
'Dev > Flex' 카테고리의 다른 글
[FLEX] 왜 Sprite는 Canvas에 addChild 안되는 걸까? (7) | 2007.12.04 |
---|---|
[FLEX] Coloring the Background of Cells (20) | 2007.11.20 |
[FLEX] XML의 값을 Boolean 값으로 캐스팅하는 방법? (1) | 2007.11.16 |
[FLEX] Datagrid 에 Mouse Over 시에 나오는 색을 바꾸고 싶다면? (0) | 2007.11.09 |
[FLEX] Flex 3.0 베타에서 구현한 데이터그리드 멀티헤더 (datagrid multi-header) (7) | 2007.06.12 |