Search

'FLEX'에 해당되는 글 105건

  1. 2011/10/31 mypad에서 3개이상 화면 분활되는것 (3)
  2. 2010/10/05 webcam detect (1)
  3. 2010/10/04 flex webcam감지
  4. 2010/03/03 드디어 red5 0.9버전이 final로 나와따
  5. 2009/12/30 flex papervision3d에서 colloda모델 로드
  6. 2009/05/06 ultra shock라는 웹페이지
  7. 2009/04/23 flex스킨 css모음입니다.정말 쓸만하군요~ㅎㅎ (1)
  8. 2009/04/23 네모 던지기 입니다.
  9. 2009/04/21 각종 프로그래밍 모음 - 총망라~
  10. 2009/04/21 red5 미디어서버를 이용한 각종 채팅 프로그램과 화상 프로그램등 목록들~
  11. 2009/04/20 red5를 사용한 sip 폰을 개발하는 오픈소스 프로젝트...
  12. 2009/04/20 flex에서 record를 하는 방법이라..ㅋㅋㅋ
  13. 2009/04/20 ria용 바코드 식별 프로그램 ㄷㄷㄷ
  14. 2009/04/10 flex 마메 에뮬
  15. 2008/06/16 화상체팅 소스입니다.
  16. 2008/06/14 Creating a video sharing web application with FLEX
  17. 2008/06/14 플래시명령어모음
  18. 2008/06/14 플래시9의 바이너리 소켓
  19. 2008/06/14 포토샵 배경색 바꾸기..
  20. 2008/06/14 FLEX,FLASH 좋은 사이트 소개
  21. 2008/06/14 FLEX에서 팝업효과
  22. 2008/06/14 Flex, PHP와 MySQL를 이용한 간단 메모장 만들기
  23. 2008/06/14 플렉스에서 Event 처리
  24. 2008/06/14 제목 | FLEX에서 타이머 사용법
  25. 2008/06/14 Flex와 PHP를 이용한 MyTube 구현
  26. 2008/06/14 [Flex] 스킨(Skin)을 이용하여 확장가능한 게이지 ..
  27. 2008/06/14 Flex Component간 종속성을 없애보자(이벤트)
  28. 2008/06/14 Flex에서 namespace를 사용하는 예제
  29. 2008/06/14 [Flex] 동영상 화면 캡쳐후 서버에 전송하는 방법
  30. 2008/06/14 Flex] ExternalInterface를 이용한 Javascript와 통신

mypad에서 3개이상 화면 분활되는것

FLEX 2011/10/31 18:42 Posted by <!--r'i"z&i\n+#]]x juree23

'FLEX' 카테고리의 다른 글

mypad에서 3개이상 화면 분활되는것  (3) 2011/10/31
flex webcam감지  (0) 2010/10/04
TAG AAA

webcam detect

FLEX/TIP 2010/10/05 17:00 Posted by <!--r'i"z&i\n+#]]x juree23

http://dougmccune.com/blog/2008/04/03/simple-flex-motion-detection-example/
TAG

flex webcam감지

FLEX 2010/10/04 11:36 Posted by <!--r'i"z&i\n+#]]x juree23
http://www.adobe.com/kr/devnet/flash/articles/webcam_motion_print.html
저작자 표시 비영리 변경 금지

'FLEX' 카테고리의 다른 글

mypad에서 3개이상 화면 분활되는것  (3) 2011/10/31
flex webcam감지  (0) 2010/10/04

드디어 red5 0.9버전이 final로 나와따

FLEX/TIP 2010/03/03 17:50 Posted by <!--r'i"z&i\n+#]]x juree23
http://code.google.com/p/red5/
저작자 표시 비영리 변경 금지

flex papervision3d에서 colloda모델 로드

FLEX/TIP 2009/12/30 14:57 Posted by <!--r'i"z&i\n+#]]x juree23
http://sourceforge.net/projects/colladamaya/files/COLLADAMax%201.4.1%20plug-ins/ColladaMax_FREE_3.05C.exe/ColladaMax_FREE_3.05C.exe/download
저작자 표시 비영리 변경 금지

ultra shock라는 웹페이지

FLEX/TIP 2009/05/06 19:02 Posted by <!--r'i"z&i\n+#]]x juree23

ultra shock라는 웹페이지..

각종 컨포넌트의 데모를 볼수있고 다운받을수 있다~

와~잘만드는구나~하는 생각을 하게 되는 실력들~ㄷㄷㄷ

http://www.ultrashock.com

저작자 표시
TAG It

flex스킨 css모음입니다.정말 쓸만하군요~ㅎㅎ

FLEX/TIP 2009/04/23 15:15 Posted by <!--r'i"z&i\n+#]]x juree23
flex스타일을 한번 싹 바꿔보세요~ㅎㅎ
css스킨 모음입니다.~
http://www.scalenine.com/gallery/index.php
저작자 표시
TAG flash, Flex, It, 스킨

네모 던지기 입니다.

FLEX/TIP 2009/04/23 11:01 Posted by <!--r'i"z&i\n+#]]x juree23

.네모 던지기 입니다.

물리쪽 볼때 쓸모가 있겠습니다.

주소 : http://multi.kmcc.ac.kr/mozi/TestThrow/TestThrow.html


저작자 표시
TAG Flex, It

각종 프로그래밍 모음 - 총망라~

FLEX/TIP 2009/04/21 10:52 Posted by <!--r'i"z&i\n+#]]x juree23
각종 프로그래밍 모음 - 총망라~
완전 레어 아이템~~~홈페이지입니다. ~ㄷㄷㄷ
http://micropilot.tistory.com/1135?srchid=BR1http%3A%2F%2Fmicropilot.tistory.com%2F1135
저작자 표시
http://www.red5-recorder.com/chat-products.php
나하고 같은 생각들을 하는 사람들이 있다.
근데 퍼포먼스는 좀 떨어지는 느낌이다.
먼가 날림으로 만든 느낌이 많이 나는 그럼 프로그램들.....ㅡ.ㅡ;;;
저작자 표시
TAG It, red5

red5를 사용한 sip 폰을 개발하는 오픈소스 프로젝트...

FLEX/TIP 2009/04/20 17:51 Posted by <!--r'i"z&i\n+#]]x juree23
http://code.google.com/p/red5phone/
ㄷㄷㄷ
바로이거야~~
야호!!~~~
나랑 같은 생각을 하는 사람이 있다니...굳
저작자 표시

flex에서 record를 하는 방법이라..ㅋㅋㅋ

FLEX/TIP 2009/04/20 17:19 Posted by <!--r'i"z&i\n+#]]x juree23
flex에서 사용자 interact내용을 recording 하는 라이브러리~~~
http://code.google.com/p/flexmonkey/
저작자 표시
TAG It

ria용 바코드 식별 프로그램 ㄷㄷㄷ

FLEX/TIP 2009/04/20 16:17 Posted by <!--r'i"z&i\n+#]]x juree23
ria용 바코드 식별 프로그램입니다.
웹캠을 이용하여 바코드를 식별해 내는 신기한 페이지...
http://en.barcodepedia.com/download
저작자 표시
TAG It, 바코드

flex 마메 에뮬

FLEX/TIP 2009/04/10 18:27 Posted by <!--r'i"z&i\n+#]]x juree23
http://osflash.org/fc64
저작자 표시

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

Creating a video sharing web application with FLEX

FLEX/TIP 2008/06/14 11:11 Posted by <!--r'i"z&i\n+#]]x juree23
어도비 데브넷에 올려진 article입니다.

미디어서버와 플렉스 글구 php 와 서버측에서 인코딩 솔루션(Carbon Coder)을 이용한

구성과 사용 코드 입니다.

아시다시피 플래시에서 웹상에서 on2 vp6 코덱으로 인코딩이 안되기 때문에

이러한 방식으로 국내에서도 많이 사용하는 예가 될테인데여.

구상중이신 분들에게 도움이 되시길 바랍니다.

간단하게 설명하면, 플렉스로 짜여진 ui를 통해 원본 영상 파일을 php 와 결합하여 인코딩을 담당하는

서버로 보내고 해당 인코딩 서버에서 Carbon Coder를 통하여 on2 vp6 토덱의 flv를 변환하여

미디어서버측으로 전달하고, 최종적으로 클라이언트에게 스트리밍 서비스를 하는 형태입니다.

사용자 삽입 이미지

'FLEX > TIP' 카테고리의 다른 글

ria용 바코드 식별 프로그램 ㄷㄷㄷ  (0) 2009/04/20
flex 마메 에뮬  (0) 2009/04/10
Creating a video sharing web application with FLEX  (0) 2008/06/14
플래시명령어모음  (0) 2008/06/14
플래시9의 바이너리 소켓  (0) 2008/06/14
포토샵 배경색 바꾸기..  (0) 2008/06/14

플래시명령어모음

FLEX/TIP 2008/06/14 11:11 Posted by <!--r'i"z&i\n+#]]x juree23

