관리 메뉴

I LOVE EJ

Flex Imformation 본문

Web Development/FLEX

Flex Imformation

BeOne 2007. 8. 10. 14:39
플래시는 웹 브라우저에서 멀티미디어를 자유자재로 표현하고 사용자에게 친숙하면서도 편리한 인터페이스를 제공한다. 플렉스는 플래시 기술을 웹에 그대로 적용해 그래피컬하면서도 유연한 UI의 특성을 가지고 있으며, 프로그래머들이 쉽게 배울 수 있는 획기적인 개발 언어이다. 특히 프로그래밍 언어 측면에서 여러 모로 자바와 유사한데 이를 중심으로 플렉스에 한발 다가가 보자.

이 글은 플렉스를 처음 접하거나 자바 기반의 웹 개발자 모두를 위해 플렉스의 원리를 자바 기술과 비교하면서 설명하고자 한다. 특히 단락의 제목을 플렉스의 특성에 대해 함축적으로 기술해 그것만 봐도 어느 정도 감을 잡을 수 있도록 구성했다.

XML로 기술되는 플래시 웹 컴포넌트 개발 및 실행 환경 ‘플렉스’
플렉스는 웹에서 플래시 형태로 보여진다. 여러분이 직접 데모 사이트(www.macromedia.com/devnet/flex/example_apps.html)를 방문해 구동되는 모습을 보자. 화면의 하단을 보면 쇼핑몰 데모(Flex Store), 블로그 데모(Flex Blog Reader), 실행 데모(Flex File Explorer)가 있다. 플렉스의 데모를 실행하면 웹 브라우저에서 작동하는 플래시와 똑같이 작동한다.

<화면 1> 플렉스 애플리케이션 샘플(CSS를 적용한 Flex Store)

<화면 1>은 Flex Store의 실행 화면으로 상품의 드래그앤드롭이 가능하며 하나의 화면에서 작동한다. 보통 JSP로 화면을 만들 경우에는 iframe을 써서 여러 개의 JSP 간에 파라미터를 주고받는 복잡한 코딩이 되기 때문에 이러한 드래그앤드롭은 꿈도 못 꾸는 것과 비교된다. 또한 플렉스에는 CSS(Cascading Style Sheets)를 적용함으로써 다양한 타입의 화면을 보여줄 수 있다.

웹 애플리케이션의 한계를 뛰어넘은 플렉스
일반적으로 고객이 원하는 어떤 화면을 만들기 위해 디자인은 물론 HTML 코드, 스타일시트, 자바스크립트, JSP 코드 등 엄청난 작업을 해야 하는 경우가 많다. 예를 들어 트리 메뉴를 자바스크립트에서 구현하면 코딩이 무척 복잡하다. 하지만 플렉스로 구현한 경우는 그렇지 않음을 볼 수 있다. <리스트 1>처럼 XML 구조의 트리 데이터만 정의하면 <화면 2>의 트리 메뉴를 구현할 수 있다.

<리스트 1> 플렉스로 구현한 트리 메뉴 소스코드
<?xml version="1.0" encoding="euc-kr"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml">
   <mx:Script>
      function showData(data) {
         mx.controls.Alert.show(data, 'Message');
      }      
   </mx:Script>
      <mx:HBox horizontalGap="10"> <!mx:Tree의 정의 시작
      <mx:Tree height="200" width="300"
         change="showData(event.target.selectedItem.attributes.label)">
      <mx:dataProvider>
         <mx:XML>
            <node label="플렉스의 구성"> <!트리 구조 데이터 시작
               <node label="1. 플렉스 애플리케이션 프레임워크">
                  <node label="1.1.MXML"/>
                  <node label="1.2.Action Script"/>
                  <node label="1.3.Flex Class Library"/>
               </node>
               <node label="2. Flex Runtime Service">
                  <node label="2.1.Compiler"/>
               </node>
            </node>  <!트리 구조 데이터 끝
         </mx:XML>
      </mx:dataProvider>
   </mx:Tree>  <!mx:Tree의 정의 끝
   </mx:HBox>
</mx:Application>

<화면 2> 플렉스로 구현한 트리 메뉴

풍부한 UI와 플래시의 장점 제공
플렉스의 장점 중 하나는 HTML 코드와 스타일시트, 자바스크립트 코드 등으로 표현되는 UI의 한계를 뛰어넘어 다양한 UI를 컴포넌트로 제공한다는 점이다. 특히 개발 과정에서 나온 컴포넌트들은 화면용 컴포넌트와 비즈니스용 컴포넌트로 분리할 수 있어 매우 효율적이다.

<화면 1>처럼 쇼핑몰을 구현함에 있어 기존의 세션과 파라미터 전송 방식으로 페이지를 이동할 필요 없이 하나의 플렉스 화면에서 거의 모든 처리가 가능하다. 또한 플렉스는 소스코드와 컨텐츠의 노출을 막을 수 있다는 장점이 있다. 즉 보기 메뉴에서 소스보기를 시도하더라도 <html> 속에 <object> 태그로 플렉스가 플래시로 컴파일된 위치밖에 볼 수 없다.

XML을 비롯한 표준화된 기술 사용
<리스트 1>은 플렉스로 구현한 트리 메뉴 소스코드로, 트리를 펼쳐서 해당 부분을 클릭할 때 showData 함수를 호출해 레이블 값을 alert 창으로 보여주고 있다. 그 결과는는 <화면 2>와 같다. <리스트 1>은 자바스크립트와 XML 문법을 아는 개발자라면 쉽게 와 닿으리라 생각한다. 그 이유는 플렉스에서 기본적인 코드는 XML 문법을 따르는 MXML 파일 형식으로 저장되고, 마우스 클릭 등의 이벤트 처리는 자바스크립트의 문법과 유사한 액션스크립트 2.0의 기술을 쓰기 때문이다. 그래서 필자도 플렉스의 코드를 이해하고 구현하는 데 그리 오래 걸리지 않았을 뿐 아니라 어떤 코드나 함수가 있을 것인지 예측할 수 있을 정도였다. 그렇다면 플렉스가 지원하는 표준화된 기술은 어떤 것이 있는지 살펴보자.

