http://code.google.com/p/swfobject/
여기서 2.1버전을 다운로드할 수 있습니다.
기존에 1.5에서 사용하는 방식과 완전이 틀려졌습니다.

더욱 간편해지고 더욱 쉬워졌습니다.
해당 파일을 받고 압축을 풀면 매우 쉽게 예제가 나와있습니다.
[code]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
    <head>
        <title>SWFObject 2 dynamic publishing example page</title>
        <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
        <script type="text/javascript" src="swfobject.js"></script>
        <script type="text/javascript">
        swfobject.embedSWF("test.swf", "myContent", "300", "120", "9.0.0", "expressInstall.swf");
        </script>
    </head>
    <body>
        <div id="myContent">
            <h1>Alternative content</h1>
            <p><a href="http://www.adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p>
        </div>
    </body>
</html>
[/code]
핵심부분은 저기 swfobject객체의 embedSWF메소드를 호출하면 됩니다.
저런식으로. 아주 간단해요.

만약 파라메터나 flashvars를 넘기고 싶다면
[code]
var flashvars = {
  bridgeName: "mudchobo"
};
var params = {
  menu: "false"
};
var attributes = {};

swfobject.embedSWF ( "test.swf", "myContent", "300", "120", "9.0.0",
    "expressInstall.swf", flashvars, params, attributes );
[/code]
이런식으로 파라메터값을 넘겨줄 수 있습니다.

어떤분은 기존 flex3가 생성하는 html-templete을 기존방식이 아닌 swfobject방식으로 바꿔서 templete을 재구성했더라구요.
http://olegflex.blogspot.com/2008/06/swfobject-2-flex-template.html
여기서 받을 수 있습니다.

기존에 AC_FL_RunContent란 메소드를 호출하는 index.templete.html파일을 보면 정말 복잡합니다. 하지만 저 템플릿방식으로 변경하면 소스코드도 이해하기 쉽고, 나중에 javascript를 삽입해서 테스트를 해보고 싶을 때 더욱 쉽게 작업할 수 있겠죠.
 
Posted by 머드초보
,
 
열이아빠님 블로그를 구독하고 있는데요. 플렉스에서 좋은 프레임워크가 없을까 하는 생각에 갑자기 열이아빠님의 블로그에 포스팅한 '10 가지 플렉스 디버깅 도구 및 프레임워크'가 생각이 났습니다.
여기서 나온게 Mate Framework라는 것인데, 발음은 메이트가 아닌 마떼라고 발음하는 것이라고 열이아빠님께서 말씀하셨습니다. 조또마떼! 일본애니메이션보면 디게 많이 나오는데...잠만 기댕겨?라는 뜻인듯?-_-;
Mate Flex Framework 공식홈페이지 http://mate.asfusion.com/
Mate Flex Framework 공식홈페이지에 가보면,
Mate is a tag-based, event-driven Flex framework.
라고 되어있습니다. tag기반에 event driven 플렉스 프레임워크라는 겁니다.
개발 방식도 우선 Service와 Event를 정의한 EventMap, 그리고, View로 나눠져 있습니다. MVC랑 비슷한 것 같은데, View에서 이벤트가 발생하면 이벤트를 정의해놓은 EventMap에서 찾아서 Event를 발생하죠. 이 EventMap에서는 해당 Service를 호출하는 등의 구조로 되어있어요. 제가 설명하는게 맞는지는 모르겠지만, 대충 저런 구조인 듯하네요. '서비스는 WAS없이도 돌아간다라고 생각하고 짜야된다가 현재의 결론입니다'라고 허광남씨가 말했던 것 처럼 여기서도 Service는 다른 것에 영향없이 돌아가야하는 겁니다.
이 Service는 BlazeDS를 이용한 RemoteObject가 될 수 있고, HTTPService를 이용한 서비스가 될 수 있고, WebService가 될 수 있습니다. 물론, Flex에서 만든 어떤 Method가 될 수도 있습니다.

그러면 해당 서비스를 EventMap에 정의를 해놓고, View에서는 Event를 발생시키기만 하면 되는 겁니다.
백날 말로 하는 것보다 코드로 보는게 빠릅니다-_-;

New -> Project -> Flex Project 를 선택!
Project Name은 HelloMate라고 하고, Web application을 선택하고, Application Server는 NONE으로 Finish고고싱!
Mate Flex Framework공식 홈페이지에 가면 downloads를 클릭하면, swc파일이 있는데요. 이것을 libs폴더에 복사합니다.