----------------------------------------------------------------------------
// .....       주석 기호  
/* ..... */    주석 기호  
----------------------------------------------------------------------------
\r        // 리턴 코드  (ASC 13)
\n        // 줄바꿈 코드 (ASC 10)
\r\n      // 줄바꿈 코드  (2줄)
\t        // Tab 코드 (ASC 9)
\b        // Backspce 코드 (ASC 8)
&         // text 파일 데이타 구분 코드
----------------------------------------------------------------------------
산술연산자  +, -, *, /, %                 //  %  나머지를 구한다
대입연산자  =, +=, -=, *=, /=, %=         //  i+=4 와  i=i+4 는 같다
증감연산자  ++, --                        //  i++  와   i=i+1 는 같다  
비교연산자  ==, !=, >, <, >=, <=          //  !=  '같지않다' 로 해석
비교연산자  ===                           //  숫자 와 문자 구분
a = 5;    b = "5";                        //  숫자 5 와 문자 "5"
(a == b)                                  //  숫자 5 와 문자 "5"  는 같다 (true)
(a === b)                                 //  숫자 5 와 문자 "5" 는 틀리다 (false)
논리연산자  &&, ||, !                     //  그리고(AND), 또는(OR), 아니면(NOT)
조건연산자  ?    ( a ) ? b : c ;          //  a 조건이 맞으면 b 틀리면 c 실행
x=5;  y=10;  z=(x<6) ? x: y;   trace (z); //  z 은 5 이다
문자연산자  eq  ne  not  or  add          //  eq(==) ne(!=) not(!) or(||) add(+ 문자열의 연결)
( )                                       //  연산의 순서를 정한다
[ ]                                       //  배열을 지정한다
" "                                       //  문자를 지정한다
a=1+2;  trace(a);                         //  연산 결과 출력.  결과는 3
aaa=1;  set("ccc", aaa );  trace(ccc);    //  변수에 값을 지정.  결과는 1
aaa=1;  set("ccc", "aaa");  trace(ccc);   //  변수에 값을 지정.  결과는 aaa
set("ooo", getProperty ("ppp", _x ));     //  ppp x 좌표를  ooo 에 지정.
----------------------------------------------------------------------------
for (a=1; a<=10; a++)  { trace("a="+a); };             //  for  반복문
for (i=1; i<=120;  i+=12) { continue; };               //  for step 반복문
while(true) {  if(a == 0) { break; }; };               //  while  반복문
do { if(a == 0) { break; }; };  while(true);           //  do 반복문
if((n == 0) || (n >= 5)  &&  (n <= 55)  !(n=15)) {     //  if 조건문
 gotoAndPlay(1);
} else if (n == 2) {
 gotoAndPlay(2);
} else {
 gotoAndPlay(3);
};
num_ch = 3;                                             //  switch 조건문
switch (num_ch) {                                                
      case 1:    trace ( " case 1 tested true " );  break;
      case 2:    trace ( " case 2 tested true " );  break;
      default:    trace ( " no case tested true " );
};
----------------------------------------------------------------------------
function sumnumber(a,b,c) {  return(aaa= a+b+c); };    // 함수
sumnumber(1,2,3);
trace(aaa);
----------------------------------------------------------------------------
Math.abs(-1)              //  절대값.   결과는 1
Math.sin(1)               //  sin 값.   결과는 0.841470984807897
Math.cos(1)               //  cos 값.   결과는 0.54030230586814
Math.tan(1)               //  tan 값.   결과는 1.5574077246549
Math.log(2)               //  log 값.   결과는 0.693147180559945
Math.exp(1)               //  지수 값.    결과는 2.71828182845905
Math.sqrt(9)              //  제곱근 값.    결과는 3
Math.pow(2 , 4)           //  거듭제곱 값.    결과는 16
Math.ceil(1.1)            //  가까운 정수로 올림 값.    결과는 2
Math.ceil(1.5)            //  가까운 정수로 올림 값.    결과는 2
Math.floor(1.2)           //  가까운 정수로 내림 값.    결과는 1
Math.floor(1.7)           //  가까운 정수로 내림 값.    결과는 1
Math.round(1.2)           //  가까운 정수로 반올림 값.    결과는 1
Math.round(1.5)           //  가까운 정수로 반올림 값.    결과는 2
Math.max(1 , 2)           //  두 정수 중 큰 정수값.    결과는 2
Math.min(1 , 2)           //  두 정수 중 작은 정수값.    결과는 1
int(1.12 );               //  수치를 정수화.   결과는 1    
int(1.82 );               //  수치를 정수화.   결과는 1    
parseInt("3.2");          //  문자열을 정수화.  결과는 3    
parseInt("3.7");          //  문자열을 정수화.  결과는 3    
parseInt("5abc");         //  문자열을 정수화.  결과는 5
parseInt("abc5");         //  문자열을 정수화.  결과는 NaN    
parseInt("3E8", 16);      //  16 진수로 변환.   결과는 1000
parseInt("777", 8);       //  8 진수로 변환.   결과는 511
parseInt("1010", 2);      //  2 진수로 변환.   결과는 10
parseFloat("2")           // 문자열을 부동점 숫자로 변환.  결과는 2
parseFloat("2.4")         // 문자열을 부동점 숫자로 변환.  결과는 2.4
parseFloat("2.6abc")      // 문자열을 부동점 숫자로 변환.  결과는 2.6
Number("11")              //  문자열을 숫자로 변환.   결과는 11
Number("12.34")           //  문자열을 숫자로 변환.   결과는 12.34
Number("12.34abc")        //  문자열을 숫자로 변환.   결과는 NaN
sss = 123;  uuu = sss.toString();      // 숫자를 문자로변환.  결과는 123
ord("abc");                            //  ASCII 값.   결과는 97
s = "abc";   sss = s.charCodeAt(0);    //  1번째 ASCII 값 .   결과는 97
s = "abc";   sss = s.charCodeAt(1);    //  2번째 ASCII 값.    결과는 98
chr(65);                               //  ASCII 코드를 문자화.  결과는 A
String.fromCharCode(64,65,66);         //  ASCII 코드를 문자화.  결과는 @AB
Math.random();                         // 난수 발생.  결과는 0 - 1 사이의 소숫점 포함한 값
random(5);                             // 난수 발생.  결과는 0,1,2,3,4 중 하나
----------------------------------------------------------------------------
// delete 변수 또는 객체 ;             // 변수를 삭제  (var 로 선언된 변수는 삭제할 수 없다)
account = 1;   trace (account) ;                      // 결과는 1  
account = 1;   delete account;    trace (account);    // 결과는 undefined
delete onEnterFrame;                                  // 반복 실행 중지
----------------------------------------------------------------------------
typeof( );            // String, Number, MovieClip, Object, Boolean, Function 여부를 지정
trace (typeof(1));    // 결과는 Number
trace (typeof("1"));  // 결과는 String
trace (typeof(aaa));  // aaa가 무비클립 이라면  결과는 MovieClip
----------------------------------------------------------------------------
isFinite( );            // 숫자가 유한수이면 true 무한수거나 음의 무한대이면 false
trace (isFinite(aaa));  // aaa 값이 NaN 이라면 결과는 false
----------------------------------------------------------------------------
Mouse.show();           // 마우스 보임
Mouse.hide();           // 마우스 감춤
myClip.onMouseDown = function () {trace (" depth 무시"); };     // 마우스 누를 때
myClip.onMouseUp = function () {trace ("depth 무시"); };        // 마우스 눌렀다 놓을 때
myClip.onMouseMove = function () { trace ("depth 무시"); };     // 마우스 이동할 때
myClip.onPress = function () { trace ("depth 적용"); };         // 마우스 누를 때
myClip.onRelease = function () { trace ("depth 적용 "); };      // 마우스 눌렀다 놓을 때
myClip.onReleaseOutside = function () { trace ("Outside"); };   // 마우스 나가서 놓을 때
myClip.onRollOver = function () { trace ("Over called"); };     // 마우스 오버 때
myClip.onRollOut = function () { trace ("Out called"); };       // 마우스 아웃 때
----------------------------------------------------------------------------
// 단추무비클립 클릭후 액션 스크립트를 넣는다
on (press){           }  // 마우스 버튼을 누를 때   };  x  }  o
on (release){         }  // 마우스 버튼을 눌렀다 뗄 때
on (releaseOutside){  }  // 마우스 버튼을 누르고 나가서 뗄 때
on (rollOver){        }  // 마우스 포인트가 위로 올라올 때
on (rollOut){         }  // 마우스 포인트가 밖으로 나갈 때
on (dragOver){        }  // 누른 채로 밖으로 나갔다가 다시 들어올 때
on (dragOut){         }  // 마우스버튼을 누르고 바깥으로 드래그할 때
on (keyPress){        }  // 지정한 키를 누를 때
----------------------------------------------------------------------------
// 무비클립 클릭후 액션 스크립트를 넣는다
onClipEvent (load) {            }  // 시작 될때  };  x  }  o  
onClipEvent (unload) {          }  // 제거 될때
onClipEvent (enterFrame) {      }  // 트리거 될때
onClipEvent (mouseMove) {       }  // 마우스가 이동할 때
onClipEvent (mouseDown) {       }  // 마우스 클릭 시
onClipEvent (mouseUp) {         }  // 마우스 클릭 후
onClipEvent (keyDown) {         }  // 키를 누를 때
onClipEvent (keyUp) {           }  // 키를 눌렀다 놓을 때
onClipEvent (data) {            }  // loadVariables 또는 loadMovie 액션에서 데이터가 수신될 때
----------------------------------------------------------------------------
TextField.onChanged = function () { trace ("onChanged called"); };
// 텍스트 필드의 내용이 변경될 때
TextField.onSetFocus = function () { trace ("onSetFocus called"); };
// 텍스트 필드의 내용 부분에 마우스가 클릭 될 때
TextField.onKillFocus = function () { trace ("onKillFocus called"); };
// 텍스트 필드의 내용 바깥 부분에 마우스가 클릭 될 때
TextField.onScroller = function () { trace ("onScroller called"); };
// 텍스트 필드의 내용이 스크롤 될 때
----------------------------------------------------------------------------
myMovieClip.onData = function () { trace ("onData called"); };  
// 무비 클립이 loadVariables 또는 loadMovie 호출로부터 데이터를 받을 때
myMovieClip.onLoad =  function () { trace ("onLoad called"); };  
// 무비 클립이 load 호출로부터 데이터를 받을 때
myMovieClip.onUnLoad =  function () { trace ("onUnLoad called"); };  
// 무비 클립이 Unload 때
myMovieClip.stop()  
// 작업 중지
----------------------------------------------------------------------------
myDate = new Date();                               // 날짜 로드
myDate = new Date (년,월,일,시,분,초);             // 날짜 지정
yyyy = (myDate.getFullYear() + "-" + (myDate.getMonth() + 1) + "-" + myDate.getDate());
tttt = (myDate.getHours()+ " :" + myDate.getMinutes() + " :" +myDate.getSeconds());
----------------------------------------------------------------------------
_root.onEnterFrame = function() {   };             // 메인화면에서 프레임 반복
onEnterFrame = function() {   };                   // 심볼화면에서 프레임 반복
----------------------------------------------------------------------------
tmtm = getTimer();          
onEnterFrame = function() {
  if ( (getTimer()-tmtm) >= 500 ) { tmtm=getTimer(); trace (tmtm); };   // 0.5초후 반복실행
  if ( (getTimer()-tmtm) >= 1000 ) { tmtm=getTimer(); trace (tmtm); };  // 1초후 반복실행
  if ( (getTimer()-tmtm) >= 2000 ) { tmtm=getTimer(); trace (tmtm); };  // 2초후 반복실행
};
----------------------------------------------------------------------------
onEnterFrame = function() {                                
   nr += 1;  if (nr > 5 )  {  delete  onEnterFrame;  };           // 5번 반복실행후 중지
   trace (nr);
};
----------------------------------------------------------------------------
createTextField ("ins", 1, 100, 100, 50, 50)
ins.border = true;
function callback() {
   ins._x += 5;
   if ( ins._x > 400 ) { clearInterval( intervalID );  };      // 중지 (clearInterval)
}
var intervalID;
intervalID = setInterval( callback, 100 );             //  0.1초후 반복실행 (setInterval)
----------------------------------------------------------------------------
"script.as"         // script.as 파일 넣기 (액션 스크립트 txt 파일)
----------------------------------------------------------------------------
System.useCodepage = true;   // 한글 깨짐 방지
----------------------------------------------------------------------------
trace(targetPath(this));     // 대상 패스를 반환.  결과는 _level0.instance1 로 표시
trace(this.valueOf());       // 결과는 _level0 로 표시
----------------------------------------------------------------------------
trace(this.getBytesLoaded());  // 무비클립의 로드된 바이트 수를 알려준다.
trace(this.getBytesTotal());   // 무비클립의 전체용량 바이트 수를 알려준다.
----------------------------------------------------------------------------
getURL("C:/")                                          // 탐색기 열기
getURL("C:/Windows/NOTEPAD.EXE");   };                 // 메모장 열기
getURL("C:/Program Files/Accessories/WORDPAD.EXE");    // 워드패드 열기
getURL("C:/Program Files/Accessories/MSPAINT.EXE");    // 그림판 열기
getURL("C:/Windows/CALC.EXE");                         // 계산기 열기
getURL ("aaa.exe");                                    // aaa.exe 파일 열기 (message)
getURL ("aaa.txt", "_self");                           // aaa.txt 파일 열기
getURL ("movie.html", "_self");                        // movie.html 파일 열기
getURL ("http://www", "_blank");                    // http://www 를 새로운 창으로 열기
----------------------------------------------------------------------------
Stage.showMenu = "true";        // 스크린 메뉴 보임
Stage.showMenu = "false";       // 스크린 메뉴 감춤  
Stage.scaleMode = "noScale";    // 화면의 사이즈를 고정
Stage.align = "TL";             // 화면의 정렬을 T(위) L(왼쪽)
           //  "T" 위 가운데    "B" 아래 가운데    "L" 가운데 왼쪽    "R" 가운데 오른쪽
           //  "TL" 위쪽 왼쪽   "TR" 위쪽 오른쪽   "BL" 아래쪽 왼쪽   "BR" 아래쪽 오른쪽
Stage.height      // 픽셀로 표시된 스테이지의 높이
Stage.width       // 픽셀로 표시된 스테이지의 넓이
----------------------------------------------------------------------------
_root.createEmptyMovieClip("box",1);      // 스테이지 테두리 주기
with (_root.box) {  moveto(1, 1);   linestyle(10, 0x00cc00, 100);
    lineto(stage.width, 1);     lineto(stage.width, stage.height);
    lineto(1, stage.height);    lineto(1, 1);   };
----------------------------------------------------------------------------
fscommand("showmenu", true);      // 스크린 메뉴 보임
fscommand("showmenu", false);     // 스크린 메뉴 감춤
fscommand("allowscale", true);    // 스크린 크기에 따라 무비의 크기도 변함
fscommand("allowscale", false);   // 스크린 크기에 따라 무비의 크기도 안변함
fscommand("fullscreen", true);    // 풀 스크린 (esc키 누르면 해제)
fscommand("fullscreen", false);   // 풀 스크린을 원래의 크기로 만든다
fscommand("trapallkeys", true); // 키보드 키 사용할 수 없음 (풀 스크린 일때 esc키 먹통)
fscommand("trapallkeys", false);  // 키보드 키 사용할 수 있음
fscommand("quit");                // 스크린 닫기
fscommand ("exec", "a.exe");      // a.exe 파일 실행 (no message)
   플래시 무비(exe) 가 위치하는 폴더안에 fscommand 라는 하위 폴더를 만들고
   fscommand 디렉토리에  a.exe 가 있을때 플래시 무비(exe)를 실행하면 a.exe파일 실행