◆ J2EE : 플렉스는 자바 애플리케이션 서버에서 작동되며, 나중에는 닷넷 플랫폼에서도 작동되도록 지원할 것이다.
◆ XML : XML 문법을 따르는 MXML 파일 형식으로 코드를 저장하고, 'mx'라는 XML 네임스페이스를 사용한다.
◆ DOM 레벨 3 이벤트 모델 : 플렉스의 이벤트 모델이 쓰는 것으로 DOM 트리 구조를 통해 이벤트를 전달하는 방식이다.
◆ ECMAScript/자바스크립트 : 플렉스에서는 이와 유사한 액션스크립트를 적용했다.
◆ 웹 서비스 : 플렉스 애플리케이션은 HTTP 통신뿐 아니라 XML 통신 프로토콜인 SOAP 메시지로 데이터를 송수신할 수 있다.
◆ CSS : MXML 스타일은 이를 기초로 한다.
◆ 자바 객체 지원 : MXML 태그는 자바빈즈를 비롯한 일반 자바 객체를 사용할 수 있다.
◆ SWF : 플렉스는 공인된 플래시 파일 포맷인 SWF 파일로 컴파일된다.
◆ SVG(Scalable Vector Graphics) : 플렉스는 벡터 형식의 그래픽 표준인 SVG를 따른다.

자바 기반 웹 애플리케이션 개발과 유사
플렉스에서 사용하는 각 요소(컴포넌트)들은 널리 알려진 표준 기술을 사용하기 때문에 자바를 이용해 웹을 개발해본 사람이라면 그 기능이 서로 유사함을 알 수 있다. <표 1>에 플렉스와 자바 기반 웹 개발시 유사하게 쓰이는 기술들을 정리했다.

<표 1> 플렉스와 자바 기반 웹 개발의 유사 요소

◆ 문법 : 플렉스에서는 HTML 대신에 XML을 따르는 MXML을 쓴다. 또한 플렉스에서는 폰트나 색상 등의 스타일을 지정하는 CSS처럼 Style, Font, Theme 등을 사용한다. 클라이언트의 이벤트 처리를 위해 자바스크립트와 유사한 코딩 스타일을 지닌 액션스크립트를 사용한다.
◆ 컴포넌트 및 화면 구성 : 사용자 화면을 구성하는 컴포넌트로는 자바의 AWT나 Swing과 같은 컨트롤과 컨테이너가 있다. 컴포넌트를 사용해 화면을 구성하기 위해 자바에서는 컨테이너 및 레이아웃 매니저를 사용하는데 플렉스에서는 이와 유사한 컨테이너를 사용한다.
◆ 사용자 정의 컴포넌트 : 자바에서는 자바빈즈나 태그 라이브러리를 사용하는데 비해 플렉스에서는 SWC(플래시 컴포넌트)나 커스텀 컴포넌트 및 JSP 태그라이브러리를 정의해 사용할 수 있다.

<표 1>처럼 유사한 기술이 많으므로 HTML과 자바스크립트, 그리고 AWT의 컴포넌트 배치 및 레이아웃 매니저의 개념을 알면 대충 플렉스의 코드는 이해할 수 있으리라 생각된다. 그리고 플렉스는 독립적으로 구동되는 서버가 아니라 자바 애플리케이션 서버에 배치되기 때문에 JSP를 비롯한 자바 객체, 스트럿츠 프레임워크, 웹 서비스 등과도 쉽게 연동할 수 있다. 그러면 어떻게 플렉스를 배치하는지 살펴보자.

플렉스는 서버 컴포넌트
플렉스는 독립적으로 실행되는 서버가 아니라 JRun, 톰캣 등 WAS(Web Application Server)나 JSP 컨테이너에 배치되는 서버 컴포넌트이다. 따라서 JSP 컨테이너가 설치되어 있을 경우 손쉽게 플렉스 개발 환경을 구축할 수 있다.

플렉스 인스톨 후 flex.war를/WEB-INF 밑에 풀어주면 애드온된다
플렉스 서버 환경 구축은 제목처럼 간단하다. 현재는 플렉스 1.0 설치 파일을 구하려면 매크로미디어 홈페이지에서 설치 CD를 주문해야 하지만, 향후에는 다운로드 사이트에서 바로 다운받을 수 있을 것이라고 한다. 다음은 톰캣 5.0에서 server.xml 파일에 flex와 samples라는 컨텍스트를 추가하기 위한 설정이다.

<Context path="" docBase="ROOT" debug="0" reloadable="true"/>
<Context path="/flex" docBase="ROOT/flex" debug="0" reloadable="true"/>
<Context path="/samples" docBase="ROOT/samples" debug="0" reloadable="true"/>

<화면 3> 플렉스 컴포넌트 설치 디렉토리

