System.useCodePage 대신 이렇게..는... 맥에서는 안통하네요.ㅠㅠ

Programming/Flex 2009.06.23 13:45
[Flex]Encoding problem when using URLVariables
위글에 영원의 헤아림님께서 http://blog.flashplatform.kr/195 참고 포스팅을 해주셨습니다. 
포스팅을 따라가다보니 원강민님께서 포스팅까지 가게 되었는데요.

포스팅 내용을 보다가.. 한글이 여전히 깨지는것을 발견했습니다.
왜냐면... 저는 Mac OSX 10을 사용중이고, Safari에서 블로그를 보고있기 때문이네요...
윈도에서는 한글이 잘 뜨는것을 확인했습니다.
역시 플렉스는....머리아파요..-_-;;;
저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

[Flex]Encoding problem when using URLVariables

Programming/Flex 2009.04.02 00:35
URLVariables를 통해서 파라미터를 셋팅하고, navigateToURL이나 URLLoader를 통해서 한글 데이터를 전송하고자 할 때, 한글 파라미터 값이 깨지는 경우가 발생합니다.

Server side에서 갖가지 인코딩을 다 적용해 보았으나 죄다 실패!
Flex에서 URLRequest의 contextType을 죄다 변경해 보았으나 역시 실패!

그래서 결국 생각해낸 방법이 Base64를 이용하는 것입니다.-_-;;
근본적인 해결책은 아니더라도... 나쁘진 않은 방법이긴 하죠.-ㅅ-;

<test.mxml>
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Script>
          <![CDATA[
              import flash.net.navigateToURL;
              import mx.utils.Base64Decoder;
              import mx.utils.Base64Encoder;
              private function finishSubmit(event:Event):void
            {
               
                var request:URLRequest = new URLRequest("/test.jsp");
                var param:URLVariables = new URLVariables();
                var be:Base64Encoder = new Base64Encoder();
                var bd:Base64Decoder = new Base64Decoder();
                be.encodeUTFBytes(t.text);
                en.text = be.toString();
                bd.decode(en.text);
                de.text = bd.flush().toString();
               
                request.method = URLRequestMethod.POST;
                request.data = param;
                param.txt = en.text;
                param.undecodetxt = t.text;
                var ul:URLLoader = new URLLoader();
                ul.dataFormat = URLLoaderDataFormat.VARIABLES;
                ul.load(request); // test.jsp로 리퀘스트가 전송됩니다.
               
               
            }
          ]]>
      </mx:Script>

    <mx:Panel title="LineChart and AreaChart Controls Example"
        height="100%" width="100%" layout="absolute">
        <mx:Button x="61" y="105" label="Button" click="finishSubmit(event)"/>
        <mx:Label x="61" y="37" id="t" text="한글 텍스트...."/>
        <mx:TextArea x="50" y="201" width="267" height="196" id="en"/>
        <mx:TextArea x="352" y="189" width="382" height="197" id="de"/>
    </mx:Panel>

</mx:Application>


참으로 귀찮았나 봅니다.-_-;; 암튼 위 코드를 실행하면 아래와 같은 화면이 실행됩니다.
버튼을 누르면 한글 스트링을 encoding, decoding합니다.
그리고 test.jsp로 전송도 하구요.

<test.jsp>
<%@ page language="java" contentType="text/html; charset=euc-kr"
    pageEncoding="UTF-8"   %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
String txt = request.getParameter("txt");
String undecodetxt = request.getParameter("undecodetxt");
System.out.println(undecodetxt);
System.out.println(txt);
System.out.println(Base64Coder.decodeString(txt));

%>
</body>
</html>