----------------------------------------------------------------------------
// getURL 로 javascript 사용하기
var hello = "Hello, World";
getURL("javascript:alert(\" "+ hello + "  \")");   // 메세지 띄우기
getURL("javascript:window.self.close()");          // 윈도우창 닫기
getURL("javascript:window.external.AddFavorite('http://','가')" );    //즐겨찾기 추가
----------------------------------------------------------------------------
// fscommand 로 javascript 사용하기
1.  fscommand ("messagebox", "This is a Flash.");   // aaa.swf flash script
2.  파일메뉴 - 제작설정 - 포맷 (HTML체크) - HTML (템플릿: with FSCommand 체크)
3.  파일메뉴 - 제작 (파일명은 aaa.swf) -  aaa.html 파일이 디렉토리에 만들어 진다
4.  aaa.html 파일을 열고  function aaa_DoFSCommand(command, args) {  아래에
      if (command == "messagebox") {  alert(args);  };   을 적고 저장 한다
5.  aaa.html 실행 (실행후 제작설정 해제)
----------------------------------------------------------------------------
// fscommand 로 javascript 의 변수값 불러오기
1. fscommand ("search", TextFieldvar);     // aaa.swf flash script
2. if (command == "search") {              // aaa.html script
       EEEfind = "FFFFFFFF";
       window.document.aaa.SetVariable("TextFieldvar", EEEfind) ;
       return TextFieldvar;
    };
3. aaa.html 실행
----------------------------------------------------------------------------
_root.loadMovie("a.swf");            // swf 파일 불러오기
_root.bbb.loadMovie("a.swf")         // swf 를 메인에 있는 bbb무비클립에 불러오기
_root.loadMovie("a.swf", 1);         // swf 를 레벨1로 불러오기 (2 는 1를  screen over)
_root.loadMovie("aaa.jpg");          // jpg 파일 불러오기
_root.bbb.loadMovie("aaa.jpg"); // jpg 파일을 메인에 있는 bbb무비클립에 불러오기
unloadMovie (1);                     // 레벨 1에 로드된 무비를 언로드
unloadMovie ("a.swf");               // 현재 무비에 로드된 a.swf 무비를 언로드
_root.bbb.unloadMovie();    // 메인 타임라인의 bbb 무비클립에 로드된 무비를 언로드
this["bbb"].unloadMovie();  // 현재 타임라인의 bbb 무비클립에 로드된 무비를 언로드
sss.bbb.unloadMovie();   // sss 심볼 타임라인의 bbb 무비클립에 로드된 무비를 언로드
----------------------------------------------------------------------------
button.onPress = function() { _root.loadMovie("aaa.swf"); }  // aaa.swf 실행중 초기화 하기
----------------------------------------------------------------------------
_root["ball_"+counter]._x = 11;       //  메인 화면의 클립 좌표
this["ball_"+counter]._x = 11;        //  현재 화면의 클립 좌표
aaa["ball_"+counter]._x = 11;         //  aaa 심볼 화면의 클립 좌표
----------------------------------------------------------------------------
this.createEmptyMovieClip("aaa", 1);             //  무비클립 생성 (2 는 1를 screen over)
this.duplicateMovieClip (aaa, bbb, 1);           //  aaa 무비클립  bbb 로 복사
this.bbb.removeMovieClip();                      //  bbb 무비클립 삭제
myClip._visible = true;                   //  클립 보임
myClip._visible = false;                  //  클립 감춤
myClip.swapDepths(100);               //  클립 깊이 100 으로 지정 (2 는 1를 screen over)
myClip.swapDepths(otherClip);                    //  클립 깊이 otherClip 과 바꿈
for (i=1; i<=360; i++)  {                        //  클립 복사
     duplicateMovieClip (ins1, "mc"+i, i);
     setProperty ("mc"+i, _x, random(300));
     setProperty ("mc"+i, _y, random(300));
     setProperty ("mc"+i, _alpha, random(300));
     setProperty ("mc"+i, _xscale, 150);
     setProperty ("mc"+i, _yscale, 150);
};  
for (i=1; i<=360; i++)  {                        //  클립 복사
     duplicateMovieClip (ins1, "mc"+i, i);
     this["mc" + i]._x = i;
     this["mc" + i]._y = i;
};  
for (i=1; i<=50; i++)  {                          // 클립 이동
      this["mc_"+i]._x += 10;
      this["mc_"+i]._y += 10;
};  
for (i=1; i<=360; i++)  {                         // 클립 삭제
     this["mc" + i].removeMovieClip ();
};  
----------------------------------------------------------------------------
setProperty ("mv", _x, 150);           // mv 무비클립 x좌표 속성 변경
myMovieX = getProperty( mv, _x);       // mv 무비클립 x좌표 속성 읽기
trace(myMovieX);
----------------------------------------------------------------------------
_alpha              알파값(%)
_currentframe       현재재생중인 프레임()
_droptarget         드래그 앤드드롭 할때 놓는 타깃위치(name)
_framesloaded       로드된 프레임수()
_height             높이()
_name               인스턴스(string)
_rotation           회전값()
_soundbuftime       사운드버퍼링 시간(기본값 5초:)
_totalframes        총프레임수()
_url                다운로드한 URL(string)
_visible            보인다,안보인다 (true,false)
_width              가로길이()
_x                  x좌표()
_y                  y좌표()
_xmouse             마우스x좌표()
_ymouse             마우스y좌표()
_xscale             x배율(%)
_yscale             y배율(%)
----------------------------------------------------------------------------
_root.a.play;                    //  메인에 있는 a무비클립  프레임 재생
_root.a.stop;                    //  메인에 있는 a무비클립  프레임 중지
play();                          //  stop으로 정지된 현재타임라인의 프레임 재생
stop();                          //  현재타임라인의 프레임 중지
gotoAndPlay(1);                  //  현재 Scene의 1프레임 재생
gotoAndPlay("a");                //  현재 Scene의 Label명 a 재생
gotoAndPlay("Scene 2", "c");     //  Scene 2의 Label명 c 재생
a.gotoAndPlay(1);                //  a무비클립의 1프레임 재생
gotoAndStop(1);                  //  현재 Scene의 1프레임 중지
nextScene();                     //  다음 장면의 프레임 1로 보내고 중지
prevSecne();                     //  이전 장면의 프레임 1로 보내고 중지
nextFrame();                     //  다음 프레임으로 보내고 중지
prevFrame();                     //  이전 프레임으로 보내고 중지
toggleHighQuality ();            //  저해상도와 고해상도 간을  전환
updateAfterEvent();              //  화면을 갱신 (onClipEvent 핸들러 내에서만 사용)
                                  //  (onMouseDown,  onMouseUp,  onMouseMove)
----------------------------------------------------------------------------
tellTarget ("../a") { nextFrame(); } //  ../a 무비클립을 호출후 다음 프레임 재생
if (_framesloaded = 10) {  }         // 만약 무비의 10프레임이 로드되면
----------------------------------------------------------------------------
// with 문
for (i=0; i<1000; i++) {
    with (aaa[i]) {
       _x = Math.floor(Math.random() * 500);
       _y = random(500);
       _rotation = random(360);
   }
}
// tellTarget 문 (속도빠름)
for (i=0; i<1000; i++) {
    tellTarget (aaa[i]) {
       _x = Math.floor(Math.random() * 500);
       _y = random(500);
       _rotation = random(360);
    }
}
----------------------------------------------------------------------------
aaa = new Array();              // 배열 초기화    
aaa = new Array("1","2","3");   // 배열값 넣기
bbb = ["Sun","Mon","Tue"];      // 배열값 넣기
aaa[1] = "abc";                 // 배열값 변환  ( "2" 가 "abc" 로 변환)
aaa[0] = "Jan" ;  aaa[1] = "Feb" ;  aaa[2] = "Mar" ;         // 배열값 변환
aaa[3] = "Apr"                  // 배열 추가 (aaa 값은  "Jan,Feb,Mar,Apr" )
ccc = aaa.concat(bbb);          // 배열 합침 (ccc 값은  "Jan,Feb,Mar,Apr,Sun,Mon,Tue" )
ddd = ccc.join("/");            // ,를  /로 변환  (ddd 값은  "Jan/Feb/Mar/Apr/Sun/Mon/Tue" )
ddd = ccc.length;               // 배열값 갯수 (ddd 값은  7 )
ddd = ccc.slice(2,4);           // 배열값 읽기 (ddd 값은  "Mar,Apr" )
eee = ccc.push("z","zz");       // 배열추가후  배열값 갯수 (eee 값은  9 )
                                 //  (ccc 값은 "Jan,Feb,Mar,Apr,Sun,Mon,Tue,z,zz"   로 변함)
eee = ccc.pop();                // 마지막 배열 분리후 값  (eee 값은  "zz" )
                                 //  (ccc 값은  "Jan,Feb,Mar,Apr,Sun,Mon,Tue,z"   로 변함)
eee = ccc.shift();              // 첫번째 배열 분리후 값 (eee 값은  "Jan" )
                                 //  (ccc 값은  "Feb,Mar,Apr,Sun,Mon,Tue,z"   로 변함)
eee = ccc.reverse();            // 배열값 순서바꿈 (eee 값은  "z,Tue,Mon,Sun,Apr,Mar,Feb" )
                                 //  (ccc 값도  "z,Tue,Mon,Sun,Apr,Mar,Feb"   로 변함)
eee = ccc.splice(2,5,"x","xx","xxx");  // 배열값 읽기후  변환  (eee 값은  "Mon,Sun,Apr,Mar,Feb" )
                                        //  (ccc 값은  "z,Tue,x,xx,xxx"   로 변함)
eee = ccc.unshift("1","2");     // 첫번째 배열추가후  값  (eee 값은  "7" )
                                 //  (ccc 값은  "1,2,z,Tue,x,xx,xxx"   로 변함)
sss = new Array(1,2,3);         // 숫자 배열값 넣기
uuu = sss.toString();           // 문자로변환.  결과는 1,2,3
vvv = uuu.toLowerCase();        // 대문자를  소문자로 변환.  원래 값은 변경되지 않음      
vvv = uuu.toUpperCase();        // 소문자를  대문자로 변환.  원래 값은 변경되지 않음  
xxx = Number("111")             //  숫자로 변환.   결과는 111
xxx = Number("aaa")             //  숫자로 변환.   결과는 NaN
xxx = Number(true)              //  숫자로 변환.   결과는 1
xxx = Number(false)             //  숫자로 변환.   결과는 0
----------------------------------------------------------------------------
cliparray = new Array();                     // 무비클립을 배열로 저장하기
for (a=1; a<=3; a++)  {
     cliparray[a] =  _root["clip"+a];
     cliparray[a].x =  _root["clip"+a]._x;
     cliparray[a].y =  _root["clip"+a]._y;
     trace(cliparray[a].x);
     trace(cliparray[a].y);
}
----------------------------------------------------------------------------
myString = new String();                           // 문자 변수초기화    
myString = new String("가나다");                   // 문자 넣기
tet="가나다";   myString = new String(tet);        // tet  변수 넣기
text0=myString.charAt(0);                          // text0 값은 "가"  -  1개 읽기
text1=myString.charAt(1);                          // text1 값은 "나"  -  1개 읽기
text2=myString.charAt(2);                          // text2 값은 "다"  -  1개 읽기
text3=myString.concat("라마","바사","다");     // text3 값은 "가나다라마바사다"  -  추가
text4=text3.substr(2,4);                           // text4 값은 "다라마바"  -  여러개 읽기
text5=text3.substring(2,4);                        // text5 값은 "다라"  -  여러개 읽기
text6=text3.slice(2,4);                            // text6 값은 "다라"  -  여러개 읽기
text7=myString.charCodeAt(1);                      // text7 값은  45208  - 문자를 코드화
text8="a" + String.fromCharCode(64) + "m";         // text8 값은 "a@m"  - 코드를 문자화
text9= text3.indexOf("다");                        // text9 값은 2  -  문자위치
text10= text3.lastIndexOf("다");                   // text10 값은 7  -  마지막 문자위치
text11= text3.length;                              // text11 값은 8  -  문자길이
text12= text3.split("나");                         // text12 값은 "가,다라마바사다"  -  문자분리
text13= text6.concat(text3);                 // text13 값은 "다라가나다라마바사다"  -  문자합침
text14= text13.substr((text13.length-1),1);        // text14 값은 "다"  -  마지막 문자 읽기
sss = myDate.toString();  day = sss.substring(0,3);     // 문자로변환        
----------------------------------------------------------------------------
// aaa 문장을 bbb 배열로 저장하기                  // 문장을 배열로 저장하기
// 결과는 bbb[0]="a" bbb[1]="b" bbb[2]="c" bbb[3]="d" bbb[4]="e"
aaa = "a b c d e";
aaalen = aaa.length;
bbb = new Array();
for (a=0; a<=aaalen; a++)  { bbb[a] = "";  };
bbbno = 0;   bbbchr = "";
for (a=0; a<=aaalen; a++)  {
if ( aaa.charAt(a) == " " ) {  bbb[bbbno] = bbbchr;   bbbno += 1;   bbbchr = "";  
} else { bbbchr += aaa.charAt(a);   };
};
for (a=0; a<=bbbno; a++)  {  trace( "*" + bbb[a] + "*" )   };  
----------------------------------------------------------------------------
for (a=1; a<=22; a++) {                                       // 텍스트 필드 글자속성
        this["k"+(a)].textColor=0xff0000;
        this["k"+(a)].border=true;
        this["k"+(a)].borderColor=0xff0000;
        this["k"+(a)].background=true;
        this["k"+(a)].backgroundColor=0xffffff;
};
----------------------------------------------------------------------------
TextField.removeTextField();                                   // 텍스트 필드 삭제
----------------------------------------------------------------------------
createTextField ("instanceName", depth, x, y, width, height)   // 텍스트 필드 생성
      instanceName 새 텍스트 필드의 인스턴스 이름
      depth 새 텍스트 필드의 깊이를 지정하는 양의 정수 (2 는 1를  screen over)
      x 새 텍스트 필드의 x 좌표를 지정하는 정수
      y 새 텍스트 필드의 y 좌표를 지정하는 정수
      width 새 텍스트 필드의 넓이를 지정하는 양의 정수
      height 새 텍스트 필드의 높이를 지정하는 양의 정수
instanceName.type = "dynamic";      // 텍스트 필드의 기본 속성  (dynamic 또는 input)
instanceName.autoSize = "false";

// (글자수에 맞게 테두리 크기 자동 조절 true false center right)
instanceName.border = false;                 // (테두리)  
instanceName.borderColor = 0xff0000;         // (테두리 색상)  
instanceName.background = false;             // (배경)
instanceName.backgroundColor=0xffffff;       // (배경 색상)
instanceName.textColor = 0xff0000;           // (글자 색상)
instanceName.multiline = false;              // (한줄  또는  여러줄)
instanceName.selectable = true;              // (텍스트 필드를 선택할 수 있는지 여부)
instanceName.maxChars = null;

//(사용자가 입력할 수 있는 최대 문자 수) (null 이면 무한대)
instanceName.length = 0;                     // (글자 수)
instanceName._name = "";                     // (인스턴스 이름)
instanceName.variable = "";                  // (변수 이름)
instanceName.html = false;                   // (html 태그 사용 여부)
instanceName.htmlText = "";                  // (html 태그)
instanceName.wordWrap = true;                // (자동 줄바꿈 )
instanceName._x = 0;                         // (x 좌표)
instanceName._y = 0;                         // (y 좌표)
instanceName._width  = 0;                    // (넓이)
instanceName._height = 0;                    // (높이)
instanceName._xscale = 100;                  // (넓이 조절 %)
instanceName._yscale = 100;                  // (높이 조절 %)
instanceName.restrict = "";                  // (입력할 수 있는 문자 세트)
instanceName.embedFonts = false;             // (장치 글꼴 사용 여부)
instanceName.password = false;               // (****표시)
instanceName._visible =  true;

 // (보임/안보임.  false로 설정된 텍스트 필드는 사용할 수 없음)
instanceName.scroll = 0;                     // (현재 스크롤 수직 위치)
instanceName.hscroll = 0;                    // (현재 스크롤 수평 위치)
instanceName.maxscroll = 0;                  // (TextField.scroll의 최대값)
instanceName.maxhscroll = 0;                 // (TextField.hscroll의 최대값)
instanceName.text = "";                      // (글자)

myformat = new TextFormat();                 // 텍스트 필드의 기본 TextFormat 속성
myformat.align = "left";                     // (단락의 정렬 )
myformat.blockIndent  = 0;                   // (왼쪽 여백에서 블록 들여쓰기. 포인트 단위)
myformat.indent  = 0;       // (왼쪽 여백에서 단락 들여쓰기. 각 단락의 첫 줄에만 적용)
myformat.bold = false;                       // (텍스트가 굵은체로 표시되는지 여부)
myformat.bullet = false;                     // (텍스트가 불릿 목록에 있는지 여부 * 표시)
myformat.color  = 0x000000;                  // (텍스트의 색상)
myformat.font = "Times New Roman";           // (텍스트의 글꼴)
myformat.italic = false;                     // (텍스트가 기울임체로 표시되는지 여부)
myformat.leading  = 0;                       // (줄 사이의 행간 세로 간격)
myformat.leftMargin  = 0;                    // (단락의 왼쪽 여백 포인트 단위)
myformat.rightMargin  = 0;                   // (단락의 오른쪽 여백 포인트 단위)
myformat.tabStops = [ ];                      // (사용자 정의 탭 중지를 지정 // (empty array))
myformat.target = "";                        // (브라우저에서 하이퍼링크가 표시되는 창)
myformat.size = 12;                          // (텍스트의 크기)
myformat.underline = false;                  // (텍스트에 밑줄이 그어졌는지 여부)
myformat.url = "";                           // (텍스트가 링크되는 URL)

instanceName.text = "this is my test field \r aaa" + "bbb";    // 텍스트에 내용 넣기
instanceName.setTextFormat(myformat);        //  텍스트 필드의 TextFormat  변경
----------------------------------------------------------------------------
instanceName.restrict = "A-Z 0-9";           // 대문자, 공백, 숫자만 입력할 수 있음
instanceName.restrict = "^a-z";              // 소문자를 제외한 모든 문자를 입력
instanceName.restrict = "A-Z^Q";             // 대문자 Q를 제외한 대문자만 입력
instanceName.restrict = "\\-"                // 마이너스 부호 (-) 만 입력
----------------------------------------------------------------------------
aa.html = true;                              // html 태그 사용 (b)
aa.htmlText = " this is bold text ";
----------------------------------------------------------------------------
aa.html = true;                              // html 태그 사용 (table)
aa.htmlText = "";
aa.htmlText += " 테이블의 텍스트1  ";
aa.htmlText += " 테이블의 텍스트2 ";
aa.htmlText += " 이동 하기 ";
----------------------------------------------------------------------------
function Func(arg){  trace ("You clicked me!  Argument was "+arg);   };  
aa.html = true;                              // html 태그 사용 (asfunction)
aa.htmlText = " Click ";  
----------------------------------------------------------------------------
on (release) {TextField.hscroll += 1; }      // 텍스트를 수평으로 스크롤
on (release) {TextField.scroll += 1;  }      // 텍스트를 수직으로 스크롤
x = TextField.maxscroll;                     // 총 줄수를 표시
----------------------------------------------------------------------------
TextField.onSetFocus = function(){           // 텍스트 입력 (텍스트필드 속성이 입력일때)
    this.text=" input data ";                 // 마우스 클릭시 내용 자동 입력
};
----------------------------------------------------------------------------
// aaa 와 bbb 란 두개의 텍스트 필드를 만든후
aaa.text="1234567890"
Selection.setFocus("aaa");              // 텍스트 모든 문자 포커스. 문자 없으면 커서 깜박
Selection.setSelection(2,5);            // (시작점, 끝점).  결과는 "345" 포커스
bbb.text = Selection.getBeginInde

'FLEX > TIP' 카테고리의 다른 글

flex 마메 에뮬  (0) 2009/04/10
Creating a video sharing web application with FLEX  (0) 2008/06/14
플래시명령어모음  (0) 2008/06/14
플래시9의 바이너리 소켓  (0) 2008/06/14
포토샵 배경색 바꾸기..  (0) 2008/06/14
FLEX,FLASH 좋은 사이트 소개  (0) 2008/06/14

플래시9의 바이너리 소켓

FLEX/TIP 2008/06/14 11:10 Posted by <!--r'i"z&i\n+#]]x juree23
as3.0에서 공식적으로 바이너리 소켓을 지원하게되면서

POP3 ,SMTP ,IMAP 그리고 뉴스서버지원에다가 VNC서버까지도 지원합니다.

정말 무한 도약인데요 플래시 자체로 모든 기능이 갖춰지는 플랫폼이 거의 완성단계에 오는것 같군요.

package {



import flash.display.Sprite;

import flash.events.*;

import flash.net.Socket;



public class Socket_sample extends Sprite{



private var socket:Socket;



public function Socket_sample(){

socket =new Socket();

socket.addEventListener( Event.CONNECT, onConnect);

socket.connect("localhost",2000);//정책상 1024 이상의 포트만 해야함

}

private function onConnect(event:Event):void{

trace("소켓이 연결되었음");

}



}



}



여기까진 기존 소켓과 크게 달라보이지 않는데

socket.writeBytes(byteArray,0,byteArray.length);메소드로 패킷을 기록할수있습니다.



UTF 패킷은 writeUTF(), writeUTFbytes() 로 기록할수있습니다.

재믿는것은 writeMulitByte()란 메소드인데

주로 문자데이터를 전송할때 한글체계같은 2바이트 문자라든가 기타 비정규적인 문자일경우에 쓸수 있습니다.

socket.writeMultiByte("example","unicode");



ex)POP3서버로 문자를 전송할때