CD에 있는 설치 파일을 인스톨하면 설치 디렉토리에 flex.war이 생긴다. flex.war의 압축을 풀어서 생기는 WEB-INF 이하 디렉토리의 파일들을 <화면 3>처럼 JSP 컨테이너 루트 디렉토리의 WEB-INF 디렉토리에 복사하면 현재 설정 그대로 플렉스를 구동할 수 있다. 앞의 코드에서 samples 컨텍스트의 경우 flex.war를 복사해줘도 되나 샘플 코드가 없으므로 flex.war와 같이 생성되는 samples.war 파일들을 따로 samples라는 디렉토리를 만들어서 압축을 풀어준다. 컨텍스트와 컴포넌트 설정이 제대로 됐을 경우 JSP 컨테이너를 재가동하면 톰캣 콘솔에서 플렉스 1.0이 설정됐다는 메시지가 나오며, http://127.0.0.1:8080/samples/로 접속하면 각종 데모를 볼 수 있다.

플렉스 서버는 mxml을 .swf 파일로 컴파일해 서비스한다
JSP의 경우 서버로 JSP 페이지의 요청이 처음 들어오면 서블릿으로 컴파일해 처리 결과를 리턴한다. 그 후에는 JSP 파일의 변경 여부를 체크해 변경됐으면 JSP를 서블릿으로 컴파일해 리턴하고, 변경된 내용이 없으면 캐시 디렉토리의 컴파일된 서블릿을 그대로 리턴한다.

JSP의 서비스 방식과 마찬가지로 플렉스도 내장된 컴파일러가 있으며 MXML 파일에 대한 요청이 들어오면 .swf로 컴파일한다. 이는 소스코드가 바뀌기 전까지 캐시되어 서비스된다. 바꿔 말하면 MXML 형식으로 필요한 코드를 작성하고, JSP 문서 디렉토리에 넣어 두면 플래시의 결과 화면을 볼 수 있다.

플렉스 프레젠테이션 서버는 플렉스 개발과 실행 서비스를 제공한다
어떻게 보면 플렉스 컴파일러 실행 파일을 이용해 mxml을 swf 파일로 컴파일해 웹 서버에 올려 서비스하면 되지 않을까 하는 생각을 하는 사람도 있을 것이다. 그러나 굳이 플렉스를 프레젠테이션 서버로 해서 서비스하는 이유가 있다. 바로 변경될 때마다 재컴파일해야 하는 불편함이 있기 때문이다. 여기에 분산 환경에서 비즈니스 로직을 제공하는 일반 자바 객체뿐만 아니라 자바, 닷넷 등의 웹 서비스 객체와 연동하는 서비스를 제공한다는 것도 한 몫을 한다. 한편으로는 필자는 자바에서 PDF로 출력하는 컴포넌트처럼 swf로 만들어 주는 컴포넌트도 나오지 않을까 하는 생각을 해본다.

플렉 아키텍처
플렉스 아키텍처는 플렉스 프레젠테이션 서버를 중심으로 파악하면 된다(<그림 1>). 플렉스 프레젠테이션 서버는 크게 개발 환경 부분과 실행 환경 부분으로 구성되어 있다. 개발 환경은 MXML, 액션스크립트, 플렉스 클래스 라이브러리를 플렉스 애플리케이션 프레임워크로 묶을 수 있다. 런타임 서비스는 swf 컴파일 및 캐싱 등의 실행 서비스를 제공한다.

<그림 1> 플렉스 아키텍처

<그림 1>의 하단을 보면 플렉스 프레젠테이션 서버가 WAS에 애드온되는 모습을 표현하기 위해 J2EE와 닷넷을, 우측에는 텍스트 에디터와 위지윅 방식을 지원하는 ‘브래디’라는 플렉스 전용 IDE를 볼 수 있다. 브래디는 현재 베타 4 테스트 중이며, 외형은 마치 드림위버 MX 2004를 보는 것과 같다.

<화면 4> 플렉스의 IDE 브래디

MXML은 플렉스 애플리케이션을 XML로 기술한다
MXML은 XML 기반이므로 자바 관련 IDE는 물론 메모장과 같은 텍스트 에디터만 있어도 쉽게 코딩할 수 있다. 또한 플렉스 전용 IDE인 브래디에서는 위지윅 방식의 코딩이 가능하다. 브래디는 플렉스 프로그램 작성시 레이아웃과 UI, 데이터 서비스 등 프레젠테이션 부분을 표현하는 데에 사용된다. MXML은 HTML에 비유될 수 있는데 그 특징은 다음과 같다.

◆ 유사점 : MXML은 HTML이 웹에서 보이는 화면을 태그로 표현하는 마크업 언어인 것처럼 플렉스에서 어떤 컴포넌트를 어떻게 보이도록 할 것인가를 기술하는 마크업 언어이다. 이것은 HTML처럼 각 컴포넌트의 속성을 지정함으로써 화면을 표현할 수 있다. 플렉스에서 사용하는 비주얼한 컴포넌트들은 <화면 5>의 컨트롤과 <화면 6>의 컨테이너로 구성되며, 컨트롤은 컨테이너에 담겨서 배치된다는 점에서 자바의 AWT와 유사하다.
◆ 차이점 : HTML은 지정된 태그만 가능하나 MXML은 커스텀 컴포넌트도 표현할 수 있다. 또한 HTML은 브라우저 화면에 나타날 것만을 기술하지만 MXML은 추가로 데이터와 연동하는 부분도 기술한다.
◆ MXML 문법 : MXML은 XML 문법만 알면 쉽게 이해할 수 있다. XML 문법을 따르므로 구조적이며 가독성이 높다. 다음의 코드는 'Hello Flex'라는 메시지를 Label 컨트롤에 찍어주는 간단한 코드이다. 2째 줄은 XML의 시작을 알리는 부분이며 인코딩 방식을 지정한다. 만약에 MXML 안에 한글이 있다면 <리스트 3>처럼 인코딩을 'euc-kr'로 지정해야 파싱 에러가 안 난다. 3째 줄의 <mx:Application>은 MXML의 루트 태그로 여기서부터 MXML이 시작되며 </mx:Application>으로 끝난다. 또한 'mx'라는 네임스페이스 사용을 나타내고 있으며, 이에 모든 태그에는 'mx'가 붙는다. 4째 줄은 Label 컨트롤을 쓰겠다는 것이며, Label에 텍스트 속성은 'Hello Flex'로 하고 폰트 크기는 20이다. 이처럼 HTML에서 사용했던 여러 가지 속성은 MXML 태그의 프로퍼티로 제공되는데, MXML 태그에는 컴포넌트 속성, 이벤트, 스타일, 이벤트 반응(behavior) 등을 지정할 수 있다. 이는 액션스크립트의 함수로써 접근과 제어가 가능하다.