우선 패키지를 만들어봅시다.
src에 New -> Folder를 선택해서 events, maps, services, views를 만듭니다.
우선 events에 Event클래스를 하나 만들어봅시다.
New -> ActionScript Class선택 후 Name은 HelloEvent로 하고, Superclass는 flash.events.Event를 선택!
events/HelloEvent.as
[code]
package events
{
    import flash.events.Event;

    public class HelloEvent extends Event
    {
        /* Constants */
        public static const SAY:String = "sayHelloEvent";
       
        /* Properties */
        public var name:String;
       
        public function HelloEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
        {
            super(type, bubbles, cancelable);
        }
    }
}
[/code]
SAY라는 상수를 하나 만들어서 sayHelloEvent라고 합시다. 이 이름을 통해 이벤트를 구분합니다.
Properties는 event를 발생할 때 properties값을 지정해서 EventMap에 정의한 메소드에 파라메터로 넣기 위해서 사용합니다.

이제 service를 만들어봅시다.
New -> ActionScript Class선택 후 name은 HelloService라고 합시다.
services/HelloService.as
[code]
package services
{
    public class HelloService
    {
        public function sayHello(name:String):String
        {
            return "Hello! " + name + ", I'm so sorry but I love dagujitmal";
        }
    }
}
[/code]
단순히 name을 파라메터로 받아서 Hello!를 붙여줘서 리턴해주는 메소드입니다.

이제 view를 만들어봅시다.
New -> File -> MXML Component선택! Filename은 HelloBox로 하고, Based on은 조낸 귀찮으니까 VBox로 하고, 사이즈도 그냥 그대로 갑시다-_-;
views/HelloBox.mxml
[code]
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
    xmlns:mate="http://mate.asfusion.com/"
    width="400" height="300"
    horizontalAlign="center"
    verticalAlign="middle">
    <mx:Script>
        <![CDATA[
            import events.HelloEvent;
           
            private function sayHello():void
            {
                helloDispatcher.generateEvent();
            }
           
            private function helloResult(result:String):void
            {
                myLabel.text = result;
            }
        ]]>
    </mx:Script>
   
    <!-- Dispatcher -->
    <mate:Dispatcher id="helloDispatcher" generator="{HelloEvent}" type="{HelloEvent.SAY}">
        <mate:ResponseHandler  type="helloResultResponse" response="helloResult(event.helloResult)" />
        <mate:eventProperties>
            <mate:EventProperties name="{input.text}" />
        </mate:eventProperties>
    </mate:Dispatcher>
   
    <mx:TextInput id="input" enter="sayHello();"/>
    <mx:Button id="button" label="hello" click="sayHello();"/>
    <mx:Label id="myLabel" text="이름을 입력하세요" width="295"/>
</mx:VBox>
[/code]
mate에서 제공하는 Dispatcher기능을 쓰기 위해 네임스페이스를 지정해줍니다.
그리고, <mate:Dispatcher />태그가 있는데요. 여기서 자세히 보면, HelloEvent를 발생하고, 이벤트 종류는 HelloEvent.SAY인 것이죠. 이 이름은 단순 EventMap에 있는 것이랑 매핑하기위해서 쓰인 것 같구요.
이 이벤트를 발생할 때 Properties값은 input에 있는 text값을 넘깁니다. 방금 위에서 HelloEvent를 정의할 때 Properties값 name을 선언했는데, 저렇게 EventProperties에 지정을 해주면 저 값을 물고 들어갑니다.
그다음 그 응답값을 받을 ResponseHandler를 정의해주는데, helloResultResponse는 EventMap에 있는 것이랑 매핑하기 위한 이름이구요, response는 실제 메소드를 호출해줍니다. event.helloResult값은 EventMap에서 정의한 Properties값이구요. 여기서 설명하는 것보다 EventMap을 실제로 보면 이해가 훨씬 빠릅니다.

