2009년 5월 20일 수요일

DataGrid Paging 구현

일반 웹처럼 DataGrid에서 아래에 페이지번호를 달아서 페이징을 하면 좀 이상할 것 같아서, 우아하게 DataGrid의 스크롤이 맨 아래에 닿으면 다음 페이지를 읽어서 DataGrid의 아래에 추가해 주는 방법을 생각해냈다. 뭐, 사실 Grid를 사용하는 대부분의 프로그램들이 이렇게 한다. 하지만, Flex의 DataGrid에는 명시적으로 스크롤이 맨 아래에 닿았을 때 발생시키는 이벤트가 없어서 좀 고민을 많이 했다.

DataGrid에 scroll="scrollHandler(event)"

이렇게 scroll 이벤트를 이벤트핸들러에 연결시킨다.


아래는 이벤트핸들러 메소드

private function scrollHandler(event:ScrollEvent):void {
    if (grid.maxVerticalScrollPosition == event.position
       && event.delta > 0) {

        // do something
        Alert.show("end of Vertical scroll");
    }
}

event.delta > 0
이 부분은 스크롤을 맨 아래에 닿은 상태에서 계속 당기면 scroll 이벤트가 계속 발생하기 때문에, 끝에 닿은 상태에서 더 이상 못 움직일 때는 이벤트 처리를 하지 않도록 하기 위해서 사용했다.

이렇게 간단하게 끝날 문제는 사실 아니다. 스크롤바를 맨 아래서 올렸다 내렸다 하면 자꾸 이벤트가 발생하니까 같은 페이지를 중복해서 요청하지 않도록 하는 코드도 들어가야 할 것 같다.

2009년 5월 19일 화요일

id를 이용한 정적/동적 컴포넌트 참조

Flex에서 ActionScript를 사용하다 보면 컴포넌트를 직접 사용할 수도 있지만 id 문자열을 이용해 참조해야 할 경우가 종종 생긴다.

<mx:TextInput id="tiName" />

mxml 파일에 이런 TextInput이 선언되었다면,

tiName.text = "tiger";
이렇게 할 수도 있지만,

this["tiName"].text = "tiger";
이렇게 id 문자열을 이용해서도 참조가 가능하다.

지금까지는 정적으로 선언된 컴포넌트를 참조하는 법을 보았는데, 이외에 동적을 컴포넌트를 생성하는 경우도 가끔은 생긴다.

var textName:TextInput = new TextInput();
textName.id = "tiName";
someComp.addChild(textName);

이렇게 동적으로 생성한 컴포넌트는 this["id"] 형태로는 찾을 수가 없다. 그래서, 별도의 저장장소에 저장해 두고 사용해야 한다.

id가 원래 현재문서에서 unique한 것이므로, id를 key로 생성된 컴포넌트를 value로 해서 Dictionary에 저장해서 사용하면 적당할 것이다.

var dynamicComps:Dictionary = new Dictionary();
dynamicComps["tiName"] = textName;

위와 같이 저장하고, 참조하고 싶을 때는 dynamicComps["tiName"] 를 사용하면 된다.

Dictionary에 대한 보다 자세한 설명은 아래 링크 참조
http://flexsong.tistory.com/8

아주 유용한 이클립스 단축키

Ctrl + 마우스왼쪽클릭
변수에 마우스 포인터를 올려 놓은 상태에선 변수 선언 위치로, 클래스명 위에서 하면 클래스 소스로 이동한다.

Alt + ←

이전 편집 위치로 이동
파일간 이동이든, 파일내 이동이든 이 단축키를 누르면 이전 편집위치로 이동한다. 계속 누르면 계속 그 이전으로 이동한다. 'Ctrl + 마우스왼쪽클릭'으로 한참 이동했다가 다시 돌아올 때 유용하다.

Alt + →
'Alt + ←'과 반대로 이후 편집 위치로 이동

F4
이클립스의 프로젝트 익스플로러에서 클래스를 선택한 후에 F4를 누르면, 그 클래스의 상위 클래스구조를 트리형태로 보여준다.

Ctrl + Space
변수명이나 클래스명 등의 일부를 입력하고 이 단축키를 누르면 입력한 문자열로 시작하는 변수명과 클래스명 리스트가 나타나 선택할 수 있고, 선택대상이 하나면 리스트 없이 자동으로 입력된다. 클래스 변수 뒤에 '.'을 찍고 이 단축키를 누르면 해당 클래스에서 사용할 수 있는 변수와 메소드 리스트가 나타나 선택할 수 있다.