// 간단한 플렉스 예제
<?xml version="1.0" encoding="utf-8"?>  
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml">
<mx:Label text="Hello Flex" fontSize="20"/>
</mx:Application>

// 간단한 플렉스 예제(한글)
<?xml version="1.0" encoding="euc-kr"?>  
…중략…

액션스크립트는 이벤트, 에러 및 데이터를 처리하는 스크립트이다
플렉스의 UI는 이벤트 중심으로 작동한다. 플렉스에서는 사용자가 발생시키는 이벤트 유형을 정의하고, 어떻게 반응할 것인가를 액션스크립트로 기술한다. 액션스크립트로써 이벤트를 처리하는 방법은 자바스크립트와 유사하다. 실행 중에 발생하는 에러나 데이터 검증 에러를 감지해 사용자에게 메시지를 전달하며, 플렉스 컨트롤 중에서 배열과 같은 데이터가 있어야 화면에 보여지는 것들(예 : 리스트, 그리드, 트리 메뉴 등)에 다양한 방법으로 내외부 데이터를 제공한다.

액션스크립트는 문법, 용도 등에서 자바스크립트와 유사하지만 차이점도 있다. 하나는 Document, Window, Anchor와 같은 브라우저 관련 객체를 지원하지 않는다는 것이다. 이는 일반 웹 페이지가 페이지(윈도우) 중심으로 움직이는 것과는 달리 플렉스는 한 애플리케이션에서 화면을 모두 처리하기 때문이다. 그리고 자바스크립트는 String 값의 길이가 ‘0’이 아니면 true를 리턴하고, ‘0’이면 false를 리턴하는 반면 액션스크립트는 String을 number로 변환해 ‘0’이면 false를 리턴하고, 아니면 true를 리턴한다.

플렉스 클래스 라이브러리는 플렉스 컴포넌트를 제공한다
플렉스 클래스 라이브러리는 컨트롤과 컨테이너로 구성되어 있다. 컨트롤은 사용자 작동을 핸들링하거나 데이터를 보여주는 컴포넌트이고(<화면 5>), 컨테이너는 플래시 플레이어가 그리는 화면이나 컨트롤을 배치하기 위한 컴포넌트이다(<화면 6>). 이들은 플렉스 애플리케이션의 개발 편의를 위해 다음과 같은 특성을 가진다.

◆ 모든 컴포넌트들은 MXML API를 통해 선언하고 그 속성과 이벤트를 정의할 수 있다.
◆ 액션스크립트 API는 실행시에 컨트롤의 메쏘드와 속성, 이벤트를 제어할 수 있다.
◆ 스타일, 스킨, 폰트 등을 이용해 사용자 정의의 룩앤필을 적용할 수 있다.

런타임 서비스에서는 관리적인 서버 기능을 제공한다
플렉스 런타임 서비스에서는 히스토리 관리, 원격 객체 접근 등 관리적인 서버의 기능을 제공함으로써 보다 편리하게 개발할 수 있다. 그러나 인증이나 세션 관리처럼 자바 애플리케이션 서버와 중복되는 기능은 해당 서버의 기능을 활용하도록 되어 있다. 이외에도 컴파일 및 캐싱, 플래시 플레이어 감지 및 업데이트 등의 기능이 제공된다.

한편 플렉스의 코드는 액션스크립트 클래스, MXML 파일, SWF 파일 및 외부 컴포넌트 등으로 구성된다. 이들이 컴파일된 결과는 SWF 파일로 플래시 플레이어에 다운로드되어 클라이언트에서 플레이된다. 하나의 파일로 만들어지기 때문에 MXML 파일이나 인클루드된 액션스크립트 파일 밖에서 클래스를 정의하거나 사용할 수 없으며, 임포트된 액션스크립트 클래스는 최종 SWF 파일에 추가된다.

플렉스 개발의 기본은 MXML과 액션스크립트
TV의 모 CF 광고에서 ‘북치기, 박치기’만으로 랩을 할 수 있다고 했는데 플렉스도 MXML과 액션스크립트를 알면 기본기는 터득한 셈이다. MXML은 플렉스의 XML의 확장판으로 인터페이스를 기술하며, 액션스크립트는 자바스크립트처럼 이벤트와 데이터를 처리한다고 보면 된다. MXML과 액션스크립트는 WEB-IN\flex 디렉토리 밑에 위치하는 플렉스 클래스 라이브러리의 각종 컴포넌트들을 사용한다. 이 세 가지 요소들이 모여 플렉스 애플리케이션 프레임워크를 구성한다.

액션스크립트는 MXML에 들어가는 이벤트 처리 스크립트이다
액션스크립트는 버튼을 누르거나 마우스를 조작하는 등의 여러 가지 이벤트 처리를 기술하는 스크립트이다. 액션스크립트에서 MXML을 사용하는 방법은 HTML 태그의 다양한 위치에서 자바스크립트를 활용하는 방법과 유사하다. 간단한 버튼 컨트롤을 예로 액션스크립트를 사용하는 방법들을 살펴보겠다.