socket.writeUTFBytes("팝3 짱이닷"\n); //\n은 팝3에서 뉴라인으로 인식



자 이렇게만 해놓으면 전송이 되는것은 아니고

이제 모든 소켓 데이터 오브젝트를 구성했으면 실제로 전송을 하라는 갱신명령어인

socket.flush();를 하면됩니다. 이 플러시는 실제전송이 아닌 버퍼에 미리 새겨넣게됩니다.



그런데 분명 위에서는 xmlsocket의 인스턴스이므로

xmlSocket.send(xml)이런식으로 send를 통해서 버퍼의 내용들을 전송합니다.



전송이 된다면 받을수도있어야되는데

readBoolean():Boolean ,readByte():init ,readDouble():Number ,readFloat():Number ,readInt():int

readUnsignedByte():unit, readUnsignedInt():unit , readUnsigedShort():uint , readUTF():String

'FLEX > TIP' 카테고리의 다른 글

Creating a video sharing web application with FLEX  (0) 2008/06/14
플래시명령어모음  (0) 2008/06/14
플래시9의 바이너리 소켓  (0) 2008/06/14
포토샵 배경색 바꾸기..  (0) 2008/06/14
FLEX,FLASH 좋은 사이트 소개  (0) 2008/06/14
FLEX에서 팝업효과  (0) 2008/06/14

포토샵 배경색 바꾸기..

FLEX/TIP 2008/06/14 11:10 Posted by <!--r'i"z&i\n+#]]x juree23
Ctrl+Backspace
alt+Backspace
를 누르면 배경/전경으로 된것으로
그림의 배경색이 바뀐다.

'FLEX > TIP' 카테고리의 다른 글

플래시명령어모음  (0) 2008/06/14
플래시9의 바이너리 소켓  (0) 2008/06/14
포토샵 배경색 바꾸기..  (0) 2008/06/14
FLEX,FLASH 좋은 사이트 소개  (0) 2008/06/14
FLEX에서 팝업효과  (0) 2008/06/14
Flex, PHP와 MySQL를 이용한 간단 메모장 만들기  (0) 2008/06/14

FLEX,FLASH 좋은 사이트 소개

FLEX/TIP 2008/06/14 11:09 Posted by <!--r'i"z&i\n+#]]x juree23
http://cafe.naver.com/flexcomponent.cafe

'FLEX > TIP' 카테고리의 다른 글

플래시9의 바이너리 소켓  (0) 2008/06/14
포토샵 배경색 바꾸기..  (0) 2008/06/14
FLEX,FLASH 좋은 사이트 소개  (0) 2008/06/14
FLEX에서 팝업효과  (0) 2008/06/14
Flex, PHP와 MySQL를 이용한 간단 메모장 만들기  (0) 2008/06/14
플렉스에서 Event 처리  (0) 2008/06/14

FLEX에서 팝업효과

FLEX/TIP 2008/06/14 11:09 Posted by <!--r'i"z&i\n+#]]x juree23

public function popupEvent():void
   {
    var pop:W_DEPT  = W_DEPT(PopUpManager.createPopUp(this,W_DEPT,true));
           
       pop.width = 400;
       pop.height =  500;
       PopUpManager.centerPopUp(pop);
        
   }
-------------------------------------------------

W_DEPT.mxml

-------------------------------------------------

<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="onCreationComplete()"
   showCloseButton="true"  close="PopUpManager.removePopUp(this)" width="354" height="470">

.....

</mx:TitleWindow>

'FLEX > TIP' 카테고리의 다른 글

포토샵 배경색 바꾸기..  (0) 2008/06/14
FLEX,FLASH 좋은 사이트 소개  (0) 2008/06/14
FLEX에서 팝업효과  (0) 2008/06/14
Flex, PHP와 MySQL를 이용한 간단 메모장 만들기  (0) 2008/06/14
플렉스에서 Event 처리  (0) 2008/06/14
제목 | FLEX에서 타이머 사용법  (0) 2008/06/14

Flex, PHP와 MySQL를 이용한 간단 메모장 만들기

FLEX/TIP 2008/06/14 11:09 Posted by <!--r'i"z&i\n+#]]x juree23

-출처 장창학(nooreestyle)-

 

Flex, PHP와 MySQL로 간단하게 HTTPService를 구현해봤습니다. 초보용입니다. 대충 이렇게도 만들수 있다는 정도로만 봐주세요.

 

 

1. 테이블의 생성 (memo.sql)


CREATE TABLE memo (
  userid int(10) unsigned NOT NULL auto_increment,
  username varchar(30) NOT NULL default '',
  contents text,
  dates varchar(50) NOT NULL default '',
  PRIMARY KEY (userid)
);

 

총 4개의 필드를 이용합니다. 자동으로 증가하는 게스글수인 userid, 사용자명인 username, 메모내용인 contents, 그리고 마지막으로 메모작성날짜인 dates로 구성됩니다.

 

2. PHP코드 (memo.php)

 

<?php
   Define( "DATABASE_SERVER", "localhost" );
   Define( "DATABASE_USERNAME", "DB계정" );
   Define( "DATABASE_PASSWORD", "DB계정패스워드" );
   Define( "DATABASE_NAME", "DB명" );
 
   //DB접속
   $mysql = mysql_connect(DATABASE_SERVER, DATABASE_USERNAME, DATABASE_PASSWORD);mysql_select_db( DATABASE_NAME );
 
   if( $_POST["username"] AND $_POST["contents"] AND $_POST["dates"])
   {

     //메모 입력
     $Query = "INSERT INTO memo VALUES ('', '".$_POST['username']."', '".$_POST['contents']."', '".$_POST['dates']."')";
     $Result = mysql_query( $Query );
   }

   //memo테이블 데이터 불러오기:가장 나중에 입력값 순서로 가져옴
   $Result = mysql_query("SELECT * from memo order by userid desc");
  
   //XML문서의 반환시작
   $Return .= "<users>";
  
   //게시글수(객체수) 만큼 구하기
   while ( $memo = mysql_fetch_object( $Result ) )
   {
     $Return .= "
         <user>
         <userid>".$memo->userid."</userid>
         <username>".$memo->username."</username>
         <contents>".$memo->contents."</contents>
         <dates>".$memo->dates."</dates>
         </user>";
   }

   $Return .= "</users>";

   //검색결과를 메모리에서 제거, 그리고 결과를 찍어주삼~
   mysql_free_result( $Result );
   print ($Return)
 ?>

 

3. MXML코드 (memo.mxml)

 

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="
http://www.adobe.com/2006/mxml" xmlns="*" layout="absolute" creationComplete="memoRequest.send();initDate();" width="100%" height="100%" initialize="System.useCodePage=true" backgroundGradientColors="[#515f6f, #c0c0c0]">
     
   <mx:HTTPService id="memoRequest" url="memo.php" useProxy="false" method="POST">
      <mx:request xmlns="*">
         <username>{username.text}</username><contents>{contents.text}</contents><dates>
          {dates.text}</dates>
      </mx:request>
   </mx:HTTPService>
  
   <mx:Script>
   <![CDATA[
        import mx.controls.Alert;
        private function CheckReg():void {
         if(username.length==0) {
            Alert.show("Input your name !","Alert");
            username.focusEnabled=true;
         } else if(contents.length==0) {
          Alert.show("Input your message !","Alert");
            contents.focusEnabled=true;
         } else {
          memoRequest.send()
          username.text="";
          contents.text="";
         }
        } 
   ]]>    
   </mx:Script>

   <mx:Script>
     <![CDATA[       
         private var today:Date;
     
         private function initDate():void {
             today = new Date();       
             dates.text=DateDisplay.format(today);
         }
     ]]>
   </mx:Script> 
  
   <mx:DateFormatter id="DateDisplay" formatString="MMMM D, YYYY"/> 
   <mx:Form y="22" width="633" horizontalCenter="0" height="178">
 <mx:Panel width="600" height="140" layout="absolute" horizontalCenter="-68.5" title="메모입력" fontSize="12">
  <mx:Label x="10" y="12" text="이름" fontSize="12" enabled="true" fontFamily="Arial" fontWeight="bold"/>
  <mx:TextInput x="49" y="10" id="username"  width="181"/>
  <mx:Label x="10" y="43" text="메모" fontSize="12" enabled="true" fontFamily="Arial" fontWeight="bold"/>
  <mx:TextInput x="49" y="40" width="521" id="contents" />
  <mx:TextArea id="dates" x="410" height="21" y="11" textAlign="right" color="#000000" fontSize="10" fontFamily="Verdana" borderColor="#ffffff" editable="false"/>
     <mx:Button label="입력" right="10" bottom="8" fontSize="12" click="CheckReg();"/>
 </mx:Panel>
   </mx:Form>
    
   <mx:Panel width="600" height="400" layout="absolute" title="메모보기" horizontalCenter="0" y="208" fontSize="12">
   <mx:DataGrid id="dgMemoRequest" dataProvider="{memoRequest.lastResult.users.user}"  width="560" height="260" horizontalCenter="0" top="10" fontSize="12">
     <mx:columns>
         <mx:DataGridColumn headerText="NO" dataField="userid" width="50"/>
      <mx:DataGridColumn headerText="이름" dataField="username" width="100"/>
      <mx:DataGridColumn headerText="메모" dataField="contents"/>
      <mx:DataGridColumn headerText="작성일" dataField="dates" width="150"/>
     </mx:columns>
    </mx:DataGrid>
   <mx:TextArea id="selectedcontents" text="{dgMemoRequest.selectedItem.contents}" width="560" height="70" horizontalCenter="0" bottom="10" wordWrap="true" editable="false"/>
   </mx:Panel>  
  
</mx:Application>

플렉스에서 Event 처리

FLEX/TIP 2008/06/14 11:08 Posted by <!--r'i"z&i\n+#]]x juree23

이벤트 알림을 수신하는 데에는 3가지 방법이 있습니다.

 

1. MXML에서 이벤트 핸들러 등록

2. MXML 선언에서 인라인 이벤트 핸들러 생성

3. ActionScript를 통해 이벤트 리스너 등록

 

1. MXML에서 이벤트 핸들러 등록

------------------------------------------------------------------------------------------

 

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
 <mx:Script>
  <![CDATA[
   import flash.events.MouseEvent;
   
   private function clickHandler(event:MouseEvent):void
   {
    myLabel.text = "Hello, World!";
   }
  ]]>
 </mx:Script>
 <mx:Panel
  title="My Application" horizontalAlign="center"
  paddingTop="10" paddingBottom="10" paddingLeft="10" paddingRight="10"
 >
  <mx:Label id="myLabel" width="180" fontWeight="bold" fontSize="24" />
  <mx:Button id="myButton" label="Click Me!" click="clickHandler(event);" />
 </mx:Panel>
</mx:Application>

 

------------------------------------------------------------------------------------------

 

2. MXML 선언에서 인라인 이벤트 핸들러 생성

------------------------------------------------------------------------------------------

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
 <mx:Panel
  title="My Application" horizontalAlign="center"
  paddingTop="10" paddingBottom="10" paddingLeft="10" paddingRight="10"
 >
  <mx:Label id="myLabel" width="180" fontWeight="bold" fontSize="24" />
  <mx:Button id="myButton" label="Click Me!" click="myLabel.text='Hello, World!'" />
 </mx:Panel>
</mx:Application>

------------------------------------------------------------------------------------------

 

3. ActionScript를 통해 이벤트 리스너 등록

------------------------------------------------------------------------------------------

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
 creationComplete="creationCompleteHandler(event);"
>
 <mx:Script>
  <![CDATA[
   import flash.events.MouseEvent;
   import mx.events.FlexEvent;
   
   private function creationCompleteHandler(event:FlexEvent):void
   {
    // Listen for the Click event on the Button control
    myButton.addEventListener(MouseEvent.CLICK, clickHandler);
   }
   
   private function clickHandler(event:Event):void
   {
    myLabel.text = "Hello, World!";
   }
  ]]>
 </mx:Script>
 <mx:Panel
  title="My Application" horizontalAlign="center"
  paddingTop="10" paddingBottom="10" paddingLeft="10" paddingRight="10"
 >
  <mx:Label id="myLabel" width="180" fontWeight="bold" fontSize="24" />
  <mx:Button id="myButton" label="Click Me!" />
 
 </mx:Panel>
 
</mx:Application>

제목 | FLEX에서 타이머 사용법

FLEX/TIP 2008/06/14 11:08 Posted by <!--r'i"z&i\n+#]]x juree23

http://livedocs.adobe.com/flex/201/lang ··· mer.html
을 보고 간단하게 구현해봤어요~

다른 참고문서는
Working with Dates and Times  Timer를 이용하여 동적으로 보여주는 달력과 시계만들어보기
Controlling time intervals  : 시간 intervals 제어

입니다.

Flex의 Timer는 flash.utils에 있구요~
EventDispatcher를 확장해서 구현된 Class입니다.

실시간으로 시계를 보여준다던가 게임을 만들때 주로 사용하게 될 것 같네요.
사용하기 아주 쉽네요.

아래는 소스코드입니다. 이 코드로 Timer의 전부를 다 구현한 것 같네요.
주석처리를 안하는게 더욱 깔끔할 것 같네요. 해석하는데도 어렵지 않고요~

MXML 소스 (Language : xml)
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()">
    <mx:Script>
    <![CDATA[
        import flash.utils.Timer; 
        import flash.events.TimerEvent;

        private var timer:Timer;

        private function init():void
        {
            timer = new Timer(100,10);
            timer.addEventListener(TimerEvent.TIMER, onTickEventHandler);
            timer.addEventListener(TimerEvent.TIMER_COMPLETE, onTimerCompleteEventHandler);
            updateTextInput();
        }

        private function startTimer():void
        {
            timer.start();
            updateTextInput();
        }

        private function resetTimer():void
        {
            timer.reset();
            updateTextInput();
        }

        private function stopTimer():void
        {
            if(timer.running == true)
            {
                timer.stop();
                updateTextInput();
            }
        }

        private function onTickEventHandler(e:TimerEvent):void
        {
            updateTextInput();
        }

        private function onTimerCompleteEventHandler(e:TimerEvent):void
        {
            updateTextInput();
            mx.controls.Alert.show("Time's Up!");

        }

        private function updateTextInput():void
        {
            txtCount.text = String(timer.currentCount);
            txtCount.text = String(timer.currentCount);
            txtRepeatCount.text = String(timer.repeatCount);
            txtDelay.text = String(timer.delay);
            chkRunning.selected = timer.running;
        }
    ]]>

    </mx:Script>
    <mx:Panel x="10" y="10" width="341" height="174" layout="absolute" title="Timer Test">
        <mx:Label x="10" y="10" text="currentCount"/>
        <mx:Label x="102" y="10" text="repeatCount"/>
        <mx:Label x="194" y="10" text="delay(milliseconds)"/>
        <mx:TextInput id="txtCount" x="10" y="36" text="0" width="84" editable="false" restrict="[0-9]"/>
        <mx:TextInput id="txtRepeatCount" x="102" y="36" text="0" width="84" restrict="[0-9]" change="timer.repeatCount=int(txtRepeatCount.text)"/>
        <mx:TextInput id="txtDelay" x="194" y="36" text="0" width="84" restrict="[0-9]"  change="timer.delay=int(txtDelay.text)"/>
        <mx:Button x="10" y="66" label="타이머 시작" click="startTimer()"/>
        <mx:Button x="102" y="66" label="타이머 리셋" click="resetTimer()"/>
        <mx:Button x="194" y="66" label="타이머 중지" click="stopTimer()"/>
        <mx:CheckBox x="10" y="96" label="Running" id="chkRunning" selected="false" enabled="true"/>
    </mx:Panel>
 