Ctrl + k
특정 문자열을 선택한 후에 이 단축키를 누르면 바로 다음에 나타나는 동일한 문자열로 이동한다. 울트라에디트나 아크로에디트의 'F3'과 동일한 기능이다. 단, 이 찾기 옵션은 이전에 'Ctrl + F'에서 사용한 옵션과 동일하게 적용되므로 원하는대로 못 찾는다면 이전에 '대소문자 구분'이나 '전체 단어' 등의 옵션 등이 선택했었는지 'Ctrl + F'를 눌러 확인해 보아야 한다.

Ctrl + Shift + k
Ctrl + k와 반대로 특정 문자열이 나타나는 바로 이전 위치로 이동한다. 울트라에디트나 아크로에디트의 'Shift + F3'과 동일한 기능이다.


물론, 위의 단축키들은 Flex 코드 개발시에도 동일하게 작동한다.

2009년 5월 15일 금요일

Flex에서 Java의 HashMap과 같은 기능 사용

Flex에도 Java의 HashMap과 같이 key=value 형태로 저장하고 조회할 수 있는 클래스가 있다. 그것이 바로 Dictionary.

아래와 같이 사용할 수 있다.
var dict:Dictionary = new Dictionary(); // 이렇게 생성해서
dict[key] = value; // 이렇게 값을 저장하고
dict[key]          // 이렇게 값을 꺼낸다
 
key와 value에는 아마도 Object가 들어가는 걸로 봐서 어떤 값이든 들어가는 것 같다. HashMap에서도 그랬듯이 나는 key에는 String, value에는 String 또는 Object를 넣는 데 주로 사용할 듯하다.


혹시나 이해가 안 갈까 봐, 아래는 간단한 예제 코드
var dict:Dictionary = new Dictionary();
dict["userid"] = "tiger";
Alert.show("User ID : " + dict["userid"]);

결과는 User ID : tiger


단, HashMap처럼 keySet이나 contains 같은 메소드는 전혀 없고, 오직 넣고 꺼내기만 된다.

2009년 5월 14일 목요일

Flex에서 HTML 페이지 띄우기

Flex에서 HTML(ASP, PHP, JSP 등 포함)를 띄울 일이 종종 생긴다.
이를 위해서 IFrame이라는 Flex Component가 있는데 이걸 제대로 사용하려면 wmode 같은 걸 설정하는데 이게 아무래도 Adobe 컴포넌트가 아니라서 DataGrid 스크롤이 휠로는 안 되는 등 뭔가 깔끔하게 처리되는 맛이 떨어진다. 그래서, 아예 웹브라우저를 하나 생성하는 게 가장 간편하고 확실한 방법인 듯하다.

아래 코드는 Flex에서 웹브라우저 팝업을 띄우는 예제이다.


// 작은 사이즈의 팝업으로 뜬다
if (ExternalInterface.available)
    ExternalInterface.call("window.open", url, "_blank", "width=800,height=600");
else {
    try {
        // 새로운 탭 또는 현재 웹브라우저와 같은 브라우저로 뜬다          
        navigateToURL(new URLRequest(url));
    }
    catch (e:Error) {
        Alert.show("Cannot open Popup : " + e.message);
    }
}


첫번째(if)에서 ExternalInterface.call은 현재 Flex가 동작하고 있는 웹브라우저에 자바스크립트 명령을 실행하는 방법이다. 즉, window.open(url, "_blank", "width=800,height=600"); 라는 자바스크립트 코드가 웹브라우저에서 실행된다. 이게 첫번째 옵션인 이유는 여기는 open 메소드의 세번째 인자로 다양한 옵션을 줄 수 있고, 팝업 차단이 되어 있어도 뜬다고 하기(확인 못 해 봤음) 때문이다. 나는 사이즈 옵션을 이용해 큰 브라우저가 아닌 작은 팝업을 만들고 싶었기 때문에 이것을 가장 우선으로 처리했다.
두번째(else)에서는
navigateToURL라는 메소드를 이용해 URL을 웹브라우저에 띄운다. 그런데, 여기는 별다른 옵션을 줄 수 없어 HTML 페이지가 새로운 탭에 열리거나 현재 웹브라우저와 같은 크기의 창이 열려 현재 Flex 화면을 가리기 때문에 ExternalInterface를 사용할 수 없을 경우에 어쩔 수 없이 사용하도록 처리했다.

참고:
navigateToURL을 이용해서 동적으로 생성된 컨텐츠를 다운로드 받게 할 수도 있다. navigateToURL에서 받는 URL의 페이지(ASP, PHP, JSP, Servlet 등)의 Contents Type을 text/html이 아닌 다른 값(예를 들면, Excel은 application/vnd.ms-excel)으로 하면 브라우저 창 대신 다운로드창이 떠서 다운로드할 수 있다.