컨트롤의 이벤트 속성에서 스크립트 처리하기
다음의 코드는 버튼 컨트롤의 click 이벤트 속성에 직접적으로 ‘클릭’이라는 메시지를 alert 창으로 뿌리도록 기술하는 예이다. 이때 mx.controls.Alert.show 함수는 system_classes 디렉토리에 기본으로 제공되는 액션스크립트 함수이다.

<?xml version="1.0" encoding="euc-kr"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml">
   <mx:Button label="누르세요" click="mx.controls.Alert.show('클릭!', 'Message');"/>
</mx:Application>

스크립트 태그에서 함수로써 이벤트 처리하기
다음의 코드는 자바스크립트가 <script> 태그 안에 함수를 기술하듯 <mx:Script> 태그 안에 액션스크립트의 함수를 기술한 예이다. 즉 버튼 컨트롤에 click 이벤트 발생시 myButtonClick 함수를 호출하고 이를 <mx:Script> 태그 안에 기술한 것을 보여준다.

<?xml version="1.0" encoding="euc-kr"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml">
   <mx:Script>
      function myButtonClick() {
         mx.controls.Alert.show('클릭!', 'Message');
      }      
   </mx:Script>
   <mx:Button label="누르세요" click="myButtonClick()"/>
</mx:Application>

이벤트 처리 함수를 액션스크립트 파일로 따로 정의해 사용하기
다음은 자바스크립트가 <script> 태그 안에 들어가는 코드들을 .js 파일에 파일로 빼듯이 액션스크립트가 .as 파일에 정의한 예이다. 여기서 my_script.as 파일은 같은 디렉토리에 위치하며, 다른 디렉토리에 정의할 경우 상대 또는 절대 경로로 표시하면 된다.

* my_action.mxml
<?xml version="1.0" encoding="euc-kr"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml">
   <mx:Script source="my_script.as" />
   <mx:Button label="누르세요" click="myButtonClick()"/>
</mx:Application>

* my_script.as
function myButtonClick() {
   mx.controls.Alert.show('클릭!!', 'Message');
}

액션스크립트에서 인클루드하기
다음은 include를 태그로 처리하지 않고 안에 정의한 예이다. #include 구문은 로직에 따라 필요한 위치에 동적으로 올 수 있다.

<?xml version="1.0" encoding="euc-kr"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml">
      <mx:Script>
      #include "my_script.as"
      </mx:Script>
   <mx:Button label="누르세요" click="myButtonClick()"/>
</mx:Application>

액션스크립트에서 컴포넌트 사용 방법
액션스크립트에서 컴포넌트를 사용한다는 것은 코드 재사용성 및 복잡한 로직을 캡슐화할 수 있다는 점에서 매우 유용하다. 이는 JSP에서 자바빈즈를 쓰는 것과 유사하다. JSP에서는 자바빈즈 클래스를 먼저 만든 상태에서 JSP 태그나 스크립트에서 쓰는 반면, 액션스크립트에서는 MXML 자체로 정의해 쓸 수 있다.

MXML을 이용한 컴포넌트 사용
<리스트 2>에는 두 개의 파일이 있는데, GusuButton1.mxml은 컴포넌트를 정의한 파일이다. 여기서는 버튼의 글씨를 빨간색으로 정의했고, click 이벤트를 dispatchEvent 함수를 통해 따로 정의했다. 이 파일에 정의된 버튼을Custom1.mxml의 ‘xmlnl=*’에서 GosuButton1이란 이름으로 찾아오며, click 이벤트가 발생하면 메시지를 출력하게 된다.

 <리스트 2> MXML을 이용한 컴포넌트 사용 예
Custom1.mxml
<?xml version="1.0" encoding="euc-kr"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml" xmlns="*">
   <GosuButton1 click="mx.controls.Alert.show('GosuButton1을 누르셨군요^_^')"/>
</mx:Application>

GosuButton1.mxml
<?xml version="1.0" encoding="euc-kr"?>
<mx:HBox xmlns:mx="http://www.macromedia.com/2003/mxml">
   <mx:Metadata>
       [Event("click")]
   >/mx:Metadata>
      <mx:Button label="GosuButton1" color="red" click="dispatchEvent({type:'click'})"/>    
</mx:HBox>

액션스크립트를 이용한 컴포넌트 사용
<리스트 3>은 GosuButton.as 파일에 컴포넌트를 정의했으며, 여기서는 Button 클래스를 GosuButton2 클래스로 재정의했다. 플렉스의 모든 컴포넌트들은 MoviClip, UIObject, UIComponent 순으로 구성되어 있다. 그래서 컴포넌트들은 동일한 API를 통해 속성에 접근할 수 있다. <리스트 3>에서는 init 메쏘드에 버튼의 컬러 및 레이블 속성을 지정했다. custom2.mxml에서는 GosuButton2로 정의된 클래스를 ‘gosu’라는 네임스페이스에서 찾아서 태그로 사용했다.

<리스트 3> 액션스크립트를 이용한 컴포넌트 사용 예
custom2.mxml
<?xml version="1.0" encoding="euc-kr"?>
<mx:Application xmlns:gosu="*" xmlns:mx="http://www.macromedia.com/2003/mxml" >
   <gosu:GosuButton2 click="mx.controls.Alert.show('GosuButton2를 누르셨군요^_^')" />
</mx:Application>

GosuButton.as
class GosuButton2 extends mx.controls.Button {
   function GosuButton2() {
   }
function init(Void):Void  {
      setStyle("color", 0x6666CC);
      setLabel("GosuButton2");
      super.init();
      invalidate();
   }
}