</mx:Application>


 


글쓴이 : 지돌스타 http://blog.jidolstar.com/104  

Flex와 PHP를 이용한 MyTube 구현

FLEX/TIP 2008/06/14 11:08 Posted by <!--r'i"z&i\n+#]]x juree23
Flex를 이용한 인터페이스 구성 파트 1

Flex 를 이용해서 원하는 비디오를 재생시키기 위해서는 Flex에게 재생시킬 수 있는 비디오의 리스트를 알려줘야만 합니다. 어떻게 해야하냐면 XML파일을 이용해서 Flex에게 비디오 리스트 정보를 넘겨줄 수가 있는데요, 여기서는 PHP로 다시 돌아가서 데이터베이스에서 비디오 리스트를 읽어들인 후에 XML로 출력하는 스크립트를 만들어 보도록 하겠습니다. 다음 [리스트 6]의 movies.php 파일을 보도록 하죠.

[리스트 6] movies.php
require "DB.php";

$moviebase = 'http://localhost:8080/movies/';

header( 'content-type: text/xml' );

$dsn = 'mysql://root@localhost/movies';
$db =& DB::connect( $dsn );
if ( PEAR::isError( $db ) ) { die($db->getMessage()); }
?>

$res = $db->query( 'SELECT title, source, thumb, width, height FROM movies' );
while( $row = $res->fetchrow( ) ) {
?>

thumb="" width=""
height="" />
}
?>

위 PHP 스크립트를 만든 후에 커맨드 라인에서 실행시키거나 브라우저에서 실행시키게 되면 다음 [그림 3]과 같은 XML 리스트를 볼 수가 있습니다.


[그림 3] XML로 표현된 비디오 리스트

이제 XML로 비디오 리스트 정보를 넘겨줄 수 있으니 전에 만들었던 simplemovie.mxml 파일을 좀 더 개선해 보도록 하겠습니다. 다음 [리스트 7]은 simplemovie.mxml의 업그레이드 된 버전입니다.

[리스트 7] mytube1.mxml


layout="absolute" creationComplete="movieXmlData.send()">


id="movieXmlData" result="onGetMovies( event )" />


import mx.rpc.events.ResultEvent;
import mx.controls.VideoDisplay;
import mx.controls.List;
import mx.rpc.http.HTTPService;
import mx.collections.ArrayCollection;

[Bindable]
private var movies : ArrayCollection = new ArrayCollection();

public function onGetMovies( event : ResultEvent ) : void
{
var firstMovie : String = event.result.movies.movie[0].source.toString();
videoPlayer.source = firstMovie;

movies = event.result.movies.movie;
movieList.selectedIndex = 0;
}

public function onPrevious() : void
{
if ( movieList.selectedIndex == 0 )
movieList.selectedIndex = movies.length - 1;
else
movieList.selectedIndex -= 1;
videoPlayer.source = this.movieList.selectedItem.source.toString();
}

public function onPlay() : void
{
videoPlayer.source = this.movieList.selectedItem.source.toString();
videoPlayer.play();
}

public function onNext() : void
{
if ( movieList.selectedIndex >= ( movies.length - 1 ) )
movieList.selectedIndex = 0;
else
movieList.selectedIndex += 1;
videoPlayer.source = this.movieList.selectedItem.source.toString();
}

public function onChange() : void
{
videoPlayer.source = this.movieList.selectedItem.source.toString();
}












dataProvider="{movies}"
change="onChange()"
labelField="title">




전 과 비교해서 크게 바뀐 부분이 있다면 파일의 상단에 있는 액션 스크립트(ActionScript)인데요, 이 코드로 전체적인 인터페이스를 관리하게 됩니다. 이 액션 스크립트가 하는 일은 먼저 onGetMovies 함수에 있는 HTTPService를 이용해서 movies.php 파일로부터 XML 정보를 읽어들이는 것입니다. HTTPService 클래스는 XML 리스트를 찾게 되면 XML 문서 객체모델(Document Object Model)로 변경하게 되고, 우린 이 문서 객체 모델을 이용해서 첫번째 비디오에 대한 정보를 얻어서 재생할 수가 있습니다. 또 onGetMovies 함수는 movies 라는 변수를 이용해서 페이지에 있는 리스트 박스에 비디오의 이름을 출력하게 됩니다. 나머지 액션 스크립트는 유저가 리스트 박스에 있는 비디오를 선택하거나 "이전", "다음" 버튼을 선택했을 경우를 처리하기 위한 코드입니다.

위 리스트의 제일 아래를 보면 전체 유저 인터페이스를 구성하는 Flex 오브젝트를 볼 수 있습니다. 여기에 이전 비디오와 다음 비디오를 선택할 수 있는 버튼을 배치하고, 오른쪽에는 현재 비디오 리스트를 출력하는 리스트 박스가 배치되어 있습니다.

이제 Flex Builder를 이용해서 위 프로그램을 컴파일하고 실행시키게 되면 [그림 4]와 같은 화면을 볼 수 있습니다.


[그림 4] Flex를 이용해서 구성한 첫 번째 인터페이스

리스트 박스에서 비디오를 선택할 수도 있고, 이전, 다음 버튼을 이용해서 비디오를 선택할 수도 있습니다. 멋있죠? 이제 미리보기 이미지를 제공해 주면 더 멋있어질 것 같네요.

Flex를 이용한 인터페이스 구성 파트 2 &; 미리보기 이미지

미 리보기 이미지를 비디오 리스트에 출력하려면 리스트 박스를 비디오의 제목과 미리보기 이미지를 같이 출력할 수 있도록 수정해야 합니다. 다행히도 Flex의 기능을 이용하면 아주 쉽게 수정이 가능합니다. 우선 태그에 itemRenderer를 추가하도록 하고, 다음 [리스트 8]을 보겠습니다.

[리스트 8] mytube2.mxml
...

dataProvider="{movies}"
change="onChange()"
itemRenderer="MovieItem">

...
여 기서 MovieItem이라는 item renderer MXML 컴포넌트를 만들었습니다. 이 컴포넌트를 만들려면 메뉴에서 "New > MXML Component"를 선택하고 [리스트 9]와 같이 컴포넌트를 코드에 넣으면 됩니다.

[리스트 9] MovieItem.mxml



height="{data.height/3}" rotation="5" left="10" top="0" />


여기서는 Canvas 라는 컨테이너를 이용했지만, 원한다면 마음에 드는 컨테이너를 선택해서 설정하셔도 괜찮습니다. 그리고 나서 미리보기 이미지 추가를 위해서 태그를 사용하고 비디오 제목을 출력하기 위해서 을 이용하면 됩니다. 좀 더 재밌게 해보기 위해서 미리보기 이미지를 약간 회전시켜 봤습니다. [그림 5]를 보도록 하죠.


[그림 5] 미리보기 이미지를 추가한 리스트 박스

꽤 괜찮은 비디오 플레이어가 됐네요. 여기에 추가적으로 비디오 설명, 재생 시간, 링크, 추천 버튼과 같은 기능을 추가하면 더 좋을 것 같습니다.

저장소와 대역폭

데 이터베이스를 구성하고 비디오 공유 사이트 페이지를 만들어 내는것 자체는 지금까지 잘 해결했는데, 사실 이것말고 한가지 더 고려해야 할 것이 있습니다. 바로 대역폭을 고려해야 합니다. 플래시 비디오 파일 자체가 인코딩이 잘 된다고 해도 역시 비디오 파일이기 때문에 크기가 큰 편에 속하게 됩니다. 그렇기 때문에 중간에 끊김없이 비디오 재생을 얼마나 할 수 있는지 파악하는 것이 무엇보다 중요하게 됩니다.

확실한 방법중 하나는 인터넷 데이터 센타에서 서비스를 하는 것입니다. 다른 방법으로는 비디오 공유 사이트에서는 비디오 자체에 대한 데이터를 가지지 않고 링크만 저장하고 실제 비디오 데이터는 다른 곳에 저장하는 방법입니다. 아마존의 S3 서비스 같은 경우가 좋은예인데요, 저렴한 가격으로 좋은 저장소로 활용할 수가 있고, 어느정도 사이트가 커질때까지는 안정적으로 활용할 수 있습니다.

결론

플래시를 이용한 비디오의 등장과 광대역폭의 보편화로 인해서 이제 적은 예산으로 비디오 공유 사이트를 운영한다는 것이 현실로 다가왔습니다. 바라기는 이 글을 통해서 여러분이 좀 더 멋있는 비디오 공유사이트를 만들어냈으면 하는 것입니다.

[Flex] 스킨(Skin)을 이용하여 확장가능한 게이지 ..

FLEX/TIP 2008/06/14 11:07 Posted by <!--r'i"z&i\n+#]]x juree23
전에 웹 서핑중에 학습하는데 도움이되는 컴포넌트를 발견하였다.
그것은 Peter Ent의 블로그에 올라온 게이지 컴포넌트였다.
잠시 구경해보자.

GaugeComponent.zip

원본소스다. 받아가삼~

")


1. Gauge 컴포넌트가 학습용으로 좋은 이유


난 이 Gauge 컴포넌트의 소스를 보자마자 컴포넌트 학습용으로 정말 좋다고 판단했다.
그 이유는 다음과 같다.

  1. 각종 스킨 타입을 제작 및 적용하는 방법을 학습할 수 있다.
    Gauge 컴포넌트는 단순히 UIComponent에 그래픽 속성만 부여하여 만들어진 컴포넌트가 아닌 Skin 및 style을 이용하여 다양한 모양의 Gauge를 만들어낼 수 있도록 만들었다. Gauge컴포넌트는 총 3부분으로 구성된다. 바늘(Needle), 바늘커버(Cover), 프레임(Frame) 이 그것이다. 이 구성을 PNG,JPG,SWF와 같은 그래픽 스킨 또는 프로그램적으로 만들어진 스킨(ProgrammaticSkin ,Border , 및 RectangularBorder 등을 확장함)을 적용이 가능하도록 되어 있다.
    사용자 삽입 이미지

    기본 프로그램 스킨

    사용자 삽입 이미지

    그래픽 이미지 스킨 적용

    사용자 삽입 이미지

    다른 프로그램 스킨 적용


  2. 컴포넌트 확장 학습을 할 수 있다.
    기본으로 만들어진 Gauge 컴포넌트는 바늘이 한개이다. 이를 확장하여 다음 그림과 같은 2개의 바늘을 가진 컴포넌트를 아주 쉽게 만들 수 있다.
    사용자 삽입 이미지
  3. Filter을 이용한 Grapic 학습에 도움을 준다.
    아래 그림의 Gauge는 실제로 Graphics 이용해 그림을 그리고 나서 BevelFilter를 이용해 음영 표현을 한것과 하지 않은 것을 보여주고 있다.
    사용자 삽입 이미지

    BevelFilter를 사용했을 때

    사용자 삽입 이미지

    Filter를 사용하지 않았을 때


2. 선행학습

컴포넌트를 제작하기 위해 먼저 ActionScript를 이용한 확장 컴포넌트를 만드는 방법에 대해서 먼저 학습할 필요가 있다. 특별히 UIComponent를 확장해서 만들것이므로 Flexdocs.kr 에서 제공하는 "확장된 컴퍼넌트의 작성에 대해"를 먼저 학습하기 바란다.

그리고 선행적으로 학습해야할 것은 스킨을 적용하는 방법이다. 아래 내용에 대해서 어느정도 숙지하고 있어야 Gauge컴포넌트를 이해하는데 도움이 된다. 아래 링크를 참고하여 필요한 지식을 얻자!

스킨의 종류


스킨 적용법



3. Gauge 컴포넌트 제작 방향 및 순서 선정

Gauge 컴포넌트는 일단 다음과 같은 방향으로 만들어 진다.

  1. 3개의 스킨(frameSkin, coverSkin, needleSkin)을 가진다.
  2. frame 배경색,투명도,경계선색,경계선투명도,경계선두께 스타일을 지정할 수 있다.
  3. cover의 색, 알파값, 커버의 그림자 유무을 스타일로 지정할 수 있다.
  4. 바늘(needle)의 색, 두께, 알파값을 스타일로 지정할 수 있다.
  5. 최대(maximum),최소값(minimum)을 설정할 수 있도록 한다.
  6. 값(value)를 설정할 수 있게 하고 Bind가 가능하게 한다.
  7. 바늘은 아래방향에서 좌측으로 45도을 최소값을 가리키게 하고 우측으로 315도 방향을 최대값을 가리키게 한다.
  8. 값(value)가 주어질 경우 바늘은 Rotate 이펙트를 이용해서 회전할 수 있도록 한다.
  9. LiveDrag의 속성(liveDragging)을 가지고 true이면 Gauge의 바늘을 마우스로 클릭하거나 드래그로 움직일 수 있다. 이때 gaugeClick 이벤트를 송출하도록 한다. 송출시 현재값과 새로운값을 넘겨준다.
  10. 바늘 하나를 더 추가한 DoubleGauge컴포넌트를 만들 수 있다.

위의 조건을 모두 만족하는 Gauge 컴포넌트를 만들기 위해 다음과 같은 순서로 제작한다.

  1. 프로그램 스킨을 이용한 기본스킨제작
    참고 : http://flexdocs.kr/docs/flex2/docs/00000808.html 
  2. 마우스 클릭시 현재값과 새로운값을 송출하는 이벤트를 만든다.
  3. Gauge 컴포넌트를 만든다.
      - 스타일, 이벤트 메타데이타 지정
      - Skin 및 Rotate 이펙트 인스턴스  변수 선언
      - 생성자 : 마우스 이벤트 Listener
      - value, maximum, minmum, liveDragging 속성 setter, getter 제작
      - createChildren() : 스킨 인스턴스 생성 및 addChild, Rotate 이펙트 인스턴스 생성(target은 바늘이 된다.)
      - measure() : 기본 폭, 높이를 50으로 지정한다.
      - updateDisplayList() : 각 스킨의 위치 및 사이즈를 지정하고 값에 따라 바늘 각도에 따라 표시해줌, Cover의 그림자 효과 설정
  4. 위의 기본 Gauge를 적용해봄
  5. 다른 스킨 만들어봄 (네모모양, 다이얼형태)
  6. 바늘이 1개 더 추가된 Gauge 제작



4. 기본 스킨을 만들자.

스킨의 이름은 GaugeSkin 이라 정하자.
프로그램 스킨을 만들기 위해 부모 클래스로서 다음 3가지중 한개를 선택할 필요가 있다.
참고 : http://flexdocs.kr/docs/flex2/docs/00000809.html 


Gauge예제에서는 Border 부모 클래스로 선택했다.
아래는 GaugeSkin 클래스의 기본골격이 되겠다.

GaugeSkin.as (Language : java)
package gauge.skins.programmatic
{
    import mx.skins.Border;
    import flash.display.Graphics;
    import mx.styles.StyleManager;
    import flash.filters.DropShadowFilter;

    public class GaugeSkin extends Border
    {
        public function GaugeSkin()
        {
            super();
        }
        override protected function updateDisplayList( w:Number, h:Number ) : void
        {
            //스타일 대응의 속성을 추가한다.
            //컴포넌트의 상태를 검출하는 논리를 추가해 속성을 설정
            //스킨 name에 따라 속성을 적용한 스킨의 기본 그림을 그려준다.
        }
    }

    private var _borderMetrics:EdgeMetrics;
    override public function get borderMetrics() :EdgeMetrics
    {
        //경계선의 두께를 알아내기 위한 속성의 값을 boarderMetrics형태로 반환하여 준다.
    }
}


