외부에서 들어오는 데이터가 "0"이나 "1"이면 어떻한다?(혹은 true 나 false일지도..)
CheckBox를 클릭하면 Alert 창이 떠야한다면?
이럴때마다 ItemRenderer를 열어서 수정해야한다면 말이 안되겠지요.
일단 2번 같은 경우는 제가 알기로는 두가지 방법이 있습니다만 그중 하나는 Bubbles라는 이벤트 속성을 이용하는 방법입니다만 ItemRenderer에서 이벤트를 발생시키면서 bubbles 속성을 true로 지정해주면 DataGrid 밖에서 이벤트를 받아올 수 있지요.
다만.. bubbles라는 녀석의 특성상 데이터가 많이 꼬일 염려가 있다는게 문제입니다.
(꼬인다는건 "디버깅"이 어려워질 수 있다는 말을 쉽게 풀어 쓴 말입니다.)
그래서 저는 가장 확실한 방법으로 CallBack 함수를 지정해 놓는 방법을 선택했습니다.
public class CheckBoxRenderer extends CheckBox { //----------------------------------------------------------------------------- // // Constructor // //----------------------------------------------------------------------------- /** * Constructor. */ public function CheckBoxRenderer() { super(); }
//----------------------------------------------------------------------------- // // Variables // //----------------------------------------------------------------------------- /** * @private * 데이터 변경 확인 플래그 */ private var dataChanged:Boolean = false;
//----------------------------------------------------------------------------- // // Properties // //----------------------------------------------------------------------------- //------------------------------------- // onClickFunction //------------------------------------- /** * @private */ private var _onClickFunction:Function; /** * 클릭시 실행할 콜백함수 속성 */ public function set onClickFunction(value:Function):void { _onClickFunction = value; } /** * @private */ public function get onClickFunction():Function { return onClickFunction; } //----------------------------------------------------------------------------- // // Override Properties // //----------------------------------------------------------------------------- override public function set data(value:Object):void { super.data = value;
CheckBox를 상속받아 작업할겁니다. 왜 "UIComponent 안쓰고!"라고 말씀하신다면
그 이유는 UIComponent를 상속받은 클래스이기도 하고 지난시간 말했던 IDataRenderer, IDropInListitemRenderer, IListItemRenderer 이렇게 세 인터페이스가 이미 구현되어있으며 우리가 원하는 아이템 렌더러는 CheckBox아이템 렌더러이기 때문이지요.
//----------------------------------------------------------------------------- // // Variables // //----------------------------------------------------------------------------- /** * @private * 데이터 변경 확인 플래그 */ private var dataChanged:Boolean = false;
CheckBox 가 "Y"냐 "N"이냐에 따라 selected가 처리되는 로직이 필요합니다. 그러기 위해서는 그 코드를 어디에 넣는것이 좋을지 고민해봐야하는데 아까도 말했듯 모든 속성처리는 commitProperties에서 하게 됩니다. commitProperties를 호출하기 위해서는 저번에 이야기 했었던 대로 invalidateProperties() 메서드를 호출하면 됩니다. 그렇다면 코드를 아래와 같이 수정합니다.
public class CheckBoxRenderer extends CheckBox { //----------------------------------------------------------------------------- // // Constructor // //----------------------------------------------------------------------------- /** * Constructor. */ public function CheckBoxRenderer() { super(); }
//----------------------------------------------------------------------------- // // Variables // //----------------------------------------------------------------------------- /** * @private * 데이터 변경 확인 플래그 */ private var dataChanged:Boolean = false;
//----------------------------------------------------------------------------- // // Override Properties // //----------------------------------------------------------------------------- override public function set data(value:Object):void { super.data = value;
currentIcon이라는 생소한 속성을 위에서 보실 수 있습니다. 그것은 체크박스에서 체크되는 아이콘을 지칭합니다. 그 currentIcon이란 녀석은 mx_internal이라는 접근자를 이용하고 있고 LanguageReference에는 표시되지 않고 있어서 그 존재를 모르는 사람이 많습니다.
예전에 저도 그것을 몰라서 HBox에다가 넣고 horizontalAlign="center"를 주는 바보같은 짓을 일삼았는데 이 사실을 알고 난뒤에 Container를 사용하지 않고 좀더 가볍게 itemRenderer를 만들어 낼 수 있었지요.
그래서 updateDisplayList() 메서드에서 좌표를 잡아서 셀의 중앙에 놓고 clickHandler라는 메서드를 확장하여 변경된 값을 data에 반영하게 합니다. 그렇게 되면 아래와 같은 결과물이 나오게 되지요.
하지만 문제는 아다시피 저기서 아무리 체크박스를 눌러대도 실데이터는 바뀌지 않는다는 사실입니다.
그 다음에 밀려오는 문제는 "데이터가 변하지 않아요? 어쩌죠?" 하는 질문을 올려서 답변을 받아보거나 책을 찾아보거나 뭐.. 여러가지 행동들을 할 수 있을테지만 문제는 늘 그렇듯 근본적인 해결이 되지 않는 다는 사실입니다.
Flex 프로젝트를 1년간 11개나 해치워보니 알 수 있는건 당연하게도 매번 아이템 렌더러를 그때 그때마다 새로 만든다는게 엄청나게 귀찮은 일이었고 화면설계서를 받아보면 경악하여 기획자와 디자이너를 닥달하며 "구현이 불가능한 기능"이라는 사실을 강조하고 화면설계를 수정하자 요구 했었습니다.
사실 뭐.. 프로젝트에 투입되고 본격적인 개발이 시작되고 난뒤 약 40%정도의 시간을 그렇게 설득하고 우회하는 방법을 찾느라 소비했지요.
그렇다면 근본적인 해결점을 찾아보는 것이 어떻지 고민해보는 것이 좋겠다 싶었습니다.
괜찮은 아이템 렌더러를 만들어 놓고 앞으로 계속해서 이용하는 것이지요. 일단 그런 아이템 렌더러를 만들기 위해서는 데이터 그리드가 어떻게 만들어졌는지 알아야 합니다.
데이터 그리드의 구조 입니다.
전체적으로 각 객체의 컨트롤을 맡고 있는 DataGrid 상위 객체 안에 DataGridColumn들이 Array형태로 들어가 있고 DataGridColumn 안에 Header와 ItemRenderer가 같이 들어있습니다.
(단순하게 표현하면 그렇다는 거지요.. 실제로는 더 까다롭고 복잡한 구조입니다..)
일단 저정도만 알고 있으면 우리가 만들려는 DataGridItemRenderer가 어떤 놈인지 mx 패키지에서 확인해볼 필요가 있습니다.
TextField군요.. DataGridRenderer를 확장해서는 버튼이나 콤보박스같은건 넣을 수가 없겠다고 판단됩니다. 그럼 결국 DataGridItemRenderer에서 몇가지 인터페이스 클래스를 구현하여 아이템 렌더러를 만들어 내지요. 뭐. 저것도 사람이 만든건데 우리라고 만들지 말란법은 없으니까요.
일단 구현해야할 인터페이스 클래스는 IDataRenderer, IDropInListItemRenderer, IListItemRenderer 이렇게 3가지면 괜찮습니다. ILayoutManagerClient나 IStyleClient는 왜 구현하지 않냐고 물어보시면 우리는 UIComponent를 상속받아 아이템 렌더러를 만들것이기 때문이라고 말씀드리고 싶습니다.
왜냐하면 UIComponent는 ILayoutManagerClient나 IStyleClient를 구현하고 있기 때문이지요.
이러한 연유로 IDataRenderer, IDropInListItemRenderer, IListItemRenderer 이렇게 3가지 인터페이스만 구현해 볼까 합니다.
중요한 첫번째 내용이 끝이 났어요.
두번째 내용은 Flex의 UIComponent의 라이프 사이클(Life Cycle)에 대해 알아야할 순서입니다.
UIComponent의 Protect 접근자 클래스를 잘 이해해야하는데요.
그 중에서도 특히 updateDisplayList() 메서드와 createChildren()메서드. 그리고 commitProperties() 메서드를 잘 이해해야합니다.
이 updateDisplayList라는 메서드는 자식객체를 그리거나 혹은 자식객체의 사이즈나 위치를 변경할 때 사용됩니다. 그리고 Flex에서 이 메서드를 호출하기 위해서는 invalidateDisplayList()라는 메서드를 호출하거나 자식객체를 addChild할때 실행되게 되어있는 메서드입니다.
한마디로 자식객체에 변경이 생겨서 새로 화면을 그려내야할때 사용되는 녀석인데요.
자칫 잘못하면 본의아니게 계속해서 호출해 시스템을 다운시키는 원인이 될 수 있으니 조심히 사용해야합니다.
자식객체를 생성할때 호출하는 녀석으로 컨포넌트를 최초에 생성시킬때 한번 호출되고 다음부터는 고의로 호출하지 않는이상 호출되지 않는 메서드입니다.
commitProperties 메서드는 자식객체를 addChild()하거나 invalidateProperties() 에서드를 호출하면 실행되는 메서드로 이때 자식객체의 프로퍼티를 지정하고 변경값을 적용하는 역할을 합니다.
* 배경 RPC와 쉽게 연동, Not RPC 하나의 개념으로 다양한 언어에서 쓸 수 있게 구글에서 다양한 언어별로 개발 하다 보니. 통신을 위한 단일 표준이 필요
proto 파일 -> proto 컴파일러 -> 여러 언어로 변환 (java, python, c++)
Not socket 구글 에서 2008년 7월 발표 이슈 제시 - XML 문제 - Parsing, serialization (debugging) - Portable : IDL처럼 사용 - Heavy Optimization - Language 지원 짧은 데이터의 송수신 용도/긴 데이터 송수신이 목표가 아님
* XML 보다 좋은 점 Simple 3~10배 작음 20~100배 속도 빠름 모호하지 않음 바로 프로그램에 사용하기 쉬움
* 활용 구글 - 원래 index server request/response protocol로 사용했었음 - 48,162 different message types - 12,183 .proto files 다양한 회사 국내/외 게임 회사의 통신
* 장점 쓰기 편함 Stub 코드 자동 생성 - 통신에서 가져야 할 보편적 특성을 다 추가 - Serializing, Parsing 지원 코드 일치 - 클라이언트/서버 코드 동일 IDL 형태로 정의가 단순 - Portable - 클래스 또는 struct 디자인 언어 지원 java, c++, python 3rd party lib (많은 언어 지원.http://code.google.com/p/protobuf/wiki/ThirdPartyAddOns#RPC_Implementations) 배우기 쉬움 이클립스 플러그인 존재 Lite 버전 개발 가능 Good Document BSD license 언어마다 특화되고 쓰기 편한 특징을 제공
* 단점 Output이 binary만 존재 - PB의 Reflection을 이용해서 json으로 전달 가능 Map, set 지원 없음
Test폴더 생기고 TestTxt.java 생성됨 (17KB, Protocol buffer 내부 클래스 사용)
// c++ 로 하면 test.txt.pb.cc (12K) test.txt.pb.h (8K)
// python으로 하면, test/txt_pb2.py (2K)
* 생성된 자바 코드 Descriptor 지원 - internal_static_test_Request_descriptor Reflection 지원 - Message / Message.Builder interfaces. - Json 처럼 프로토콜로 변경 가능 (ajax 가능) 메시지 수정시 하위 호환 보장, 새로운 메시지로 변경되면 기존 코드에 대한 필드만 처리 파일이름을 디폴트로 해서 소스를 생성하지만, 내가 원하는 클래지 이름과 클래스 이름의 개별 지정이 가능 - option java_package = "com.example.foo.bar"; - option java_outer_classname = “ProtocolData"; PB의 Enum은 java의 enum으로 변경
* 크기 제한 디폴트로 크기 제한 : 64 MB 속도를 최적화 또는 악의를 가진 사용자로부터 보호하기 위해서 크기를 제한할 수 있음 - CodedInputStream/CodedOutputStream (ZeroCopyInputStream/ZeroCopyOutputStream ) SetTotalBytesLimit 메소드
* proto 파일 생성시 유의할 점 package 선언 클래스 파일 이름 운영을 위한 파일명 .proto message 등록 - Protocol buffer language guide Protoc.exe(컴파일러)에 의해 만들어진 java, python, c++ 코드는 고치지 말아야 한다.(immutable) protoc에서 컴파일 되면, 자동으로 accessor가 붙는다. - get/set/has…
* message 설명 package Type - Bool, int32, uint32, float, double, string, bytes, …. - Enum Nested type Default value importing Modifier - required : 반드시 사용해야 할 필드. 미초기화된 상태 미초기화된 메시지를 빌드하면 RuntimeException, 초기화되지 않은 메시지를 파싱하면서 에러나면 IOException발생 - optional : option의 개념 hasXXX() 로 확인 - repeated : 0을 포함하는 개수를 계속 넣을 수 있음 자바에서는 List객체로 구현됨
* 필드에 번호를 반드시 주는 이유 번호를 주지 않으면 protoc 에러 발생 Write/Read 할 때, serialization 순서를 주기 위함 필드 정보가 set되었는지 쉽게 알기 위함(내부적으로 bit 연산함)
* Versioning 정보가 없는 이유 새로운 필드를 언제든지 추가 될 수 있음 모든 정보를 볼 필요 없이 필요한 정보만 파싱할 수 있도록 함 But, java는 기본으로 존재하지 않지만, c++ 은 존재한다. 링킹 이슈. (GOOGLE_PROTOBUF_VERIFY_VERSION 매크로) Incompatible한 버전 때문에 문제가 없도록 해야 함
BlazeDS, powered by Adobe LiveCycle Data Services ES2 a server‐based Java remoting and web messaging technology that enables developers to easily connect to back‐end distributed data and push data to Adobe® Flex® and Adobe AIR™ applications for more responsive rich Internet application (RIA) experiences. For more performance and capable rich Internet applications, organizations need to consider the complete product offering available with LiveCycle Data Services ES2. Review the BlazeDS and LiveCycle Data Services ES2 comparison table for details.
BLAZEDS RELEASE BUILDS
Turnkey
The turnkey download contains a ready-to-use version of Tomcat (version 6.0.14) in which the BlazeDS WAR file has already been deployed and configured along with a variety sample applications. The turnkey allows you to get up and running with BlazeDS in a matter of minutes. BlazeDS is licensed under GNU Lesser General Public License, Version 3. Please refer to the Legal Stuff page for specific licensing information.
The source download is a zip file that includes the BlazeDS source code and build scripts, everything you need to build BlazeDS from source. For more information about the BlazeDS source code or to browse the source tree, go here. BlazeDS is licensed underGNU Lesser General Public License, Version 3.
Explore your options
Features
BlazeDS
LiveCycle Data Services ES2
RPC services
Java remoting/Action Message Format (AMF)
Yes
Yes
Ajax client libraries to Java™ remoting
Yes
Yes
WS/JSON proxy service
Yes
Yes
Messaging
Servlet-based messaging services (hundreds of clients per CPU)
Yes
Yes
Java NIO high-performance messaging (thousands of clients per CPU)
Download Adobe Flex Builder 3.0.2 Professional Eclipse Plug-in
Adobe® Flex® Builder 3 Professional Eclipse Plug-in (60 day trial) A professional Eclipse™-based developer tool enabling intelligent coding, interactive step-through debugging, and visual design of user interface layout and behavior for Flex applications. Includes support for building desktop applications with Adobe AIR.
This download requires Eclipse 3.3 or higher to be installed.