SWC 컴포넌트
플래시 MX 2004를 이용해 라이브러리에 있는 컴포넌트를 SWC 파일로 익스포트한 것은 플렉스에서 컴포넌트로 사용할 수 있다. SWC 파일에는 SWF 파일, 이미지, 메타 데이터 등이 하나의 압축 파일로 저장된다. 코드 예제는 지면 관계상 매크로미디어 홈페이지를 참조하길 바란다.

액션스크립트에서 이벤트 처리 방법
액션스크립트에서 이벤트를 처리하는 방법은 크게 세 가지로 나눌 수 있다. 있는 그대로 이벤트 속성을 처리하는 방법, MXML 파일에 이벤트를 따로 정의하는 방법, 이벤트를 스크립트에서 정의해 이벤트 리스너로 등록하는 것이 그것이다.

시스템 함수 그대로 사용하는 예
다음은 일반적으로 시스템에 정의된 이벤트를 처리할 경우 쓰는 방법이다. 이 예제는 click 이벤트에 msg 함수를 정의해 버튼을 클릭할 때 msg 함수가 호출되는 것을 보여준다.

event1.mxml
<?xml version="1.0" encoding="euc-kr"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml">
   <mx:Script>
         function msg() {
             mx.controls.Alert.show('gosuButton을 누르셨군요^_^');
         }
   </mx:Script>
   <mx:Button label="BASIC이벤트" id='gosuButton' click='msg();'/>
</mx:Application>

사용자 정의 이벤트 처리 예
다음은 GosuEventButton2.mxml 파일에 btn1Clicked와 btn2Clicked라는 이벤트를 따로 정의했다. Button1, 2를 그 안에 정의하고 dispatchEvnet 함수에서 두 이벤트가 발생하도록 했으며, 태그 안에 그 이벤트를 정의했다. 그리고 event2.mxml 파일에서는 xmlns=“*”에 GosuEventButton2 컴포넌트를 찾아내어 MXML 태그로 정의하면서 두 이벤트를 처리했다. 이렇게 하면 화면에서 두 개의 버튼을 볼 수 있다.

event2.mxml
<?xml version="1.0" encoding="euc-kr"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml" xmlns="*">
   <GosuEventButton2 btn1Clicked="mx.controls.Alert.show('Button1을 누르셨군요^_^')"
   btn2Clicked="mx.controls.Alert.show('Button2를 누르셨군요^_^')"/>
</mx:Application>

GosuEventButton2.mxml
<?xml version="1.0" encoding="euc-kr"?>
<mx:HBox xmlns:mx="http://www.macromedia.com/2003/mxml">
   <mx:Metadata>
      [Event("btn1Clicked")]
      [Event("btn2Clicked")]
   </mx:Metadata>
      <mx:Button label="버튼1" color="red" click="dispatchEvent({type:'btn1Clicked'})"/>    
      <mx:Button label="버튼2" color="blue" click="dispatchEvent({type:'btn2Clicked'})"/>    
</mx:HBox>

이벤트 리스너에 사용자 이벤트를 등록하는 예
다음은 자바에서 AWT의 객체에 이벤트를 처리할 때 리스너를 등록하듯 액션스크립트에서 사용자 정의 이벤트를 이벤트 리스너 등록 함수를 이용해 컨트롤에 등록한 예이다. 여기서는 태그 안에 gosuEventListener 객체를 만들고, 플렉스가 초기화될 때 addEventListener 함수를 이용해 gosuButton이라는 아이디를 가진 버튼에 리스너를 등록한다.

event3.mxml
<?xml version="1.0" encoding="euc-kr"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml" initialize="createListener()" >
   <mx:Script>
         var gosuEventListener = new Object();
         function createListener() {
            gosuEventListener.click = function(event) {
            mx.controls.Alert.show('gosuButton을 누르셨군요^_^');
         }
      }
   </mx:Script>
   <mx:Button label="이벤트 리스너" id='gosuButton'
      initialize='gosuButton.addEventListener("click", gosuEventListener);'/>
</mx:Application>

액션스크립트의 데이터 바인딩 방법
플렉스에서는 다양한 방법으로 사용자가 보게 될 컨트롤에 데이터를 바인딩한다. 크게는 내부 데이터를 이용하는 방법과 외부 데이터를 이용하는 방법이 있다. 내부 데이터는 MXML과 액션스크립트를 이용해 데이터를 지정하는 방법이고, 외부 데이터는 XML을 이용하거나 자바 애플리케이션 서버와의 통신으로 데이터를 받는 방법이다. <화면 8>은 리스트 컨트롤에 데이터를 액션스크립트로 처리해서 보여주는 화면으로, 다음에서 설명할 네 가지의 방법으로 가능하다.

컨트롤의 dataProvider 속성에 배열 지정
리스트 컨트롤은 dataProvider에 배열을 넘겨주면 <화면 8>과 같이 데이터를 보여주게 되어 있다. <리스트 4>는  dataProvider 속성에 Array를 써서 지정하는 예이다.

 <리스트 4> 컨트롤의 dataProvider 속성에 배열 지정
data_list1.mxml
<?xml version="1.0" encoding="euc-kr"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml">
   <mx:List id="source" >
      <mx:dataProvider>
         <mx:Array>
            <mx:Object label="플렉스" data="FLEX"/>
            <mx:Object label="MXML" data="MXML"/>
            <mx:Object label="액션스크립트" data="ACTIONSCRIPT"/>
         </mx:Array>      
      </mx:dataProvider>
   </mx:List>
</mx:Application>