위에서 두개의 메소드 updateDisplayList()와 borderMetrics()만 완성하면 되겠다.
먼 저 borderMetircs() 메소드를 살펴보자. 이 메소드는 Border에 정의된 메소드로 재정의(override)해서 사용하면 된다. 경계선의 두께를 반환하면 되므로 스타일속성중 borderThickness값을 이용하면 되겠다.

Gauge.as의 borderMetircs() 메소드 재정의 (Language : java)
private var _borderMetrics:EdgeMetrics;
override public function get borderMetrics() :EdgeMetrics {
    var borderThickness:Number = getStyle("borderThickness");
    _borderMetrics = new EdgeMetrics(borderThickness, borderThickness,
        borderThickness, borderThickness);
    return _borderMetrics;
}

스타일 속성으로 배경색,배경투명도,경계선색,경계선두께,경계선투명도,바늘색,바늘두께,바늘투명도,커버색,커버투명도를 설정하기로 했다. 이들의 각각의 이름을 다음과 같이 정한다.

  • backgroundColor : frame의 배경색
  • backgroundAlpha : frame의 투명도
  • borderColor : frame의 경계선색
  • borderAlpha : frame의 투명도
  • borderThickness : frame의 두께
  • needleColor : 바늘의 색
  • needleAlpha : 바늘의 투명도
  • coverColor : 바늘 커버의 색
  • coverAlpha : 바늘 커버의 투명도

위에 서 지정한 스타일 변수명은 이 GaugeSkin을 addChild하는 부모 클래스에서 정의한 Skin 메타데이타를 참고하게 된다.  부모 클래스에서는 GaugeSkin을 frameSkin이라는 Style명으로 사용한다고 가정할 때 아래와 같이 GaugeSkin을 사용하게 된다.

Gauge.as의 일부, GaugeSkin의 부모 클래스이다. (Language : java)
[Style(name="frameSkin",type="Class",inherit="no")]
...

[Style(name="backgroundColor",type="Number",format="Color",inherit="no")]

...
public class Gauge extends UIComponent
{
...
    override protected function createChildren():void
    {
        var skin:Class = Class(getStyle("frameSkin"));
        var newSkin:IFlexDisplayObject = new skin();

        newSkin.name = "frameSkin";
        newSkin.styleName = this;
       
        addChild(newSkin);
    }
...
}


위 코드의 중간에 newSkin는 GaugeSkin의 인스턴스가 되며 그 속성인 styleName에 this를 참조시키는 것을 볼 수 있다. 여기서 this는 부모 클래스를 의미한다. 이것을 하게 되면 GaugeSkin에서 getStyle()메소드를 통해 부모 클래스에서 설정한 Style명을 참고할 수 있다. 가령 위에 [Style(name="backgroundColor")]이 정의되어 있으므로 GaugeSkin에서 getStyle("backgroundColor")로 접근이 가능하다는 것이다.

GaugeSkin.as의 updateDisplayList() 메소드 (Language : java)
override protected function updateDisplayList( w:Number, h:Number ) : void
{
    var bgColor:Number = getStyle("backgroundColor");
    if( isNaN(bgColor) || !StyleManager.isValidStyleValue(bgColor)) bgColor = 0xFFFFFF;
    var bgAlpha:Number = getStyle("backgroundAlpha");
    if( isNaN(bgAlpha) || !StyleManager.isValidStyleValue(bgAlpha) ) bgAlpha = .85;
    var borderColor:Number = getStyle("borderColor");
    if( isNaN(borderColor) || !StyleManager.isValidStyleValue(borderColor) ) borderColor = 0x606060;
    var borderAlpha:Number = getStyle("borderAlpha");
    if( isNaN(borderAlpha) || !StyleManager.isValidStyleValue(borderAlpha) ) borderAlpha = 1;
    var borderSize:Number = getStyle("borderThickness");
    if( isNaN(borderSize) || !StyleManager.isValidStyleValue(borderSize) ) borderSize = 1;
    var needleColor:Number = getStyle("needleColor");
    if( isNaN(needleColor) || !StyleManager.isValidStyleValue(needleColor) ) needleColor = 0x000000;
    var needleThickness:Number = getStyle("needleThickness");
    if( isNaN(needleThickness) || !StyleManager.isValidStyleValue(needleThickness) ) needleThickness = 3;
    var needleAlpha:Number = getStyle("needleAlpha");
    if( isNaN(needleAlpha) || !StyleManager.isValidStyleValue(needleAlpha) ) needleAlpha = 1;
    var coverColor:Number = getStyle("coverColor");
    if( isNaN(coverColor) || !StyleManager.isValidStyleValue(coverColor) ) coverColor = 0x606060;
    var coverAlpha:Number = getStyle("coverAlpha");
    if( isNaN(coverAlpha) || !StyleManager.isValidStyleValue(coverAlpha) ) coverAlpha = 1;
   
    var g:Graphics = graphics;
   
    g.clear();
   
    // the name property determines which skin is being drawn.

    switch( name )
    {
        case "frameSkin":
            g.lineStyle( borderSize, borderColor, borderAlpha );
            g.beginFill( bgColor, bgAlpha );
            g.drawEllipse(x,y,w,h);
            g.endFill();
            break;
        case "needleSkin":
            g.lineStyle( needleThickness, needleColor, needleAlpha );
            g.moveTo(0,0);
            g.lineTo(Math.min(w,h)*.45,0);
            break;
        case "coverSkin":
            g.lineStyle( 0, 0, 0 );
            g.beginFill( coverColor, coverAlpha );
            g.drawEllipse((w-w/4)/2,(h-h/4)/2,w/4,h/4);
            g.endFill();
            break;
    }
}


작성된 updateDisplayList()메소드를 분석하자.
크게 두부분으로 나뉜다. Style값을 획득하는 부분과 Skin name에 따라서 그림을 그려주는 부분이다.

윗 부분을 살펴보면 아래와 같은 코드가 반복되는 것을 볼 수 있다.
    var bgColor:Number = getStyle("backgroundColor");
    if( isNaN(bgColor) || !StyleManager.isValidStyleValue(bgColor)) bgColor = 0xFFFFFF;

이 부분은 부모클래스에서 정의한 Style명 backgroundColor 의 값을 getStyle()메소드로 읽고 있다. 하지만 부모에서 유효한 값을 사용하지 않았거나, 값이 지정되지 않았다면 bgColor를 기본값으로 0xFFFFFF로 해준다.

위 코드에서 아래 부분을 살펴보자.
아 래 부분은 GaugeSkin의  name 속성의 값이 frameSkin, needleSkin, coverSkin 일때 서로 다른 그림을 그려준다.  잘 보면 name속성이 frameSkin인 경우 해당 Style속성인 backgroundColor, backgroundAlpha, borderThickness, borderColor, borderAlpha값을 이용하여 정해진 폭과 높이에 따라 타원모양을 배경에 그려주고 있다. 같은 방법으로 needleSkin인 경우 전체크기의 약 45%정도의 바늘크기를 가진 선을 그려주고
coverSkin일때는 바늘을 덮어줄 수 있도록 중심부분에 전체 폭,높이에 대해 약 1/4 크기의 타원형 cover를 그려준다. 프로그램 스킨에서 그림을 그리는 방법 및 적용방법에 대해서는 프로그램스킨>프로그램에 의한 묘화 를 참고하면 되겠다.

부모 클래스에서는 이 GaugeSkin을 3개 인스턴스화해서 각각 이름을 frameSkin, needleSkin, coverSkin으로 하여 addChild하게 된다.


5. 이벤트를 만들자.

만들어질 이벤트는 Gauge에서 마우스 이벤트가 발생했을때 현재값과 새로운 값을 담는 역할을 한다.
그 외에는 별 내용이 없으므로 소스만 확인해보자.

GaugeEvent.as (Language : java)
package gauge.events
{
    import flash.display.InteractiveObject;
    import flash.events.MouseEvent;

    public class GaugeEvent extends MouseEvent
    {
        public function GaugeEvent(currentValue:Number, value:Number, localX:Number=0, localY:Number=0, relatedObject:InteractiveObject=null, ctrlKey:Boolean=false, altKey:Boolean=false, shiftKey:Boolean=false, buttonDown:Boolean=false, delta:int=0.0)
        {
            super("gaugeClick", true, true, localX, localY, relatedObject, ctrlKey, altKey, shiftKey, buttonDown, delta);
            this.currentValue = currentValue;
            this.value = value;
        }
       
        public var currentValue:Number;
        public var value:Number;
       
    }
}


6. Gauge 컴포넌트를 만들자.

앞서 GaugeSkin의 부모인 Gauge의 약간 맛배기로 보았다. Gauge는 UIComponent를 확장하여 사용할 것이다.
6-1 Style 및 이벤트 메타데이터 지정 & needle 회전이펙트 및 Skin 인스턴스 참조 변수 선언

아래는 Gauge가 가져야 하는 기본 구조와 Style 및 Event 메타데이타를 정의한 코드이다.
앞서 지정한 GaugeSkin에 대한 Class를 참고해야하므로 Style 메타데이타에 frameSkin, coverSkin, needleSkin을 정의했다. type은 Class이다.

그리고 이미 지정한 Style의 이름과 type 및 format을 지정한다.

class에 private변수로 frameSkin, coverSkin, needleSkin을 IFlexDisplayObject로 선언했다.
앞 서 메타데이터로 지정한 frameSkin, coverSkin, needleSkin 스타일에 대응하여 이 변수에 인스턴스가 생성되게 된다. 이 메타데이터는 우리가 앞서 정의한 GaugeSkin일 수 있고 이미지 또는 다른 Skin이 될 수 있겠다.

Gauge.as의 기본구조. (Language : java)
package gauge
{
    ....

    [Style(name="frameSkin",type="Class",inherit="no")]
    [Style(name="coverSkin",type="Class",inherit="no")]
    [Style(name="needleSkin",type="Class",inherit="no")]

    [Style(name="backgroundColor",type="Number",format="Color",inherit="no")]
    [Style(name="backgroundAlpha",type="Number",inherit="no")]
    [Style(name="borderColor",type="Number",format="Color",inherit="no")]
    [Style(name="borderAlpha",type="Number",inherit="no")]
    [Style(name="borderThickness",type="Number",nherit="no")]
    [Style(name="needleColor",type="Number",format="Color",inherit="no")]
    [Style(name="needleThickness",type="Number",inherit="no")]
    [Style(name="needleAlpha",type="Number",inherit="no")]
    [Style(name="coverColor",type="Number",format="Color",inherit="no")]
    [Style(name="coverAlpha",type="Number",inherit="no")]
    [Style(name="coverDropShadowEnabled",type="Boolean",inherit="no",default="true")]

    [Event(name="gaugeClick",type="gauge.events.GaugeEvent")]
   
    public class Gauge extends UIComponent
    {   
        protected var frameSkin:IFlexDisplayObject;
        protected var coverSkin:IFlexDisplayObject;
        protected var needleSkin:IFlexDisplayObject;
       
        private var rotate:Rotate; 

        public function Gauge()
        {
            super();
            ....
        }

        override protected function createChildren():void
        {
            super.createChildren();
            ....
        }

        override protected function measure():void
        {
            super.measure();
            ....
        }

        override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
        {
            super.updateDisplayList(unscaledWidth,unscaledHeight);
            ....
        }

        ....
    }
}


6-2 스킨적용

스킨을 addChild해야하므로 UIComponent의 createChildren() 메소드를 재정의해서 사용한다.
아 래 코드에서 보면 이미 선언한 3개 스킨 변수에 createSkin()함수를 이용하여 인스턴스를 생성하는 것을 볼 수 있다. createSkin()메소드가 하는 일은 1번째 인자로 스킨이름으로 스킨이 이미 만들어져 있는지 검사후 만약 없으면 기본 스킨 클래스인 GaugeSkin 클래스를 적용하게 한다.

Gauge를 인스턴스를 사용할때 <gauge:Gauge id="g1" /> 형태로 사용하면 createSkin()메소드는 GaugeSkin를 이용해 Skin 인스턴스생성한다. 하지만 만약 <gauge:Gauge id="g1" frameSkin='@Embed(source="/gauge/skins/graphic/BitmapFrame.png')"/> 와 같은 형태로 사용하게 되면 frameSkin 스타일의 인스턴스로 BitmapFrame.png를 Embed한 Class를 이용하게 되는 것이다. 또 다른 형태의 프로그램 스킨을 만들었다면 <gauge:Gauge id="g1" frameSkin='@ClassReference("gauge.skins.alternatives.DialSkin')"/>
와 같은 형태로 frameSkin을 적용할 수 있겠다. 여기서 DialSkin도 GaugeSkin처럼 만들어졌다고 생각하면 된다.

아래 프로그램에서 중요한 점은 바로
styleableSkin.styleName = this;
이다.
styleName을 this로 안해주면 BaseSkin또는 다른 프로그램 스킨에서 Gause.as에서 정의한 스타일 메타데이타 값들을 getStyle()로 참조할 수 없다.

Gauge.as - 스킨을 addChild하는 부분 (Language : java)
override protected function createChildren():void
{
    super.createChildren();
   
    frameSkin  = createSkin( "frameSkin", GaugeSkin );
    needleSkin = createSkin( "needleSkin", GaugeSkin );
    coverSkin  = createSkin( "coverSkin", GaugeSkin );
   
    rotate = new Rotate(needleSkin);
}

protected function createSkin( skinName:String, defaultSkin:Class ) : IFlexDisplayObject
{
    var newSkin:IFlexDisplayObject =
        IFlexDisplayObject(getChildByName(skinName));
   
    if (!newSkin)
    {
        var newSkinClass:Class = Class(getStyle(skinName));
        if( !newSkinClass ) newSkinClass = defaultSkin;
       
        if (newSkinClass)
        {
            newSkin = IFlexDisplayObject(new newSkinClass());
            if( !newSkin ) newSkin = new defaultSkin();
           
            newSkin.name = skinName;

            var styleableSkin:ISimpleStyleClient = newSkin as ISimpleStyleClient;
            if (styleableSkin)
                styleableSkin.styleName = this;

            addChild(DisplayObject(newSkin));
        }
    }
   
    return newSkin;
}


6-3 게이지 그리기

아 래 코드를 보자. 앞서 인스턴스화하고 addChild 한 frameSkin, needleSkin, coverSkin의 배치하고 있다. 특별히 coverSkin인 경우 Style 속성중 coverDropShadowEnabled가 true일때 cover의 그림자 효과를 주고 있다.
또한 needleSkin인 경우 value값에 따라 회전하고 있으며 이때 회전효과를 주기 위해 Rotate 이펙트 인스턴스를 사용하는 것을 볼 수 있다.

여기서 중요한 부분은 바로 Skin들 자체가 컴포넌트화 되어서 사용되었다는 점이다.
더욱 생각해야할 부분은 이 스킨들이 우리가 만든 GauseSkin뿐 아니라 Gauge를 인스턴스화 할때 Style을 어떻게 해주냐에 따라 전혀 다른 모습을 보여줄 수 있다는 것이다.