New -> MXML Component를 선택, Filename은 MainEventMap 그냥 Finish.
<mx:Canvas를 EventMap으로 고칩니다.
maps/MainEventMap.mxml
[code]
<?xml version="1.0" encoding="utf-8"?>
<EventMap xmlns:mx="http://www.adobe.com/2006/mxml"
    xmlns="http://mate.asfusion.com/">
    <mx:Script>
        <![CDATA[
            import services.HelloService;
            import events.HelloEvent;
        ]]>
    </mx:Script>
   
    <EventHandlers type="{HelloEvent.SAY}">
        <MethodInvoker generator="{HelloService}" method="sayHello" arguments="{event.name}" />
        <ResponseAnnouncer type="helloResultResponse">
            <Properties helloResult="{lastReturn}" />
        </ResponseAnnouncer>
    </EventHandlers>
   
</EventMap>
[/code]
EventHandlers를 정의해줬는데 여기서 type은 아까 dispatcher에서 정의한 type과 같은 HelloEvent.SAY가 되겠죠. 그다음 MethodInvoker는 메소드를 호출하는 태그입니다. 위에서 언급했듯이 메소드 말고, RemoteObject나 HTTPService, WebService도 다 됩니다.
generator는 클래스를 적어주고, method에 메소드 이름을 적습니다. arguments에는 파라메터값인데 event.name은 해당 event에서 받은 name을 말하는겁니다. 우리가 Dispatcher에 정의한 name에 input.text값을 넣었으니 그게 들어가는 겁니다. 그다으메 ResponseAnnouncer는 응답을 정의하는 건데, 그 type이 아까 위에서 정의한 그 타입과 일치해야합니다. Properties의 helloResult도 위에 Dispatcher에서 정의한 것과 동일한 이름이여야겠죠. 그러면 저 Properties에 값이 들어가는데 여기서 보면 lastReturn이라고 써있는데, 위에 메소드에서 리턴한 값을 말하는 겁니다.
저렇게 해주면 끝납니다.

이제 마지막으로 main을 작성해봅시다.
HelloMate.mxml
[code]
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    layout="absolute"
    xmlns:view="views.*"
    xmlns:maps="maps.*">
   
    <!-- Event Maps -->
    <maps:MainEventMap />
   
    <!-- views -->
    <view:HelloBox />
   
</mx:Application>
[/code]
EventMap을 추가하고, View만 추가해주면 끝납니다.
실행해봅시다.
사용자 삽입 이미지
암쏘쏘리 벗알러뷰다거짓말.......
 
Posted by 머드초보
,
 

http://labs.adobe.com/ 여기에 가면 어도비에서 어떤 것을 삽질하고 있는지 한눈에 알 수 있죠.
지금 삽질한 것 리스트 중에 Adobe AIR for Linux라는것이 있는데 Linux에서도 AIR를 가능하게 하는 것이죠.
AIR는 원래 2개의 OS만 지원을 합니다. OSX랑 WINDOWS죠.

근데 리눅스에서도 지원이 되게 삽질하려는가봅니다.
그래서 이번에 우분투를 새로 설치를 해봐서 거기다가 AIR 런타임을 한번 설치해봤습니다.
설치를 하고 제가 만든 MP3플레이어를 실행했는데 너무 잘 돌아가는군요.

사용자 삽입 이미지

어쨌든 소리도 잘 나오고 잘 되네요 ^^

덤으로 플렉스 빌더도 깔았는데, 이건 이클립스가 있어야 되더군요. 그래서 같이 깔았는데 이것도 역시 잘 되는군요. ^^ 리눅스도 이제 서버용으로만이 아닌 데스크탑용으로 자리 잡을 듯 하군요 ^^

 
Posted by 머드초보
,
 

AIR로 사운드 재생이 가능한 것을 알았습니다-_-;
초초초초초간단한 MP3플레이어를 만들어봤습니다.
사운드 컨트롤하기 참 쉽게 되어있군요.