스크립트 태그에서 dataProvider 속성에 배열 지정
<리스트 5>는 <리스트 4>에서 <mx:Array>로 지정한 배열을 <mx:Script> 태그 안에 ‘BOOK_ARRAY’라는 배열 변수로 선언해 <mx:dataProvider> 태그에 지정한 것이다. 이때 배열 변수임을 알리기 위해 ‘{ }’ 안에 변수를 기입한다.

 <리스트 5> dataProvider 속성에 배열 지정
data_list2.mxml
<?xml version="1.0" encoding="euc-kr"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml">
   <mx:Script>
   var BOOK_ARRARY:Array=
      [
         {label:"플렉스", data:"FLEX"},
         {label:"MXML", data:"MXML"},
         {label:"액션스크립트", data:"ACTIONSCRIPT"},
      ];
   </mx:Script>
   <mx:List id="source" >
      <mx:dataProvider>
         {BOOK_ARRARY}
      </mx:dataProvider>
   </mx:List>
</mx:Application>

Model 태그에 데이터 소스 XML 파일 위치 지정
<리스트 6>은 XML 파일에 라는 루트 태그를 지정하고, 엘리먼트를 데이터 소스로 만든다. 그리고 data_list3.mxml에서는 태그의 source 속성에 해당 XML 파일의 URL을 기술하고, 태그의 아이디 ‘booksModel’와 엘리먼트 이름을 List 컨트롤의 dataProvider 속성에 ‘{booksModel.book}’라는 이름으로 지정한다.

 <리스트 6> 데이터 소스 XML 파일 위치 지정
data_list3.mxml
<?xml version="1.0" encoding="euc-kr"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml">
    <mx:Model id="booksl" source="books.xml"/>
    <mx:HBox>
        <mx:List id="source" dataProvider="{books.book}"/>
    </mx:HBox>
</mx:Application>

books.xml
<?xml version="1.0" encoding="euc-kr"?>
<books>
    <book label="플렉스" data="FLEX"/>
    <book label="MXML" data="MXML"/>
    <book label="액션스크립트" data="ACTIONSCRIPT"/>
</books>

Model 태그를 이용한 배열 속성 지정
<리스트 7>은 <리스트 6>의 XML 소스를 태그 안에 엘리먼트를 나열함으로써 model 태그의 ID와 엘리먼트 이름을 List 컨트롤의 dataProvider 속성으로 지정한다. dataProvider 속성은 따로 태그로 분리되어 있는데, <리스트 6>처럼 로 지정해도 똑같이 작동한다.

 <리스트 7> Model 태그를 이용한 배열 지정
data_list4.mxml
<?xml version="1.0" encoding="euc-kr"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml">
   <mx:Model id="books">
      <book label="플렉스" data="FLEX"/>
      <book label="MXML" data="MXML"/>
      <book label="액션스크립트" data="ACTIONSCRIPT"/>
   </mx:Model>
   <mx:List id="list1">
      <mx:dataProvider>{books.book}</mx:dataProvider>        
   </mx:List>
</mx:Application>

플렉스는 자바 애플리케이션 서버로부터 동적 데이터를 가져올 수 있다
필자가 초창기에 애플릿을 개발했을 때 고민 중의 하나는 애플릿에서 동적인 데이터를 가져와서 보여주는 것이었다. 그때는 애플릿에서 서블릿을 호출하고 여기서 나오는 스트림을 받아서 애플릿에서 보여주는 방법을 쓰거나, 서버와 소켓을 연결해 데이터를 받아서 사용했다. 하지만 플렉스에서는 서버와 다양한 통신 방법을 제공한다.

플렉스 애플리케이션이 자바 애플리케이션 서버와 연동되는 개념은 클라이언트가 서버에 요청하면 Result 객체로 데이터를 받는 방식이다. 이것은 통신 프로토콜과 서버의 서비스 방식에 따라 HTTPService, WebService, RemoteObject로 나뉜다. HTTPService는 가장 일반적인 예로 HTTP 프로토콜을 이용해 JSP를 호출해 결과를 받는 것이며, WebService는 SOAP 프로토콜을 통해 웹 서비스와 통신하는 방식이다. RemoteObject는 자바에서 원격 객체를 SOAP 프로토콜이나 AMF 프로토콜을 이용해 통신하는 방식이다. 이때 해당 서비스를 찾을 수 있도록 /WEB-INF/flex/flex-config.xml 파일에 해당 서비스를 등록해야 한다. 다음은 employeeSrv라는 이름으로 등록된 HTTPService를 호출하는 예이다.

<mx:HTTPService id="employeeSrv" url="employees.jsp">
   <mx:request>
      <deptId>{dept.selectedItem.data}</deptId>
   </mx:request>
</mx:HTTPService>

플렉스 화면은 컨트롤과 컨테이너를 이용해 만들어진다
이쯤 되면 플렉스에 대해 어느 정도 감을 잡았을 것이며, 웬만한 플렉스 소스코드를 보더라도 이해하는 데는 무리가 없으리라 생각한다. 여기서 ‘북치기 박치기’ 얘기를 한번 더 하겠다. 플렉스 코딩이 MXML과 액션스크립트 중심이라면, 플렉스 화면은 컨트롤 컴포넌트와 컨테이너 컴포넌트 두 가지의 조합으로 이뤄진다. 이 두 가지를 조합하는 원리는 컨테이너를 먼저 깔아주고 그 위에 사용자가 쓸 컨트롤을 배치하는 형식이다.