<Base64Coder.java : 출처 (http://www.source-code.biz/snippets/java/2.htm)>
/**
* A Base64 Encoder/Decoder.
*
* <p>
* This class is used to encode and decode data in Base64 format as described in RFC 1521.
*
* <p>
* This is "Open Source" software and released under the <a href="http://www.gnu.org/licenses/lgpl.html">GNU/LGPL</a> license.<br>
* It is provided "as is" without warranty of any kind.<br>
* Copyright 2003: Christian d'Heureuse, Inventec Informatik AG, Switzerland.<br>
* Home page: <a href="http://www.source-code.biz">www.source-code.biz</a><br>
*
* <p>
* Version history:<br>
* 2003-07-22 Christian d'Heureuse (chdh): Module created.<br>
* 2005-08-11 chdh: Lincense changed from GPL to LGPL.<br>
* 2006-11-21 chdh:<br>
* &nbsp; Method encode(String) renamed to encodeString(String).<br>
* &nbsp; Method decode(String) renamed to decodeString(String).<br>
* &nbsp; New method encode(byte[],int) added.<br>
* &nbsp; New method decode(String) added.<br>
*/

public class Base64Coder {

// Mapping table from 6-bit nibbles to Base64 characters.
private static char[] map1 = new char[64];
static {
int i=0;
for (char c='A'; c<='Z'; c++) map1[i++] = c;
for (char c='a'; c<='z'; c++) map1[i++] = c;
for (char c='0'; c<='9'; c++) map1[i++] = c;
map1[i++] = '+'; map1[i++] = '/'; }

// Mapping table from Base64 characters to 6-bit nibbles.
private static byte[] map2 = new byte[128];
static {
for (int i=0; i<map2.length; i++) map2[i] = -1;
for (int i=0; i<64; i++) map2[map1[i]] = (byte)i; }

/**
* Encodes a string into Base64 format.
* No blanks or line breaks are inserted.
* @param s a String to be encoded.
* @return A String with the Base64 encoded data.
*/
public static String encodeString (String s) {
return new String(encode(s.getBytes())); }

/**
* Encodes a byte array into Base64 format.
* No blanks or line breaks are inserted.
* @param in an array containing the data bytes to be encoded.
* @return A character array with the Base64 encoded data.
*/
public static char[] encode (byte[] in) {
return encode(in,in.length); }

/**
* Encodes a byte array into Base64 format.
* No blanks or line breaks are inserted.
* @param in an array containing the data bytes to be encoded.
* @param iLen number of bytes to process in <code>in</code>.
* @return A character array with the Base64 encoded data.
*/
public static char[] encode (byte[] in, int iLen) {
int oDataLen = (iLen*4+2)/3; // output length without padding
int oLen = ((iLen+2)/3)*4; // output length including padding
char[] out = new char[oLen];
int ip = 0;
int op = 0;
while (ip < iLen) {
int i0 = in[ip++] & 0xff;
int i1 = ip < iLen ? in[ip++] & 0xff : 0;
int i2 = ip < iLen ? in[ip++] & 0xff : 0;
int o0 = i0 >>> 2;
int o1 = ((i0 & 3) << 4) | (i1 >>> 4);
int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6);
int o3 = i2 & 0x3F;
out[op++] = map1[o0];
out[op++] = map1[o1];
out[op] = op < oDataLen ? map1[o2] : '='; op++;
out[op] = op < oDataLen ? map1[o3] : '='; op++; }
return out; }

/**
* Decodes a string from Base64 format.
* @param s a Base64 String to be decoded.
* @return A String containing the decoded data.
* @throws IllegalArgumentException if the input is not valid Base64 encoded data.
*/
public static String decodeString (String s) {
return new String(decode(s)); }

/**
* Decodes a byte array from Base64 format.
* @param s a Base64 String to be decoded.
* @return An array containing the decoded data bytes.
* @throws IllegalArgumentException if the input is not valid Base64 encoded data.
*/
public static byte[] decode (String s) {
return decode(s.toCharArray()); }

/**
* Decodes a byte array from Base64 format.
* No blanks or line breaks are allowed within the Base64 encoded data.
* @param in a character array containing the Base64 encoded data.
* @return An array containing the decoded data bytes.
* @throws IllegalArgumentException if the input is not valid Base64 encoded data.
*/
public static byte[] decode (char[] in) {
int iLen = in.length;
if (iLen%4 != 0) throw new IllegalArgumentException ("Length of Base64 encoded input string is not a multiple of 4.");
while (iLen > 0 && in[iLen-1] == '=') iLen--;
int oLen = (iLen*3) / 4;
byte[] out = new byte[oLen];
int ip = 0;
int op = 0;
while (ip < iLen) {
int i0 = in[ip++];
int i1 = in[ip++];
int i2 = ip < iLen ? in[ip++] : 'A';
int i3 = ip < iLen ? in[ip++] : 'A';
if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127)
throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
int b0 = map2[i0];
int b1 = map2[i1];
int b2 = map2[i2];
int b3 = map2[i3];
if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0)
throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
int o0 = ( b0 <<2) | (b1>>>4);
int o1 = ((b1 & 0xf)<<4) | (b2>>>2);
int o2 = ((b2 & 3)<<6) | b3;
out[op++] = (byte)o0;
if (op<oLen) out[op++] = (byte)o1;
if (op<oLen) out[op++] = (byte)o2; }
return out; }