Gauge.as - updateDisplayList() 재정의 (Language : java)
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
    super.updateDisplayList(unscaledWidth,unscaledHeight);
   
    var coverDropShadowEnabled:Object = getStyle("coverDropShadowEnabled");
   
    // positin and size the skins.
    frameSkin.move(0,0);
    frameSkin.setActualSize(unscaledWidth,unscaledHeight);
   
    // the needle skin has its origin moved to the very center
    // of the component; makes rotating it easy.
    needleSkin.move(unscaledWidth/2,unscaledHeight/2);
    needleSkin.setActualSize(unscaledWidth,unscaledHeight);
   
    // the cover has its origin moved to the center of the
    // component, too.
    coverSkin.move( 0, 0 );
    coverSkin.setActualSize( unscaledWidth, unscaledHeight );
    if( coverDropShadowEnabled == null || coverDropShadowEnabled == true ) {
        DisplayObject(coverSkin).filters = [ new DropShadowFilter(4,45,0,.5) ];
    }
   
    // adjust the value to make sure it is within bounds.
    if( _value < _minimum ) _value = _minimum;
    if( _value > _maximum ) _value = _maximum;
   
    // determine the angle of the needle based on the current
    // value and minimum and maximum values.
    var angle:Number = calculateAngleFromValue(_value);
   
    // Use a Rotate effect to spin the needle from its previous
    // position.

    if( rotate.isPlaying ) rotate.end();
    rotate.angleFrom = _prevAngle;
    rotate.angleTo = angle;
    rotate.originX = 0;
    rotate.originY = 0;
    rotate.play();
   
    _prevAngle = angle;
}

그 외에 마우스 컨트롤하는 부분과 getter, setter 정의에 대한 설명은 생략한다.
여기서 설명하고자 하는 주제와 약간 벗어날 수 있기 때문이다. 이에 대해서는 개별적으로 소스를 분석해봤으면 한다.


7. GaugeSkin만 적용한 Gauge 컴포넌트를 사용해보자.

아래와 같이 Gauge를 테스트하는 프로그램을 만들었다.
첫번째 게이지는 어떤 스타일도 적용하지 않은 기본 게이지이다. 라이브 Drag가 되고 Drag 할때 두번째 게이지의 값과 연동되도록 했다. 두번째와 세번째는 인라인방법과 스타일시트를 이용한 방법을 이용해 스타일을 적용했다.

GaugeText.mxml (Language : xml)
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:gauge="gauge.*">
    <mx:Style>
        .needle {
            coverColor:   #009900;
            needleColor:        #009900;
            borderColor:        #009900;
            borderThickness:    3;
            backgroundColor:    #FFFFFF;
            backgroundAlpha:    .85;
            coverDropShadowEnabled: false;
        }
    </mx:Style>
   
    <mx:Script>
    <![CDATA[
        import mx.controls.Alert;
        import gauge.events.GaugeEvent;
        private function handleGaugeEvent( event:GaugeEvent ) : void
        {         
            g2.value = event.value;
        }
    ]]>

    </mx:Script>
    <gauge:Gauge id="g1" x="20" y="20" width="100" height="100"
        gaugeClick="handleGaugeEvent(event)"
        liveDragging="true"
        value="300"
        minimum="200"
        maximum="600"      
         />

    <mx:Text x="20" y="122" width="100" text="Programmatic, Basic, Interactive"/>
        
    <gauge:Gauge id="g2" x="200" y="20" width="100" height="100"
        backgroundColor="0xFFFFFF"
        backgroundAlpha=".4"
        borderColor="0xDD0000"
        borderAlpha="1"
        borderThickness="4"
        needleColor="0x000000"
        needleThickness="4"
        needleAlpha=".7"
        coverColor="0xDD0000"
        coverAlpha="1"
        value="300"
        minimum="200"
        maximum="600"/>

    <mx:Text width="100" x="200" y="122" text="Programmatic, Styled"/>
        
    <gauge:Gauge id="g3" x="352" y="10" width="100" height="100"
        styleName="needle"
        value="{stepper.value}"/>

    <mx:Text width="100" x="352" y="120" text="Programmatic, Styled"/>
        
    <mx:Label x="20" y="197" text="Set value:"/>
    <mx:NumericStepper id="stepper" x="95" y="195" minimum="0" maximum="100" />
</mx:Application&

Flex Component간 종속성을 없애보자(이벤트)

FLEX/TIP 2008/06/14 11:07 Posted by <!--r'i"z&i\n+#]]x juree23
예전에 Flex Component간 종속성을 없애보자 (Event 사용하자)라는 제목으로 글을 쓴 적이 있다.
제목의 취지대로 설명하고자 했으나 초보자들에게 쉽게 다가오지 않는 면이 있어서
내용을 보충한 더욱 쉬운 예제를 들고자 한다.

컴포넌트 종속성에 관련된 내용을 언급하기에 앞서 컴포넌트를 사용하는 이유와 그 조건을 언급하겠다.


1. 컴포넌트를 만들어야 하는 이유는 무엇일까?

컴포넌트를 만들면 프로그램 분리가 되기 때문에 가독성이 편리해지고 재사용성이 생긴다. 많은 부분에서 프로그램의 컴포넌트화는 프로젝트를 진행하는데 있어서 가장 중요한 요소중에 하나가 된다.



2. 컴포넌트가 지녀야할 조건

개인적으로 생각하는 컴포넌트(Component)가 지녀야할 조건을 다음 4가지로 요약해보았다.

  1. 편의성
    사용하기 편리해야하는 것은 컴포넌트의 가장 기본적인 요소가 아닐까? 한 예로 Flex SDK에서 제공하는 Button, TextArea와 같은 컴포넌트를 사용하는 것이 어려운가? 쉽다.
    좋은 컴포넌트는 속성 및 메소드 접근도 편리하고 이벤트 사용도 편하다.
    편 의성을 보장하기 위해 속성,메소드,이벤트 이름 선택이 무엇보다 중요하다. 즉, 체계화된 이름은 편의성 증대에 도움을 준다. 또 접근제한자(public, protected, private, internal, namespace)도 적절하게 사용해야 하겠다.
  2. 재사용성
    만들어진 컴포넌트가 다른 프로젝트를 진행할 때에도 쉽게 사용할 수 있다면 그 컴포넌트는 재사용성이 좋다고 말할 수 있을것이다. 사실 재사용성이 없다면 컴포넌트라 할 수 없다.
  3. 확장성
    컴포넌트를 상속해서 사용하기 용이해야 하겠다. 물론 확장성은 컴포넌트의 가장 중요한 요소가 되지 않지만, 확장성을 가지는 컴포넌트를 만들려고 하는 노력은 더욱도 세심하고 이용하기 편한 컴포넌트를 만드는데 도움을 줄 수 있다. 또한 많은 경우 확장해서 새롭게 디자인을 하거나 기능을 추가해야하는 경우가 생기기 때문에 확장성은 중요하다 할 수 있다.
  4. 독립성
    종속성의 반대말로 컴포넌트는 독립성을 가져야한다. 이 말은 재사용성과 일맥상통할 수 있다. 거의 비슷한 말이다. 그런데 여기서 독립성을 강조한 이유는 속성이 다른 컴포넌트의 속성을 참고하지 않는 경우를 언급하고 싶기 때문이다. 만약 제작한 컴포넌트가 다른 컴포넌트의 속성을 직접 사용하는 경우 두 컴포넌트는 종속성을 가진다. 즉, 이 컴포넌트는 단독적으로 재사용하는 것은 불가능한 것이다. 완벽한 독립성을 보장하기 위해서 가장 좋은 방법은 바로 이벤트를 이용하는 것이다.
나는 여기서 독립성(비종속성)에 관련된 내용을 언급하기로 하겠다.


3. 독립적이지 못한 컴포넌트의 예


독립적이지 못하다는 것은 컴포넌트가 다른 컴포넌트에 종속적이라는 말과 동일하다는 것을 앞서 언급했다.
두가지 예제를 보여주겠다.

3-1. 컴포넌트에서 Application.application에 접근한 예


ExComponent.mxml (Language : xml)
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:MyComp="*">
    <mx:TextArea id="myTAMain" x="10" y="40"/>
    <MyComp:StateComboBox y="10" x="10"/>
</mx:Application>
 

StateComboBox.mxml (Language : xml)
<?xml version="1.0" encoding="utf-8"?>
<mx:ComboBox xmlns:mx="http://www.adobe.com/2006/mxml" close="handleCloseEvent(event);">
        <mx:Script>
            <![CDATA[               
                import flash.events.Event;
                public function handleCloseEvent(eventObj:Event) :void {
                    mx.core.Application.application.myTAMain.text = String(selectedIndex);
                }
            ]]>

        </mx:Script>
        <mx:dataProvider>   
            <mx:String>AK</mx:String>
            <mx:String>AL</mx:String>
        </mx:dataProvider>
</mx:ComboBox>
 

위 소스는 아주 간단한 컴포넌트의 예제이다. ComboBox를 확장해서 StateComoboBox를 만들고 기본으로 2개의 아이템을 가진다. close이벤트가 실행되면 Application.application에서 만든 myTAMain을 접근하는 것을 볼 수 있다.

생각해보자. 이것이 과연 컴포넌트일까?
StateComboBox 컴포넌트는 반드시 Application 위에 있어야 하며 Application에는 myTAMain 아이디를 가진 TextArea Child가 반드시 있어야 한다. 2가지 조건을 만족하지 않는다면 StateComboBox는 사용할 수 없다는 것을 알 수 있다. 즉, 독립성을 보장할 수 없다는 것이다. 다른 말로 Application에 긴밀하게 종속적인 컴포넌트라는 것이다.


3-2. 컴포넌트에서 parentDocument 속성으로 접근한 예제

StateComboBox.mxml (Language : xml)
<?xml version="1.0" encoding="utf-8"?>
<mx:ComboBox xmlns:mx="http://www.adobe.com/2006/mxml" close="handleCloseEvent(event);">
        <mx:Script>
            <![CDATA[               
                import flash.events.Event;
                public function handleCloseEvent(eventObj:Event) :void {
                    parentDocument.application.myTAMain.text = String(selectedIndex);
                }
            ]]>

        </mx:Script>
        <mx:dataProvider>   
            <mx:String>AK</mx:String>
            <mx:String>AL</mx:String>
        </mx:dataProvider>
</mx:ComboBox>
 

이 는 바로 위의 예제와 동일하지만 handleCloseEvent()함수에서 Application.application에 접근한 대신, parentDocument에 접근했다. 이렇게 했을 경우 위 예제보다 약간의 독립성이 보장된다. 왜냐하면 꼭 Application위에 없어도 되기 때문이다. 그렇지만 Application이 아니더라도 parentDocument에 해당되는 부모 컴포넌트에 TextArea형태의 myTAMain아이디를 가진 컴포넌트가 반드시 있어야하는 것은 동일하다. 그러므로 아직까지 완벽히 독립적이다라고 할 수 없다.




4. 독립성을 가진 컴포넌트의 예 - Event 사용



ExComponent.mxml (Language : xml)
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:MyComp="*">
    <mx:TextArea id="myTAMain" x="10" y="40"/>
    <MyComp:StateComboBox y="10" x="10" ChangeItem="myTAMain.text=String(StateComboBoxEvent(event).itemIndex)"/>
</mx:Application>
 


StateComboBox.mxml (Language : xml)
<?xml version="1.0" encoding="utf-8"?>
<mx:ComboBox xmlns:mx="http://www.adobe.com/2006/mxml" close="handleCloseEvent(event);">
        <mx:Metadata>
            [Event(name="ChangeItem", type="StateComboBoxEvent")]
        </mx:Metadata>
        <mx:Script>
            <![CDATA[               
                import flash.events.Event;
                public function handleCloseEvent(eventObj:Event) :void {
                    var event:StateComboBoxEvent = new StateComboBoxEvent(StateComboBoxEvent.CHANGE_ITEM);
                    event.itemIndex = selectedIndex;
                    event.itemLabel = selectedLabel;               
                    dispatchEvent( event );
                }
            ]]>

        </mx:Script>
        <mx:dataProvider>   
            <mx:String>AK</mx:String>
            <mx:String>AL</mx:String>
        </mx:dataProvider>
</mx:ComboBox>
 


StateComboBoxEvent.as (Language : java)
package
{
    import flash.events.Event;

    public class StateComboBoxEvent extends Event
    {
        public static const CHANGE_ITEM:String = "ChangeItem";
        private var _itemIndex:int = 0;
        private var _itemLabel:String = "";
       
        public function StateComboBoxEvent( type:String )
        {
            super(type,false,false);
        }
       
        public function set itemIndex( value:int ):void
        {
            _itemIndex = value;
        }
        public function get itemIndex():int
        {
            return _itemIndex;
        }
       
        public function set itemLabel( value:String ):void
        {
            _itemLabel = value;
        }
        public function get itemLabel():String
        {
            return _itemLabel;
        }      
    }
}


위 예제는 Event를 이용한 컴포넌트이다. 앞서 언급한 예제와 달리 새로 Event를 만들었고 그 Event는 두개의 값, 즉 StateComboBox의 itemLabel과 itemIndex값을 Event Dispatch하기전에 설정한다. 이렇게 Event를 사용하면 앞의 2개 예제와 달리 TextArea를 컴포넌트 내에서 접근할 필요가 없다. 즉, 독립성이 보장된다. 여기서 만든 StateComboBox 컴포넌트는 어디서든 사용이 가능하다.


마무리


컴포넌트의 필요성과 조건, 그리고 독립성(비종속성)에 대해서 언급했다.
프 로젝트를 하게 되면 이벤트를 설계하는 것이 귀찮아서 컴포넌트간 종속적이도록 만드는 경우가 많을 것이라 생각한다. 하지만 잘 설계된 컴포넌트는 유지보수 및 재사용이 편리해진다는 것을 생각하면 컴포넌트간 독립성을 보장하는 것이 얼마나 중요한지 알 수 있을 것이라 생각한다.

자, 그럼 우리함께 외치자! 컴포넌트 만들때는 독립성을 보장하자!


참고내용

Flex Component간 종속성을 없애보자 (Event 사용하자)
Application 오브젝트에의 액세스
커스텀 컴퍼넌트 작성
나쁜남자님의 "Flex Component간 종속성에 대한 약간 다른 견해"


