当社Webサイト

カテゴリー

Amazonサーチ

  • 05/18
    AIR, ActionScript, Flex, プログラム post by 末田 佳和 @ 2009 年 5 月 18 日 17:00

    こんにちは。
    プロダクト&サービス事業部 リーダーの末田です。

    初めての本格的な投稿なのですが、
    今回は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コンポーネント ローカルマシン上のオブジェクト
    Flexコンポーネント ×
    ローカルマシン上のオブジェクト × -

    そこで、AIRの出番です。
    ブラウザ上のFlexでは(おそらく)セキュリティ上の関係で、
    ローカルマシン上にあるファイルにはアクセスできない仕様になっていると思われますが、
    AIRはローカルマシンにインストールして利用するため、この制限がゆるくなっています。
    なので、AIR上のFlexでは、Flexコンポーネントとローカルマシン上のオブジェクトの間でドラッグアンドドロップが可能です。

    AIR上の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のドキュメントにも詳しく書かれていますが、もひとつわかりにくい気もします。

    それでは!

    あわせて読みたい

    Tags: , , , , ,

4 Responses

WP_Cloudy