// Dummy constructor.
private Base64Coder() {}

} // end class Base64Coder

<결과 System.out>
한글 텍스트....
7ZWc6riAIO2FjeyKpO2KuC4uLi4=
한글 텍스트....

<Http Request Header에 찍히는 Parameter 정보>
txt=7ZWc6riAIO2FjeyKpO2KuC4uLi4%3D&undecodetxt=%ED%95%9C%EA%B8%80%20%ED%85%8D%EC%8A%A4%ED%8A%B8%2E%2E%2E%2E

네~ 됩니다.

플렉스는 아직 한글을 싫어라 합니다. 젠장.-ㅅ-;;

혹시나 서버사이드에서 인코딩 쉽사리 전송된 사례가 있다면 공유 부탁드립니다.(__)*


저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

[Flex]Textarea,TextField에서 Undo, Redo

Programming/Flex 2009.03.02 17:53
이런 뎅장. Flex의 TextArea에서는 undo, redo가 안된다!!-_-;;
아놔~ 그래서 열심히 찾아본 결과... 그 라이브러리를 누군가가 만들어 뒀다.
http://code.google.com/p/undo-textfields/ 
http://jacwright.com/blog/112/undo-redo-for-all-textfields/

ㅈㅏ~ 한번 써보자구~

사용법은 너무나도 간단하다.

소스보기



라이브러리 폴더에 요 swc를 넣고,
네임스페이스로 xmlns:text="gearsandcogs.text.*"를 지정하고~
<text:UndoTextFields target="{panel1}" />
요렇게 쓰면 끝!
그럼.. undo, redo가....파이어폭스나 맥에선 잘된다..-_-;(응???)
우리에게 필요한건 빌어먹을 IE에서 동작해야 한다는거.ㅠ.ㅠ;;;;;

젠장.. IE에서는 동작하지 않는다........ (다시 찾자..)
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

[scrap]DataGridColumn을 확장한 DataGrid 개발(formatter 적용)

Programming/Flex 2009.02.24 11:36
본 자료는 최용범님께서 2008년 8월에 아래 사이트게 작성한 내용을 스크랩한 것입니다.
http://www.adobeflex.co.kr/iwt/board/board.php?tn=pds_tech&bc=4&id=183&mode=view 에서 스크랩 한 자료입니다.

DataGridColumn을 확장한 DataGrid 개발

 

“Flex

또한 “Flex 애플리케이션 개발에서 클라이언트의 요구가 가장 많이 반영되어야 하는 컴포넌트가 DataGrid 컴포넌트이다. 그러므로 개발자들이 가장 손이 많이 가는 부분이고, 능숙하게 사용할 줄 알아야 하는 것이 DataGrid 컴포넌트라고 생각된다.

그러나 현실적으로 기본적인 DataGrid를 그냥 사용한다면 쓸데 없이 소스코드가 길어지고 가독성이 떨어지게 되어 생산성이 떨어지며 차후 유지보수도 복잡해지게 된다. 고로 본 글에서는 “Flex 애플리케이션 개발에 있어서 DataGridColumn을 확장해 생산성을 높이고 유지보수를 편하게 하는 방법을 제시해볼까 한다.

이 글을 읽는 대상층은  DataGrid를 사용한 경험이 있다는 전제 하에 기본적인 사용법은 생략하고 활용 방법에 대해서만 기술하도록 한다.

 

1.       일반적인 DataGrid 사용하기