아래는 대략 소스입니다.
[code]
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
 layout="absolute" width="400" height="300" viewSourceURL="srcview/index.html">

 <mx:Script>
  <![CDATA[
   import mx.controls.Alert;
   
   private var file:File = new File();
   private var req:URLRequest;
   private var sound:Sound;
   private var channel:SoundChannel;
   private var pausePosition:int;
   
   public function findFile():void {
    try {
     file.addEventListener(Event.SELECT, selectFileHandler);
     file.browse();
    } catch (error:Error) {
     Alert.show("파일열기 실패했습니다.");    
    }
   }
   
   public function selectFileHandler(event:Event):void {
    if (channel != null) {
     channel.stop();
    }
    sound = new Sound();
    sound.addEventListener(Event.COMPLETE, onSoundLoaded);
    sound.addEventListener(ProgressEvent.PROGRESS, onLoadProgress);
    sound.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
   
    pausePosition = 0;
    textFileName.text = event.currentTarget.nativePath;
    sound.load(new URLRequest(event.currentTarget.nativePath));
    btnPlay.enabled = true;
   }
   
   public function onLoadProgress(event:ProgressEvent):void {
       var loadedPct:Number = Math.round(100 * (event.bytesLoaded / event.bytesTotal));
       trace("The sound is " + loadedPct + "% loaded.");
     fileLoadingPB.setProgress(loadedPct, 100);  
   }
   
   public function onSoundLoaded(event:Event):void {
    var localSound:Sound = event.target as Sound;
    textArtist.text = localSound.id3.artist;
    textSongName.text = localSound.id3.songName;
   }
   
   public function onIOError(event:IOErrorEvent):void {
    Alert.show("The sound could not be loaded: " + event.text);
       trace("The sound could not be loaded: " + event.text);
   }
   
   public function btnPlayClickHandler(event:Event):void {
    btnPlay.enabled = false;
    btnStop.enabled = true;
    channel = sound.play(pausePosition);
    addEventListener(Event.ENTER_FRAME, onEnterFrame);
    channel.addEventListener(Event.SOUND_COMPLETE, onPlaybackComplete);  
   }
   
   private function onEnterFrame(event:Event):void {
    var estimatedLength:int =
           Math.ceil(sound.length / (sound.bytesLoaded / sound.bytesTotal));
       var playbackPercent:uint =
           Math.round(100 * (channel.position / estimatedLength));
          playPB.setProgress(playbackPercent, 100);
       trace("Sound playback is " + playbackPercent + "% complete.");
   }
   
   private function onPlaybackComplete(event:Event):void {
    btnPlay.enabled = false;
    btnStop.enabled = false;
    trace("The sound has finished playing.");
       removeEventListener(Event.ENTER_FRAME, onEnterFrame);
   }
   
   public function btnStopClickHandler(event:Event):void {
    btnPlay.enabled = true;
    btnStop.enabled = false;
    pausePosition = channel.position;
    channel.stop();
   }
   
  ]]>
 </mx:Script>
 <mx:ProgressBar id="fileLoadingPB" x="125.5" y="160" mode="manual"/>
 <mx:ProgressBar id="playPB" x="125.5" y="196" mode="manual" label="PLAYING %1%"/>
 <mx:Label x="72.5" y="196" text="재생바" height="28" width="45" textAlign="right"/>
 <mx:Label x="72.5" y="160" text="파일읽기" height="28" textAlign="right"/>
 <mx:Label x="82.5" y="35" text="제목 :" width="44" textAlign="right"/>
 <mx:Label x="82.5" y="61" text="가수명 :" textAlign="right"/>
 <mx:Label x="82.5" y="87" text="파일명 :" textAlign="right"/>
 <mx:Button id="btnPlay" x="91.5" y="248" label="플레이" click="btnPlayClickHandler(event);" enabled="false"/>
 <mx:Button id="btnStop" x="158.5" y="248" label="일시정지" click="btnStopClickHandler(event);" enabled="false"/>
 <mx:Button x="236.5" y="248" label="파일열기" click="findFile();"/>
 <mx:Text id="textSongName" x="134.5" y="35" text="KHJ 바보" width="191"/>
 <mx:Text id="textArtist" x="134.5" y="61" text="KHJ 돼지" width="191"/>
 <mx:Text id="textFileName" x="134.5" y="87" text="KHJ 멍충이" width="191"/>
 
</mx:WindowedApplication>
[/code]
소스를 보면 그리 어렵지 않습니다.
Sound라는 클래스가 있습니다.
사운드객체를 하나 선언하고, 파일명으로 URLRequest를 이용해 객체를 생성해서 그걸 Sound객체의 load메소드를 통해서 로드를 한 다음에, play만 해주면됩니다.

게다가 이것저것 자체적으로 지원해주는게 많습니다. 일시정지를 할 수 있게 stop을 하기전에 channal이라는 클래스를 통해 현재 position을 얻어오면 stop한다음에 그 포지션으로부터 다시 시작할 수 있습니다.

재생완료시 이벤트를 추가할 수 있고, 파일이 로드될 때 이벤트 등의 이벤트를 지원하는군요.

