こんにちは。
プロダクト&サービス事業部 リーダーの末田です。
初めての本格的な投稿なのですが、
今回はAdobe AIR/Flexでのドラッグ アンド ドロップについて書こうと思います。
弊社製品にeasyFiLEXというものがあるのですが、
そこで、ドラッグ アンド ドロップがしたいんだ! という強い要望があり、
Adobe AIR/Flexの技術を利用して実現しました。
いまどきだと、Ajaxでも実現できるのですが、今回はFlexを採用しました。
AIRとFlexそしてブラウザの関係ですが、AIRはローカルマシン上の環境、
FlexはAIR上、もしくはWebブラウザ上のFlash Player(Plugin)で動作します。
Webブラウザ上 → Flex
AIR → Flex
AIRの上ではFlexではない、通常のHTMLとJavaScriptでも動作します。
Flexを利用すると、Webブラウザ上でもローカルマシン上のAIRでも、
同じ技術でリッチなインタフェースを実現でき、
さらに、最初からドラッグ アンド ドロップがサポートされています。
Flexでは、Flexコンポーネント間のドラッグ アンド ドロップが簡単に実現できます。
しかしeasyFiLEXは、ローカルマシン上にあるファイルをWebアプリであるeasyFiLEXにアップロードして、
他の人とファイルをやり取りする仕組みのアプリケーションです。
ですので、実現したかったのは、ローカルマシンにある(例えばデスクトップにある)ファイルを
ドラッグしてブラウザ上に持って行き、ドロップすると、そのファイルがアップロードされる、
という操作を実現したかったのです。
しかし、ブラウザ上のFlexでは、コンポーネント間のドラッグアンドドロップは簡単にできますが、
ローカルマシン上のオブジェクトからFlexコンポーネント、または逆、といった環境の場合実現できないことがわかりました。
(もしできるのであればぜひ教えてください! ActiveXであれば実現できるようです)
| Flexコンポーネント | ローカルマシン上のオブジェクト | |
|---|---|---|
| Flexコンポーネント | ○ | × |
| ローカルマシン上のオブジェクト | × | - |
そこで、AIRの出番です。
ブラウザ上のFlexでは(おそらく)セキュリティ上の関係で、
ローカルマシン上にあるファイルにはアクセスできない仕様になっていると思われますが、
AIRはローカルマシンにインストールして利用するため、この制限がゆるくなっています。
なので、AIR上のFlexでは、Flexコンポーネントとローカルマシン上のオブジェクトの間でドラッグアンドドロップが可能です。
| Flexコンポーネント | ローカルマシン上のオブジェクト | |
|---|---|---|
| Flexコンポーネント | ○ | ○ |
| ローカルマシン上のオブジェクト | ○ | - |
せっかくなので、ドラッグ アンド ドロップを実現するコードを紹介したいと思います。
※対象バージョン/環境
Adobe AIR 1.5.1 SDK
Adobe Flex 3.3.0 SDK
コード全体
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | <?xml version="1.0" encoding="utf-8"?> <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="init()"> <mx:Script> <![CDATA[ private function init () : void { this.addEventListener(flash.events.NativeDragEvent.NATIVE_DRAG_ENTER, onDragEnter); this.addEventListener(flash.events.NativeDragEvent.NATIVE_DRAG_DROP, onDragDrop); } private function onDragEnter (event:flash.events.NativeDragEvent):void { if (event.target is InteractiveObject) { flash.desktop.NativeDragManager.acceptDragDrop(InteractiveObject(event.target)); } } private function onDragDrop (event:flash.events.NativeDragEvent):void { if(event.clipboard.hasFormat(ClipboardFormats.FILE_LIST_FORMAT)){ var list:Array = event.clipboard.getData(ClipboardFormats.FILE_LIST_FORMAT) as Array; for each (var file:flash.filesystem.File in list) { trace(file.nativePath); } } } ]]> </mx:Script> <mx:Panel width="100%" height="100%" layout="absolute"> </mx:Panel> </mx:WindowedApplication> |
イベントリスナーの設定
1 2 | this.addEventListener(flash.events.NativeDragEvent.NATIVE_DRAG_ENTER, onDragEnter); this.addEventListener(flash.events.NativeDragEvent.NATIVE_DRAG_DROP, onDragDrop); |
まず、2つのイベントリスナーを設定します。
flash.events.NativeDragEvent.NATIVE_DRAG_ENTER が、ドラッグしてきてオブジェクトの境界内に入った時
flash.events.NativeDragEvent.NATIVE_DRAG_DROP が、ドラッグしてきたアイテムをオブジェクトの上で離した時
の2つです。
AIR上とWeb上でまず違うのがここです。
そもそも、flash.events.NativeDragEventのイベントがAIRでしか発生しません。
私はここではまりました。
私はFlex Builderを使っているのですが、Flex Builderのデバッグモードで動作させた場合、
このイベントが発生しません。
一度リリースビルドを行い、インストールするとイベントが発生しました。
flash.events.NativeDragEvent.NATIVE_DRAG_ENTERイベント
このイベントは、ドラッグしてきてオブジェクトの境界内に入った時に発生します。
この際、ドラッグしてきてOKです、とシステムに知らさなければいけません。
1 | flash.desktop.NativeDragManager.acceptDragDrop(obj:InteractiveObject); |
を呼ぶことにより、ドラッグを受け付けることになります。
このメソッドを呼ぶと、マウスポインタが「+」マークのついたポインタに変わります。
flash.events.NativeDragEvent.NATIVE_DRAG_DROPイベント
このイベントは、実際にドロップされたときに発生します。
先の、NativeDragManager.acceptDragDrop()が事前に呼ばれていないと発生しません。
ドロップされたオブジェクトは、
1 | flash.events.NativeDragEvent.clipboard.getData(); |
で取得できます。
そのオブジェクトは、flash.desktop.Clipboardというクラスを経由して様々な情報を取得できます。
今回は、ローカルのファイル情報を取得しましたが、テキストデータやイメージデータ等も取得できます。
以上が、AIR/FlexでFlexコンポーネントとローカルマシン上のオブジェクトの間のドラッグ アンド ドロップを実現する方法です。
詳細はAIR/Flexのドキュメントにも詳しく書かれていますが、もひとつわかりにくい気もします。
それでは!





5月 29th, 2009 at 17:18
[...] AIR/Flex でドラッグ アンド ドロップ (1) [...]
6月 8th, 2009 at 13:25
[...] AIR/Flex でドラッグ アンド ドロップ (2) [...]
6月 26th, 2009 at 10:52
[...] AIR/Flex でドラッグ アンド ドロップ (3) [...]
10月 21st, 2009 at 19:03
[...] AIR/Flex でドラッグ アンド ドロップ (5) [...]