2008. 6. 21. 09:57
Flex에서 팝업용도로 많이 쓰는 TitleWindow이라는 클래스가 있습니다.
TitleWindow 의 구현코드를 보신 분은 아시겠지만 TitleWindow 에는 그렇게 많은 코드가 있지는 않습니다. (오히려 뭐가 이렇게 없어! 할 정도) 저도 상당히 의아했습니다. 주석을 빼면 정말 몇줄 안되는 코드였기 떄문이죠.

그 이유는 TitleWindow는 Panel을 상속해서 만들었는데 실제 TitleWindow에서 필요한 닫기버튼은 이미 Panel에서 구현되어 있고 단지 보이지만 않는 상태이기 때문입니다. TitleWindow에서는 showCloseButton 라는 get/set 메소드로 닫기 버튼의 보여지는 유무만 설정하면 됩니다.

그런데 여기서 좀 재미있는 부분이 있습니다. Panel에서 닫기 버튼이 구현되어 있다면 Panel을 상속받으면 그 닫기버튼도 사용할 수 있을까요? 그냥은 안됩니다. 왜냐하면 닫기버튼이 보이거나 안보이도록 설정하는 변수인 _showCloseButton이 mx_internal 로 선언되어 있기 때문입니다.

  1. /** 
  2.  *  @private 
  3.  *  Is there a close button? Panel itself never has one, 
  4.  *  but its subclass TitleWindow can set this flag to true. 
  5.  */  
  6. mx_internal var _showCloseButton:Boolean = false;  


그럼 이걸 어떻게 사용하면 될까요? TitleWindow의 showCloseButton 라는 get/set 메소드 를 보면 해답을 찾을 수 있습니다.

  1. // mx.containers.TitleWindow 내부 구현 소스  
  2.   
  3. //----------------------------------  
  4. //  showCloseButton  
  5. //----------------------------------  
  6.   
  7. [Inspectable(category="General")]  
  8.   
  9. /** 
  10.  *  Whether to display a Close button in the TitleWindow container. 
  11.  *  The default value is <code>false</code>. 
  12.  *  Set it to <code>true</code> to display the Close button. 
  13.  *  Selecting the Close button generates a <code>close</code> event, 
  14.  *  but does not close the TitleWindow container. 
  15.  *  You must write a handler for the <code>close</code> event 
  16.  *  and close the TitleWindow from within it. 
  17.  * 
  18.  *  @default false 
  19.  * 
  20.  *  @tiptext If true, the close button is displayed 
  21.  *  @helpid 3986 
  22.  */  
  23. public function get showCloseButton():Boolean  
  24. {  
  25.     return mx_internal::_showCloseButton;  
  26. }  
  27.   
  28. /** 
  29.  *  @private 
  30.  */  
  31. public function set showCloseButton(value:Boolean):void  
  32. {  
  33.     mx_internal::_showCloseButton = value;  
  34. }  


showCloseButton 속성의 코드가 좀 특이하죠?
TitleWindow 의 코드 상단에
use namespace mx_internal;
이라고 작성되어 있습니다. mx_internal 이라는 namespace를 사용하겠다는 것이지요. 이렇게 설정되면 showColoseButton 속성과 같이 mx_internal로 선언된 _showCloseButtion 변수에 접근하시면 됩니다.
return mx_internal::_showCloseButton;      //이렇게 해도 되고 또는,
return _showCloseButton;                       //이렇게만 해도 되긴 합니다
그렇다면 TitleWindow 는 Panel을 상속받았으니 그렇다 치고, 외부에서 Panel 객체의 _showCloseButton 변수를 바로 접근할 수는 없을까요? 안된다고요? 그럼 안되는데요! 안되면 제가 이 글을 쓸 이유가 없어집니다. ;) 바로 아래와 같이 가능합니다.
  1.    
  2. <?xml version="1.0" encoding="utf-8"?>  
  3. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()">  
  4.     <mx:Script>  
  5.         <![CDATA[  
  6.             import mx.controls.Alert;  
  7.               
  8.             public function init():void  
  9.             {  
  10.                 trace(myPanel.mx_internal::_showCloseButton);  
  11.             }  
  12.               
  13.               
  14.         ]]>  
  15.     </mx:Script>  
  16.     <mx:Panel id="myPanel" x="69" y="156" width="250" height="200" layout="absolute"/>  
  17. </mx:Application>  