컨트롤
컨트롤은 Button, TextArea 등 사용자가 직접적으로 조작하며 반응하는 컴포넌트들이다. 컨트롤은 MXML API를 통해 속성과 이벤트를 정의하고 액션스크립트에서 조작이 가능하다. <화면 5>를 보면 컨트롤의 기능에 대해 쉽게 이해될 것이며, SWF나 JPEG 파일을 보여주는 Loader나 진행 상태를 보여주는 ProgressBar, 달력으로 날짜를 선택하게 해주는 DateChooser, DateField 등이 눈에 띈다.

컨테이너
컨테이너는 플래시 플레이어가 그리는 사각 표면을 정의한다. 컨테이너는 말 그대로 컨트롤을 담는 컴포넌트이다. 컨트롤을 담는데 있어 컨테이너는 컨트롤 크기와 위치를 정의하는 layout 컨테이너와 컨트롤의 이동과 네비게이션을 정의하는 Navigator 컨테이너가 있다. 특히 Tab Navigator와 Accordion Navigator 컨테이너는 웹 애플리케이션에서 모양과 화면을 깔끔하게 정리해 준다.

Layout 컨테이너는 자바의 AWT를 해본 사람들이라면 어느 정도 익숙할 것이다. 네모난 상자에 컨트롤을 위치하게 해주는 Box, 여기에 타이틀 부분이 추가된 Panel, 컨테이너 내의 XY 좌표를 지정해 컨트롤을 위치시키는 Canvas, HTML 테이블의 셀에 컨트롤을 하나씩 위치시키는 Grid 등이 있다.

플렉스 컴포넌트는 CSS를 이용해 스타일을 지정한다
플렉스는 HTML에서 쓰는 CSS 개념을 그대로 적용했다. 그래서 플렉스에서 쓰는 컴포넌트는 HTML처럼 다양한 방식으로 스타일을 정의할 수 있다. 여기서는 Button 컨트롤의 fontSize 속성 스타일을 지정하는 방법을 살펴보겠다. 스타일 적용은 <화면 1>의 예를 참조하길 바란다.

◆ 컨트롤 속성으로 스타일 지정
<mx:Button id="myButton" fontSize="15" label="My Button"/>
◆ Style 태그 속에 스타일 정의
<mx:Style>
   Button { fontSize: 15 }
</mx:Style>
◆ 외부 스타일 시트 지정
<mx:Style source="myStyle.css"/>
◆ StyleManager 클래스의 버튼 폰트 크기 속성을 setStyle 메쏘드로 지정
StyleManager.styles.Button.fontSize = 15;
StyleManager.styles.Button.setStyle("fontSize",15);
◆ 버튼 아이디의 setStyle() 메쏘드 호출을 이용한 스타일 지정
myButton.setStyle("fontSize", 15);

플렉스 컴포넌트는 CSS 방식 외에도 테마나 스킨을 통해 스타일을 바꿀 수 있다. 스킨은 컴포넌트의 소스 그래픽이나 심볼을 수정함으로써 컴포넌트의 모습을 바꾸게 되는데, 플래시의 심볼을 이용하는 asset 스킨과 사용자 정의 컴포넌트를 이용하는 Progmatic 스킨이 있다. 그리고 테마는 컴포넌트의 스타일과 스킨을 모아서 하나로 구성한 것으로 디폴트로 ‘Halo’라는 테마가 적용되어 있다.

플렉스와의 인연은 계속 될까
지금까지 플렉스에 대해 개략적인 내용을 살펴봤다. 플렉스의 다양한 특징을 종합해 보면 다음과 같은 장점들로 정리할 수 있다. 특히 필자는 소스코드가 보이지 않아서 남들 모르게 마음껏 기발한 로직으로 개발할 수 있다는 것이 맘에 든다.

[1] 다양한 유저 인터페이스를 컴포넌트로 제공한다.
[2] 컴포넌트 기반으로 개발하므로 생산성이 높다.
[3] 사용자 정의 컴포넌트를 사용함으로써 재사용성이 높다.
[4] XML을 비롯한 표준화된 기술을 사용함으로써 쉽게 배워 적용할 수 있다.
[5] 클라이언트의 플래시플레이어에서 작동되므로 서버의 부하를 줄여준다.
[6] 플래시플레이어 환경이 있으면 동일한 인터페이스를 제공할 수 있다.
[7] 챠트나 그래프 등의 비즈니스를 위한 컴포넌트가 제공된다.
[8] 화면과 데이터 로직을 완벽히 분리할 수 있다.
[9] 자바애플리케이션 서버와 연동되므로 확장성이 매우 뛰어나다.
[10] 플래시로 구동되므로 스크립트 및 컨텐츠 소스 코드가 노출되지 않는다.

주목해야 할 것은 플렉스가 클라이언트의 PC, 즉 플래시 플레이어에서 실행된다는 장점 때문에 다양한 플랫폼과 디바이스에서 실행 가능하다는 점이다. 이는 휴대폰이나 PDA 등에서도 플렉스 애플리케이션이 돌아가는 날이 멀지 않았음을 의미한다.
필자는 IT에서 상당히 오래갈 기술을 예측해 보면, MS 윈도우, 썬의 자바, 어도비의 PDF, W3C의 XML 등을 들 수 있다. 그리고 이번에 다룬 매크로미디어의 플렉스 기술도 인터넷 기술 발달의 흐름선상에서 볼 때 아마 그러하리라고 확신한다. @

'Web Development > FLEX' 카테고리의 다른 글

Flex 손모양 커서 나오게 하려면  (0) 2008.10.16
AIR란?  (1) 2008.09.04
[Flex 2] 플렉스 2 실습환경 꾸미기  (0) 2007.10.15
Flex 게시판 페이지 관련  (0) 2007.08.10
Flex 2.0 설치  (0) 2007.08.10