A 기업에서, 내부 인사지원 프로그램에 대한 구축 의뢰가 들어왔다. 고객의 요구사항 중에 연봉 컬럼은 3자리마다 ‘,’ 를 찍고 오른쪽 정렬을 해야한다고 명시되어있다. 우리는 일반적으로 아래와 같은 코드를 사용할 것이다. NumberFormatter를 설정하고 labelFunction을 사용해서 값을 변환하고 DataGridColumn textAlign을 이용하여 정렬방법을 세팅할 것이다.

 

<예제코드 1> labelFunction을 사용한 그리드

<mx:Script>

                  <![CDATA[

                                  

                                   private function moneyFormat(item:Object,column:DataGridColumn):String{

                                                     return nf.format(item[column.dataField]);

                                   }                                                                    

                  ]]>

</mx:Script>

 

<mx:NumberFormatter id="nf" useThousandsSeparator="true"/>

 

<mx:DataGrid id="dg" dataProvider="{arr}" width="100%">

                  <mx:columns>

                                   <mx:DataGridColumn headerText="이름" dataField="name"/>

                                   <mx:DataGridColumn headerText="주민번호" dataField="ssn" />

                                   <mx:DataGridColumn headerText="연봉" dataField="salary" labelFunction="moneyFormat" textAlign="right">

                                                     <mx:headerRenderer>

                                                                       <mx:Component>

                                                                                        <mx:Label textAlign="center"/>

                                                                       </mx:Component>

                                                     </mx:headerRenderer>

                                   </mx:DataGridColumn>

                                   <mx:DataGridColumn headerText="입사일" dataField="yyyymmdd"/>

                  </mx:columns>

</mx:DataGrid>

 

일단 연봉 부분만 설정했는데도 소스 부분이 좀 지저분한 느낌이 든다. 여기에 이름, 주민등록번호, 입사일자까지 일일이 포맷을 만들고 labelFunction을 넣어준다면 소스는 더욱 지저분하고 길어질 것이다.

그러므로 LabelFunction 대신 DataGridColumn을 확장하여 format 메쏘드를 통해 미리 설정해 놓은 포맷, 정렬방식으로 표현이 된다면 사용하기가 훨씬 편해질 것이다.

 

2.       DataGridColumn을 확장하기 위한 준비

 

그럼 이제 DataGridColumn을 확장해보자. 먼저 포맷을 만들어준다. 실제 프로젝트에 쓰이는 포맷의 종류는 상당히 많겠지만 가장 일반적으로 쓰이는 금액, 날짜, 주민번호를 만들어보자.

 

<예제코드 2> LabelFormat.as

package comp

{

                  import mx.formatters.NumberFormatter;

                 

                  public class LabelFormat

                  {

                                   public function LabelFormat()

                                   {

 

                                   }

 

                                   // moneyFormat    세자리마다 ',' 찍어준다.

                                   public static function moneyFormat(temp:String,percision:Number):String

                                   {

                                                     var formatter:NumberFormatter = new NumberFormatter();

                                                     formatter.useThousandsSeparator=true;

                                                     formatter.precision = percision;

                                                    

                                                     var result:String = formatter.format(temp);

                                                    

                                                     if(result.charAt(0) == "."){

                                                                       return "0"+result;

                                                     }else if(result.substring(0,2) == "-."){

                                                                       return "-0."+result.substring(2,result.length);

                                                     }else{

                                                                       return result;

                                                     }

                                   }                                                  

 

                                   // dayFormat ,, 구분을 '-' 한다.

                                   public static function dayFormat(temp:String):String

                                   {

                                                     if(temp == "null") return "";

                                                     temp = temp.split("-").join("");

                                                     return temp.substring(0,4)+"-"+

                                                                          temp.substring(4,6)+"-"+

                                                                          temp.substring(6,8)+temp.substring(8,temp.length);

                                   }

                                  

                                   //ssnFormat  주민번호 , 자리를 '-'  구분해준다.

                                   public static function ssnFormat(temp:String):String

                                   {

                                                     temp = temp.split("-").join("");

                                                     if(temp.length == 13){

                                                                       return temp.substring(0,6)+"-"+

                                                                                           temp.substring(6,13);

                                                     }else{

                                                                       return temp;

                                                     }

                                   }

                  }

}

 

이제 LabelFunction을 만든다. LabelFunction이 하는 일은 간단하다. GridColumn의 값을 받아 유효성을 체크하고 LabelFormat에서 지정한 포맷으로 값을 리턴한다.

 