글쓴이 : 지돌스타(http://blog.jidolstar.com/223 

Flex에서 namespace를 사용하는 예제

FLEX/TIP 2008/06/14 11:07 Posted by <!--r'i"z&i\n+#]]x juree23

flex의 SDK를 보면 변수 또는 함수에 internal, public, private, protected 대신 mx_internal 접근권한자가 붙어 있는 것을 확인할 수 있을 것이다.

이것은 namespace이다.
즉, 이 namespace를 사용하는 모든 class에서는 접근이 가능하고 반대로 namespace를 사용하지 않는 class에서는 사용이 불가능하다.

flex에서 사용하는 namespace는 다음 3가지 경우에 사용된다.

  1. XML Object에서 namespace접두사와 namespace를 식별하는 URI를 관련짓는데 사용한다.
  2. 같은 이름의 함수명 또는 변수를 구분하는데 사용한다.
  3. 서로 다른 package에 위치한 class에서 변수 또는 함수를 참조하는데 사용한다. 이러한 경우 외부에 사용하는 것은 금지하기 위함이다.

1, 2번 항목에 대해서는 http://flexdocs.kr/docs/flex2/langref/Namespace.html  에 있는 예제를 참고하길 바란다.


여기서는 3번만 하나의 예시를 들어주도록 하겠다.

다른 package에 있는 클래스, 즉 com.jidolstar.comp1에 Comp1클래스와 com.jidolstar.comp2에 Comp2클래스가 있다고 가정하자.

위의 2개 Class는 다음과 같은 관계와 조건을 가진다.

  1. Comp1, Comp2 두 클래스는 다른 package에 있다.
  2. Comp2는 Comp1을 객체로 생성하여 Comp1에서 정의한 ns_var:String 변수를 참고할 수 있게 하고자 한다.
  3. Comp1를 Application에서 객체를 생성해서 Comp1의 변수인 ns_var를 참고할 수 없다.


위 조건을 만족하기 위한 접근자(public,private와 같은)를 무엇으로 해야할지 생각해보자.
첫번째, internal : 일단 두 Class가 다른 package에 있으므로 internal로 해서는 안된다.
두번째, private : ns_var를 private로 하면 Comp1 클래스에서만 참고할 수 있으므로 위 조건을 만족할 수 없다.
세번째, protected : 상속관계가 아니므로 protected를 사용하면 안된다.
네번째, public : ns_var를 Comp2외에 다른 곳에서 참고가 불가능하므로 public으로도 안된다.

헉.... 우리가 잘 알고 있는 internal, private, protected, public 모든 접근자로는 위의 조건을 만족시킬 수 없다.
이런 경우에 해결할 수 있는 방법이 바로 namespace이다.
따로 설명은 안하겠다. 다음 예제를 보고 이해했으면 한다. 사실 설명하기 귀찮아서 ㅡㅡ;
결과는 Debug모드에서 Console창에서 This is a namespace example 문자이 나오는 것이 전부이다. ^^


ex_internal.as (Language : java)
package com.jidolstar.core
{
    public namespace ex_internal = "http://jidolstar.com/2007/";
}


 

Comp1.as (Language : java)
package com.jidolstar.comp1
{
    import com.jidolstar.core.*;   
    use namespace ex_internal;
   
    public class Comp1
    {
        ex_internal var ns_var:String;
        public function Comp1()
        {
            ns_var = "This is a namespace example";
        }
    }
}


Comp2.as (Language : java)
package com.jidolstar.comp2
{
    import com.jidolstar.core.*;
    import com.jidolstar.comp1.Comp1;
    use namespace ex_internal;
   
    public class Comp2
    {
        private var comp1:Comp1;
        public function Comp2()
        {
            comp1 = new Comp1;
            trace(comp1.ns_var);
        }
    }
}



ExNameSpace.mxml (Language : xml)
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()">
    <mx:Script>
        <![CDATA[
            import com.jidolstar.comp2.Comp2;
            import com.jidolstar.comp1.Comp1;
           
            public function init():void
            {
                var comp2:Comp2 = new Comp2;
                var comp1:Comp1 = new Comp1;
                //trace(comp1.ns_var); //->에러걸림, 왜냐하면 Comp1의 ns_var은 ex_internal 네임스페이스로 묶여있기 때문
            }
        ]]>

    </mx:Script>   
   
</mx:Application>
 

ExNamespace.zip

위의 예제 프로그램이다. 새프로젝트를 만들고 import하면 된다.


글쓴이 : 지돌스타(http://blog.jidolstar.com/219 

[Flex] 동영상 화면 캡쳐후 서버에 전송하는 방법

FLEX/TIP 2008/06/14 11:06 Posted by <!--r'i"z&i\n+#]]x juree23
사용자 삽입 이미지


Flex의 VideoDisplay 클래스를 이용하여 재생되는 화면을 캡쳐하여 리스트화 하고 리스트된 캡쳐화면을 서버에 전송하는 프로그램을 교육용으로 만들어 보았다.

VideoDisplay 를 통해 로드된 FLV 영상이 Play 할때에 총 4군데에 Que Point를 두어서 그 지점에서 자동으로 화면을 캡쳐하도록 만들었다. 캡쳐된 화면은 List컨트롤에 itemRenderer를 이용해 추가되며 캡쳐이미지를 1개 선택후 저장방식(jpg, png)을 설정후 저장하기 하면 서버로 JPG또는 PNG형태로 HttpService를 통해 POST방식으로 전송된다. 전송된 데이터는 PHP에서 POST방식으로 받고 그 파일을 지정된 디렉토리에 fwrite()함수와 base64decode()함수를 이용해 저장한다. 저장이 완료되면 php는 반환값으로 파일명을 Flex로 돌려주는데 파일명은 "자신의 아이피_마이크로타임.확장자" 형태로 온다. 그럼 Alert.show()를 통해 화면에 뜨는데 이 파일명을 복사하면 웹브라우져에서 서버에 잘 전송되었는지 확인이 가능하겠다.

사용자 삽입 이미지

서버 프로그램은 Flex와 상관없이 Java든 ASP든 어느것을 써도 상관없다. php를 잘 모르신다면 자신있는 웹언어로 만들기 바란다.

제공되는 소스로 부터 다음을 알 수 있다.
  1. VideoDisplay 사용법
    - 볼륨조정 : VSlider를 이용해 VideoDisplay의 volumn속성을 제어한다.
    - PlayHead관련 : playHead 이벤트를 받아 totalTime 및 time값을 ProgressBar에 적용한다.
    - QuePoint사용법 : VideoDisplay에 QuePoint를 설정하면 특정시간에 이벤트를 줄 수 있다. QuePoint를 설정하는 방법과 QuePoint Event를 이용해 그 시간에 화면을 자동캡쳐한다.
    - 상태변화 : VideoDisplay가 상태변화, 즉 play, stop같은 상태가 변화가 될때 발생하는 상태변화 이벤트의 Type을 TextArea에 표시해줘서 어떤 상태변화가 있는지 확인한다.
  2. BitmapData를 이용한 화면 캡쳐방법
    VideoDisplay는 UIComponent를 상속받았기 때문에 UIComponent를 상속받은 모든 객체는 BitmapData를 만들 수 있다.
  3. 캡쳐된 화면을 서버로 전송하는 방법
    BitmapData로 캡쳐된 화면은 JPGEncoder및 PNGEncoder를 이용하여 JPG또는 PNG형태로 변환후 데이타를 서버로 전송한다.
  4. 전송된 이미지를 서버에 저장하는 방법
    여기에 있는 예제는 PHP를 사용했다. Flex로부터 받은 이미지파일을 서버의 특정디렉토리에 저장하도록 한다.
아래 링크에서 VideoDisplay, QuePoint, BitmapData에 대해 참고할 수 있을것이다.
http://flexdocs.kr/docs/flex2/langref/m ··· lay.html
http://flexdocs.kr/docs/flex2/docs/00000546.html
http://flexdocs.kr/docs/flex2/langref/m ··· ger.html
http://flexdocs.kr/docs/flex2/langref/f ··· ata.html
https://www.cynergysystems.com/blogs/page/andrewtrice?entry=flex_2_bitmapdata_tricks_and


소스는 아래 링크를 통해 참고하기 바란다. 주석을 간단하게 달아놓았으니 공부하는데 도움이 될 것이라 생각한다.



글쓴이 : 지돌스타(http://blog.jidolstar.com/215 )

Flex] ExternalInterface를 이용한 Javascript와 통신

FLEX/TIP 2008/06/14 11:06 Posted by <!--r'i"z&i\n+#]]x juree23
사용자 삽입 이미지



Flex나 Flash를 하다보면 Javascript와 서로 통신할 필요가 있다. 이때 사용하는 클래스가 ExternalInterface이다. 아래코드는 ExternalInterface를 이용한 예제이다.

Flex Builder에서 html-template 폴더에 있는 내용은 컴파일시 bin폴더에 그대로 컴파일 결과물이 나온다.
가 령 html-template폴더 내에 index.template.html은 bin폴더안 프로젝트명.html 으로 변환되어 나온다. index.template.html은 Flex결과물인 swf를 출력하기 위한 기본뼈대html문서이다. mx:Application에서 설정한 높이, 폭가 index.template.html 내에 $(width), $(height), $(application)이 컴파일후 각각 100%, 100%, 프로젝트명 등으로 변경되어 bin 디렉토리에 프로젝트명.html문서가 만들어 지게 된다.

이 사실을 잘 알고 있다면 쉽게 ExternalInterface를 연습하는데 큰 무리가 없다고 본다.

ExternalInterface에 대해 더 자세히 알고 싶다면 http://flexdocs.kr  에서 ExternalInterface로 검색해보길 바란다. 예제 및 도큐먼트를 참고할 수 있을 것이다.


ExExternalInterface.mxml (Language : java)
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="600" height="350" creationComplete="init()">

    <mx:Script>
        <![CDATA[
            public function init():void
            {
                txtMsg.text += "초기화중...\r";
                if( ExternalInterface.available )
                {
                    ExternalInterface.addCallback("sendToActionScript", receivedFromJavaScript);
                    if( checkJavaScriptReady())
                    {
                        txtMsg.text += "Javascript가 준비됨\r";
                    }
                    else
                    {
                        txtMsg.text += "JavaScript가 준비되지 못했음 대기 \n";
                        var readyTimer:Timer = new Timer(100, 0);
                        readyTimer.addEventListener(TimerEvent.TIMER, timerHandler);
                        readyTimer.start();      
                    }
                }
                else
                {
                    txtMsg.text += "External Interface를 사용할 수 없음\r";
                }
            }      
           
            private function receivedFromJavaScript(value:String):void
            {
                txtMsg.text += "JavaScript says: " + value + "\r";
      }
     
            private function checkJavaScriptReady() :Boolean
            {
                var isReady:Boolean = ExternalInterface.call("isReady");
                return isReady;
            }
            
            private function timerHandler(event:TimerEvent) :void
            {
                txtMsg.text += "자바스크립트 상태 Check중...\r";
                var isReady:Boolean = checkJavaScriptReady();
                if (isReady)
                {
                    txtMsg.text += "JavaScript가 준비됨. \r";
                    Timer(event.target).stop();
                }
            }
              
      private function clickHandler(event:MouseEvent) :void
      {
                if (ExternalInterface.available)
                {
                    ExternalInterface.call("sendToJavaScript", txtName.text);
                    txtName.text ="";
                }
            }
        ]]>
    </mx:Script>
    <mx:Style>
        Application
        {
            fontSize:12pt;
        }
    </mx:Style>
    <mx:TextInput x="10" y="10" id="txtName" width="189.5"/>
    <mx:Button x="207.5" y="10" label="자바스크립트로 보내기" id="btnSendToJS" width="146" height="24" click="clickHandler(event)"/>
    <mx:TextArea id="txtMsg" x="10" y="57" text="text" width="580" height="283"/>
   
</mx:Application>
 


굵게 표시된 부분이 추가된겁니다. body에 onload="pageInit()"이 추가되었다는 것을 꼭 확인하세욤~ ^^
index.template.html (Language : html4strict)
<!-- saved from url=(0014)about:internet -->
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>${title}</title>
<script src="AC_OETags.js" language="javascript"></script>
<style>
body { margin: 0px; overflow:hidden }
</style>
<script language="JavaScript" type="text/javascript">
<!--
// -----------------------------------------------------------------------------
// Globals
// Major version of Flash required
var requiredMajorVersion = ${version_major};
// Minor version of Flash required
var requiredMinorVersion = ${version_minor};
// Minor version of Flash required
var requiredRevision = ${version_revision};
// -----------------------------------------------------------------------------
// -->

</script>


<script language="JavaScript">
     var jsReady = false;
     function isReady()
     {
         return jsReady;
     }
     function pageInit()
     {
         jsReady = true;
         document.forms["form1"].output.value += "\n" + "JavaScript is ready. \n";
     }
     function thisMovie(movieName)
     {
         if(navigator.appName.indexOf("Microsoft") != -1)
         {
             return window[movieName];
         }
         else
         {
             return document[movieName];
         }
     }
     function sendToActionScript(value)
     {
         thisMovie("${application}").sendToActionScript(value);
         document.forms["form1"].input.value = "";
     }
     function sendToJavaScript(value)
     {
         document.forms["form1"].output.value += "ActionScript says:" + value + "\n";
     }
</script>

</head>

<body scroll="no" onload="pageInit()">
<script language="JavaScript" type="text/javascript" src="history.js"></script>
<script language="JavaScript" type="text/javascript">
<!--
// Version check for the Flash Player that has the ability to start Player Product Install (6.0r65)
var hasProductInstall = DetectFlashVer(6, 0, 65);

// Version check based upon the values defined in globals
var hasRequestedVersion = DetectFlashVer(requiredMajorVersion, requiredMinorVersion, requiredRevision);


// Check to see if a player with Flash Product Install is available and the version does not meet the requirements for playback
if ( hasProductInstall && !hasRequestedVersion ) {
    // MMdoctitle is the stored document.title value used by the installation process to close the window that started the process
    // This is necessary in order to close browser windows that are still utilizing the older version of the player after installation has completed
    // DO NOT MODIFY THE FOLLOWING FOUR LINES
    // Location visited after installation is complete if installation is required
    var MMPlayerType = (isIE == true) ? "ActiveX" : "PlugIn";
    var MMredirectURL = window.location;
    document.title = document.title.slice(0, 47) + " - Flash Player Installation";
    var MMdoctitle = document.title;

    AC_FL_RunContent(
        "src", "playerProductInstall",
        "FlashVars", "MMredirectURL="+MMredirectURL+'&MMplayerType='+MMPlayerType+'&MMdoctitle='+MMdoctitle+"",
        "width", "${width}",
        "height", "${height}",
        "align", "middle",
        "id", "${application}",
        "quality", "high",
        "bgcolor", "${bgcolor}",
        "name", "${application}",
        "allowScriptAccess","always",
        "type", "application/x-shockwave-flash",
        "pluginspage", "http://www.adobe.com/go/getflashplayer"
    );
} else if (hasRequestedVersion) {
    // if we've detected an acceptable version
    // embed the Flash Content SWF when all tests are passed
    AC_FL_RunContent(
            "src", "${swf}",
            "width", "${width}",
            "height", "${height}",
            "align", "middle",
            "id", "${application}",
            "quality", "high",
            "bgcolor", "${bgcolor}",
            "name", "${application}",
            "flashvars",'historyUrl=history.htm%3F&lconid=' + lc_id + '',
            "allowScriptAccess","always",
            "type", "application/x-shockwave-flash",
            "pluginspage", "http://www.adobe.com/go/getflashplayer"
    );
  } else {  // flash is too old or we can't detect the plugin
    var alternateContent = 'Alternate HTML content should be placed here. '
    + 'This content requires the Adobe Flash Player. '
    + '<a href=http://www.adobe.com/go/getflash/>
Get Flash</a>';
    document.write(alternateContent);  // insert non-flash content
  }
// -->
</script>
<noscript>
    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
            id="${application}" width="${width}" height="${height}"
            codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab">

            <param name="movie" value="${swf}.swf" />
            <param name="quality" value="high" />
            <param name="bgcolor" value="${bgcolor}" />
            <!--<param name="allowScriptAccess" value="sameDomain" />-->
            <param name="allowScriptAccess" value="always" />
            <embed src="${swf}.swf" quality="high" bgcolor="${bgcolor}"
                width="${width}" height="${height}" name="${application}" align="middle"
                play="true"
                loop="false"
                quality="high"
                allowScriptAccess="sameDomain"
                type="application/x-shockwave-flash"
                pluginspage="http://www.adobe.com/go/getflashplayer">

            </embed>
    </object>
</noscript>
<iframe name="_history" src="history.htm" frameborder="0" scrolling="no" width="22" height="0"></iframe>


<form name="form1" onsubmit="return false;">
     <input type="text" name="input" value="" />
     <input type="button" value="Send" onclick="sendToActionScript(this.form.input.value);" /><br />
     <textarea cols="60" rows="20" name="output" readonly="true">Initializing...</textarea>
</form>
</body>
</html>
 

글쓴이 : 지돌스타(http://blog.jidolstar.com/214