그래도 화면에 보이는 예제가 하나 필요하겠죠? 이번에는 TextArea로 예제를 하나 만들어보겠습니다.
(loveDev 블로그에서 아이디어 얻었습니다)
Flex에서 한글을 입력시에는 버벅이는 문제(천천히 타이핑 되는 문제)가 있었습니다. 이 문제를 해결하기 위해서 frame rate 를 올린다던가 하는 방법을 사용했었는데, Adobe Flex 공식사이트에 블로그에 올라온 글에서 어이없게도(?) TextField 의 alwaysShowSelection 속성을 true로 바꾸어주면 해결된다는 것이었습니다. 왜 그런지는 저도 정확하게는 잘 모르겠고... ^^;

아 무튼 Flex에서 한글 입력을 받는 TextInput, TextArea 등도 내부적으로 TextField를 상속한 UITextField 를 사용하고 있습니다. 그렇다면 이 UITextField 를 받아와야겠습니다만, 이게 또 골치아픕니다. TextArea나 TextInput 은 이 UITextField가 protected로 선언되어 있기때문에 외부에서 접근하는 것이 불가능합니다. 그래서 상속을 받아서 접근하던지, 아니면 여기와 같이 해결을 해야됩니다.

그러나 다행이도 이 TextField를 반환해주는 getTextField()라는 메소드가 존재합니다.
  1. // mx.controls.TextArea의 내부 구현 소스  
  2.   
  3. //----------------------------------  
  4. //  textField  
  5. //----------------------------------  
  6.   
  7. /** 
  8.  *  The internal UITextField that renders the text of this TextArea. 
  9.  */  
  10. protected var textField:IUITextField;  
  11.   
  12. mx_internal function getTextField():IUITextField  
  13. {  
  14.     return textField;  
  15. }  


그렇다면 UITextField에 직접 접근하여 텍스트를 입력하려면 getTextField() 메소드를 사용하여야 할텐데요, 위의 코드에서 보셨다시피 mx_internal 로 선언되어있습니다. 이럴때는 위에서 설명드린데로 하면 되겠죠?

이 getTextField를 이용하여 TextArea에 한글입력을 개선한 예제입니다.
아래에 있는 TextArea에만 alwaysShowSelection의 값을  true로 설정을 해주었습니다. 위 아래 TextArea에 한글을 입력해보세요. ;)

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"  
  3.     layout="absolute" width="300" height="200" creationComplete="init()"  
  4.     backgroundGradientAlphas="[1.0, 1.0]"  
  5.     backgroundGradientColors="[#FFFFFF, #D9D9D9]" xmlns:ns1="*">  
  6.     <mx:Script>   
  7.         <![CDATA[   
  8.             private function init():void   
  9.             {   
  10.                 var textField:TextField = myTextArea1.mx_internal::getTextField();  
  11.                 textField.alwaysShowSelection = true;   
  12.             }   
  13.         ]]>   
  14.     </mx:Script>  
  15.     <mx:TextArea x="32" width="236" height="63" y="34"/>  
  16.     <mx:TextArea id="myTextArea1" x="32" width="236" height="63" y="105"/>  
  17. </mx:Application>  


유용한 정보 되셨길 바랍니다. ;) (오창훈님 감사합니다. ㅎ)


--- 파폭3에서 예제에 한글 입력이 안되네요.. ㅡㅡ; 왜 이러지;; 티스토리에 swf 업로드 하면 object 태그는 생성되는데 embed 태그가 없네요. 이래서 한글 입력이 안되었군요. ㅡㅡ; wmode 속성이 window 일때는 한글 입력이 됩니다. opaque나 transparent 속성은 한글 입력이 안됨..;