<예제코드 3> LabelFunction.as

package comp

{

                  import mx.controls.dataGridClasses.DataGridColumn;

                  import mx.formatters.DateFormatter;

                 

                  public class LabelFunction

                  {

                                   public function LabelFunction()

                                   {

 

                                   }

                                  

                                   // 금액 labelFormat

                                   public static function moneyFormat(item:Object, column:DataGridColumn):String

                                   {

                                                     if(item[column.dataField] == null) return "";

                                                    

                                                     var temp:String = String(item[column.dataField]);

                                                     return LabelFormat.moneyFormat(temp,0);

                                   }               

 

                                   // 날짜 labelFormat

                                   public static function dayFormat(item:Object, column:DataGridColumn):String

                                   {

                                                    

                                                     if(item[column.dataField] == null && item[column.dataField] == "null") return "";

                                                    

                                                     var temp:String = String(item[column.dataField]);

                                                    

                                                     // 넘어온 값이 Date 형식이면 dateFormat 이용하여 변환하고

                                                     // String 형이면 위에서 작업한 dayFormat 이용한다.

                                                     if(item[column.dataField] is Date){

                                                                      

                                                                       var dateFormat:DateFormatter = new DateFormatter();

                                                                      

                                                                       dateFormat.formatString="YYYY-MM-DD";

                                                                      

                                                                       return dateFormat.format(item[column.dataField]);

                                                                      

                                                     }else{

                                                                       return LabelFormat.dayFormat(temp);

                                                     }

                                                    

                                   }

 

                                  

                                   // 주민 번호 labelFormat

                                   public static function ssnFormat(item:Object, column:DataGridColumn):String

                                   {

                                                    

                                                     if(item[column.dataField] == null) return "";

                                                    

                                                     var temp:String = String(item[column.dataField]);

                                                    

                                                     if(temp.length == 13){

                                                                       return LabelFormat.ssnFormat(temp);

                                                     }else{

                                                                       return temp;

                                                     }

                                   }

 

                                  

                  }

 

 

DataGridColumn에 스타일을 주면 headerText에도 스타일이 적용된다. 그런 것을 방지하기 위하여 HeaderRenderer 작성한다. 보통의 경우 헤더는 센터 정렬이 일반적이므로 옵션 없이 그냥 센터 정렬이 되게 작업하였다.

 

<예제코드 4> HeaderRenderer.as

package comp

{

                  import mx.controls.Label;

 

                  public class HeaderRenderer extends Label

                  {

                                   public function HeaderRenderer()

                                   {

                                                     super();

                                                     this.setStyle("textAlign","center");

                                   }

                                  

                  }

}

 

 

3.       DataGridColumn 확장하기

이제 DataGridColumn 확장하기 위한 준비는 끝났으니 SampleGridColumn을 만들어보자.

DataGridColumn을 상속받아 ConstructorHeaderRenderer 넣어 헤더를 중앙 정렬하게 하고 format 입력 받아 그에 맞는 포맷으로 변경하고 정렬방법을 설정한다. 아래 소스에서는 금액은 오른쪽 정렬, 나머지는 중앙정렬로 설정하였다.

 

<예제코드 5> SampleGridColumn.as

package comp

{

                  import mx.controls.dataGridClasses.DataGridColumn;

                  import mx.core.ClassFactory;

 

                  public class SampleGridColumn extends DataGridColumn

                  {

                                   private var _type:String = "";

                                  

                                  

                                   public function SampleGridColumn(columnName:String=null)

                                   {

                                                     super(columnName);

                                                     this.setStyle("textAlign","center");

                                                    

                                                    

                                                     this.headerRenderer =  new ClassFactory(comp.HeaderRenderer);

                                                    

                                                    

                                   }

 

                                   [Inspectable(defaultValue="money",enumeration="money,ssn,date" )]

                                   public function set format(type:String):void{

                                                    

                                                     _type = type;

                                                    

                                                     switch(type){

                                                                      

                                                                       // 금액일경우 오른쪽 정렬

                                                                       case "money":

                                                                                        this.labelFunction = LabelFunction.moneyFormat;

                                                                                        this.setStyle("textAlign","right");

                                                                                        break;                                      

                                                    

                                                                       // 주민번호일경우 중앙 정렬

                                                                       case "ssn":

                                                                                        this.labelFunction = LabelFunction.ssnFormat;

                                                                                        this.setStyle("textAlign","center");

                                                                                        break;                    

                                                                                       

                                                                       // 날짜일경우 중앙 정렬

                                                                       case "date":

                                                                                        this.labelFunction = LabelFunction.dayFormat;

                                                                                        this.setStyle("textAlign","center");

                                                                                        break;                    

                                                                      

                                                                       // 중앙정렬                                                                                        

                                                                       default:

                                                                                        this.setStyle("textAlign","center");

                                                                      

                                                     }

                                   }

                  }

}

 

위의 소스에서 [Inspectable(defaultValue="money",enumeration="money,ssn,date" )] 부분은 format 메쏘드를 호출할 때 코드 힌트를 설정해주는 부분이다.

 

<그림 1> Inspectable 사용 효과 

 

4.       적용 사례 보기

위의 과정을 통해 컴포넌트를 모두 만들었으니 사용해 보도록 하자.

DataGrid 2개 만들어 위에는 DataGridColumn을 사용하고 아래에는 작업한 SampleGridColumn 을 사용한다. 대신 SampleGridColumn에는 format 메쏘드를 추가하였으므로 포맷에 맞게 값을 세팅한다.

.

<예제코드 6> sample.mxml

<?xml version="1.0" encoding="utf-8"?>

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" fontSize="12" xmlns:comp="comp.*">

 

                  <mx:Script>

                                   <![CDATA[

                                                     import mx.controls.dataGridClasses.DataGridColumn;

                                                     import mx.rpc.events.HeaderEvent;

                                                     [Bindable]

                                                     private var arr:Array = [

                                                                       {name:"홍길동",ssn:"7011111222222",salary:2000,yyyymmdd:"20051214"},                                        {name:"홍길순",ssn:"7111112222322",salary:3000,yyyymmdd:"20040506"},                                        {name:"임꺽정",ssn:"5411111223522",salary:1000,yyyymmdd:"20080102"},                                        {name:"임꺽순",ssn:"2311112224266",salary:6000,yyyymmdd:"19990405"},                                        {name:"일지매",ssn:"3511111222236",salary:8000,yyyymmdd:"20010621"},                                        {name:"김철수",ssn:"7511112228422",salary:9000,yyyymmdd:"19901123"}

                                                     ];

                                                                                       

                                   ]]>

                  </mx:Script>

                 

                  <mx:VBox width="100%">

                                   <mx:DataGrid id="dg" dataProvider="{arr}" width="100%">

                                                     <mx:columns>

                                                                       <mx:DataGridColumn headerText="이름" dataField="name"/>

                                                                       <mx:DataGridColumn headerText="주민번호" dataField="ssn" />

                                                                       <mx:DataGridColumn headerText="연봉" dataField="salary" />

                                                                       <mx:DataGridColumn headerText="입사일" dataField="yyyymmdd"/>

                                                     </mx:columns>

                                   </mx:DataGrid>

 

                                   <mx:DataGrid id="dg2" dataProvider="{arr}" width="100%">

                                                     <mx:columns>

                                                                       <comp:SampleGridColumn headerText="이름" dataField="name" />

                                                                       <comp:SampleGridColumn headerText="주민번호" dataField="ssn" format="ssn"/>

                                                                       <comp:SampleGridColumn headerText="연봉" dataField="salary" format="money"/>

                                                                       <comp:SampleGridColumn headerText="입사일" dataField="yyyymmdd" format="date"/>

                                                     </mx:columns>

                                   </mx:DataGrid>

                                  

                  </mx:VBox>

</mx:Application>

 

 

<그림 2> sample.mxml을 실행한 모습

 

 

위의 DataGrid가 기본 DataGridColumn을 사용한 것이고 아래가 format을 적용시킨 확장된 DataGridColumn이다.

위와 같이 ‘A’ 기업의 인사지원 프로그램 개발 예제를 통해, Flex 애플리케이션 개발에 있어서 DataGridColumn 확장을 통한 DataGrid 개발에 대해서 알아보았다.

이번 예제에서는 기본적인 정보 이름, 주민등록번호, 연봉, 입사일 만 사용했지만, 실제로 프로젝트에서 사용하는 포맷은 요구사항에 따라 훨씬 많아질 것이다. 만약 가계부 프로그램을 개발한다면, 마이너스 잔액은 붉은 텍스트로, 플러스 잔액은 파란 텍스트로 출력되길 원할 것이다. 이러한 것들을 컴포넌트화 하여 간단한 메쏘드의 호출로 제어된다면 작업시간의 단축과 가독성의 증가 효과를 볼 수 있을 것이다.

유지보수 또한 간단해진다. 요구사항 중 이름 필드를 중앙정렬에서 왼쪽정렬로 바꿔달라는 요구가 나온다면 labelFunction.as file의 간단한 수정만으로 모든 프로젝트에 적용된다. 개인적인 생각으로는 컴포넌트의 확장은 프로그램의 개발 생산성에도 많은 도움이 되지만 유지보수시에 더욱 편리하게 사용될 것이다.

마지막으로 본 예제에서의 방법을 숙지하고, 각자가 좀 더 발전시켜 활용해 나간다면, 개발 시간의 단축을 통해 효율을 높이고 완성도를 높임은 물론 유지보수의 편리함도 찾을 수 있을 것이다.

애플리케이션을 개발할 때 가장 많이 사용되는 컴포넌트가 무엇인가?”라고 개발자에게 묻는다면 가장 먼저 나오는 대답은 ‘DataGrid’ 컴포넌트일 것이다. Flex 애플리케이션은 엔터프라이즈 업무용으로 개발이 많이 되기 때문에 특히 데이터 조회를 출력하는 DataGrid 컴포넌트와 Chart 컴포넌트가 가장 많이 사용되고 있다. 간단한 사례로, 일상 업무에서 가장 많이 사용되는 애플리케이션이 엑셀인 것을 생각해 보면 당연한 대답일 것이라고 생각을 할 수 있다.

신고
크리에이티브 커먼즈 라이선스
Creative Commons License

[FLEX]Error: Cannot determine comparator for SortField with name

Programming/Flex 2009.01.28 23:01
DataGrid를 좀 고급스럽게 사용하려고 구조적인 데이터를 사용하는 중입니다.
헌데 컬럼을 눌러 정렬을 시킬때 문제가 발생했습니다.
아래와 같은 에러가 발생했죱.
Error: Cannot determine comparator for SortField with name 'backupDeveloperMember'.
    at mx.collections::SortField/nullCompare()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\collections\SortField.as:566]
    at mx.collections::SortField/http://www.adobe.com/2006/flex/mx/internal::internalCompare()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\collections\SortField.as:234]
    at mx.collections::Sort/internalCompare()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\collections\Sort.as:831]
    at mx.collections::Sort/findItem()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\collections\Sort.as:527]
    at mx.collections::ListCollectionView/getItemIndex()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\collections\ListCollectionView.as:513]
    at ListCollectionViewCursor/collectionEventHandler()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\collections\ListCollectionView.as:2154]
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at mx.collections::ListCollectionView/dispatchEvent()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\collections\ListCollectionView.as:833]
    at mx.collections::ListCollectionView/internalRefresh()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\collections\ListCollectionView.as:1275]
    at mx.collections::ListCollectionView/refresh()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\collections\ListCollectionView.as:402]
    at mx.controls::DataGrid/sortByColumn()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\controls\DataGrid.as:3560]
    at mx.controls::DataGrid/headerReleaseHandler()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\controls\DataGrid.as:4909]
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at mx.core::UIComponent/dispatchEvent()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:9298]
    at mx.controls.dataGridClasses::DataGridHeader/mouseUpHandler()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\controls\dataGridClasses\DataGridHeader.as:1259]