PS. AIR로 MP3플레이어만들면 더 멋있을 것 같은데-_-;

 
Posted by 머드초보
,
 

http://mudchobo.tomeii.com/tt/318

새로운 버전에서 방식이 바뀌었습니다.

여기위에것을 보고 하세요 ^^

우연히 지돌스타님 블로그를 구독하다가 좋은 정보가 있어서 보고 있었습니다.
Flex에서 db와 연동하는 좋은 드라이버가 있다는 정보입니다.
http://blog.jidolstar.com/312


그래서 제가 삽질해봤습니다-_-;

보통 DB랑 연동하려면 JAVA, PHP, ASP 등 다른 언어와 연동이 필요합니다.
근데 이 asSQL이라는 것을 이용하면 그냥 Flex단에서 DB와 연결해줍니다.
우선 asSQL을 받아봅시다.
http://code.google.com/p/assql/
여기서 오른쪽에 보면 2.0.1버전용과 3.0.0버전용이 있습니다.
저는 Flex3으로 할 것이기에 3.0.0을 받아보도록 하겠습니다. assql_Beta2_Flex3.0.0.swc
DB에는 이런 테이블과 이런 데이터가 있다고 합시다.

[code]
CREATE TABLE `products` (
  `id` int(11) NOT NULL,
  `description` varchar(255) default NULL,
  `price` decimal(15,2) default NULL,
  PRIMARY KEY  (`id`),
  KEY `products_description` (`description`)
) ENGINE=MyISAM DEFAULT CHARSET=euckr;

INSERT INTO `products` (`id`, `description`, `price`) VALUES
(1, 'Lamp', 469.80),
(2, 'Table', 3502.62),
(3, 'Chair', 1061.12);
[/code]
그럼 플렉스 빌더를 실행합니다.
File -> New -> Flex Project 선택합니다. Project name은 FlexMysqlTest 라고 합시다.
Web application선택하고, Application server type은 None으로 하고 Finish 선택!

libs폴더가 있는데요. 아까 받은 assql_Beta2_Flex3.0.0.swc 파일을 libs폴더에 복사합니다.

[code]
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
 creationComplete="init();" width="400" height="400">
 <mx:Script>
  <![CDATA[
   import mx.controls.Alert;
   import com.maclema.mysql.events.MySqlErrorEvent;
   import com.maclema.mysql.events.MySqlEvent;
   import mx.collections.ArrayCollection;
   import com.maclema.mysql.ResultSet;
   import com.maclema.mysql.Statement;
   import com.maclema.mysql.Connection;
 
   [Bindable]  
   private var ac:ArrayCollection;
   private var con:Connection;
   private var st:Statement;
     
   private function init():void {
    con = new Connection("DB주소", 3306,
      "DB아이디", "DB비밀번호", "DB이름");
    con.addEventListener(Event.CONNECT, onConnect);
    con.addEventListener(MySqlErrorEvent.SQL_ERROR, onError);
    con.connect();
   }
   
   private function onConnect(e:Event):void {
        st = con.createStatement();
        st.addEventListener(MySqlEvent.RESULT, onResult);
        st.addEventListener(MySqlEvent.RESPONSE, onResponse);
        st.addEventListener(MySqlErrorEvent.SQL_ERROR, onError);
 
    st.executeQuery("SELECT id, description, price FROM products");
   }
   
   private function onResult(event:MySqlEvent):void {
    //FOR SELECT
    var resultset:ResultSet = event.resultSet;
    ac = resultset.getRows();
   }
   
   private function onResponse(event:MySqlEvent):void {
    //FOR INSERT, UPDATE, etc.
   }
   
   private function onError(event:MySqlErrorEvent):void {
    Alert.show(event.text);
   }
  ]]>
 </mx:Script>
 
 <mx:DataGrid id="dg" width="100%" height="100%" dataProvider="{ac}"/>
 
</mx:Application>
[/code]
소켓을 이용해서 하는거라 connect를 호출하고 연결한 뒤 소켓으로 막 보내는 것 같아요.
어쨌든 저렇게 하면 되네요. 참 쉽죠?(밥로스 버전-_-)

INSERT, UPDATE 와 SELECT는 이벤트가 서로 틀립니다.
INSERT,UPDATE는 RESPONSE고, SELECT는 RESULT네요 ^^

사용자 삽입 이미지


 
Posted by 머드초보
,