위 에러는 소팅하는 소팅하는 대상을 지원하지 못한다는 말입니다.
한마디로 Compare가 되지 못한단 소리.
저 에러가 난 DataGrid의 DataProvider의 구조는

위와같이 계층 구조로 되어있습니다.
bean 안에 또다른 bean이 들어있습죠.
그러니 String, int 등의 데이터는 자체적으로 Compare가 가능하지만 Object는 Compare가 되지 않습니다.

그러므로 Compare를 재정의 해 줄 필요가 있겠죠?

Flex API를 보시면 DataGrid Class에는 SortCompareFunction이라는 것이 있습니다.

오호라~ 요녀석을 사용하면 뭔가 될 듯 하군요.

참. Flex에서 쓰이는 ObjectUtil Class에는 stringCompare 메소드가 있습니다.

ObjectUtil.stringCompare 자세히 &gt;&gt;


비교 대상이 단순 String 이라면 요녀석을 사용하면 간단해 지겠군요.

참. Flex의 String Class에 localeCompare()라는 메소드가 있어요. 이것도 비슷한 역할을 하긴하는데...
첨엔 저 메소드를 썼었는데 알수 없는 이유로 반응이 엄~~~~청나게 느려집니다.-_-;;
그래서 이유를 알아보려고 트래킹을 하다하다가 중도 포기했어요.-_-;;
혹시 이유를 아시는분은 알려주시면 정말 감사드리겠습니다.

private function backupDeveloperMemberSortCompareFunction(obj1:Object, obj2:Object) :int {
var fa:String = obj1.backupDeveloperMember.name;
var fb:String = obj2.backupDeveloperMember.name;
return ObjectUtil.stringCompare(fa, fb, false);
}
private function backupDeveloperMemberLabel(item:Object, column:Object):String {
                 var retVal:String = item.backupDeveloperMember!=null?item.backupDeveloperMember.name:"";
                return retVal;
}

<mx:DataGridColumn headerText="담당개발자" dataField="developerMember"  width="80" labelFunction="backupDeveloperMemberLabel"  sortCompareFunction="backupDeveloperMemberSortCompareFunction"/>

자~ 이제 다됬네요.

정렬을 시켜 볼까요~?

잘 동작하나요.^^?
저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

[flex]Destination 못찾는 에러

Programming/Flex 2008.11.28 18:35

에러 내용.

  1. Please Contact with message. :)
    faultCode:InvokeFailed faultString:'[MessagingError message='Destination 'memberDao' either does not exist or the destination has no channels defined (and the application does not define any default channels.)']' faultDetail:'Couldn't establish a connection to 'memberDao''

 

그림_1.png

 

위와 같은 에러가 났다.

 

원인

컴파일러가 services-config.xml을 못찾아서 나는에러다.

 

해결책

Navigator로 프로젝트를 보면 루트에 .actionScriptProperties라는 파일이 보인다.

이녀석을 오픈해서 열어보면 대충 아래와 같은 내용돌이 있는데

<?xml version="1.0" encoding="UTF-8"?>
<actionScriptProperties mainApplicationPath="emt.mxml" version="3">
<compiler additionalCompilerArguments="-locale en_US" copyDependentFiles="true" enableModuleDebug="true" generateAccessible="true" htmlExpressInstall="true" htmlGenerate="true" htmlHistoryManagement="true" htmlPlayerVersion="9.0.124" htmlPlayerVersionCheck="true" outputFolderPath="bin-debug" rootURL="http://localhost:8080/" sourceFolderPath="flex_src" strict="true" useApolloConfig="false" verifyDigests="true" warn="true">
...
 ...
</applications>
<modules/>
<buildCSSFiles/>
</actionScriptProperties>
 

빨간 줄 친 저부분을 수정해 줘야 한다.

<compiler additionalCompilerArguments="-services &quot;/프로젝트 절대경로/htdocs/WEB-INF/flex/services-config.xml&quot; -locale en_US" copyDependentFiles="true" enableModuleDebug="true" generateAccessible="true" htmlExpressInstall="true" htmlGenerate="true" htmlHistoryManagement="true" htmlPlayerVersion="9.0.124" htmlPlayerVersionCheck="true" outputFolderPath="bin-debug" rootURL="http://localhost:8080/" sourceFolderPath="flex_src" strict="true" useApolloConfig="false" verifyDigests="true" warn="true">


한마디로 services-config.xml의 절대경로를 넣어 줘야 한다.

 

젠장 이걸로 하루 날려 먹었다는.;;

 

 

이 글은 스프링노트에서 작성되었습니다.

신고
크리에이티브 커먼즈 라이선스
Creative Commons License


티스토리 툴바