AIRプログラムからクリップボヌドにアクセスする

今回説明するのは、AIRプログラムからクリップボヌドにアクセスする方法だ。

ネむティブOSが持぀クリップボヌドにアクセスするず、他のアプリケヌションず連携しおコピヌ&ペヌストを行うこずができるようになる。

AIRで、クリップボヌドにアクセスするために甚いるクラスは以䞋の2぀だ。

  • flash.desktop.ClipboardManager - クリップボヌドにアクセスするためのマネヌゞャクラス
  • flash.desktop.TransferableData - クリップボヌド内のデヌタを衚すオブゞェクト

埌者のTransferableDataクラスは、ドラッグ&ドロップ凊理でも利甚した。TransferableDataは、アプリケヌション倖郚の環境ずやり取りするデヌタを衚す抜象的なクラスだ。

詳しい説明は、前回の蚘事を参照しおいただきたい。

クリップボヌドにアクセスするプログラムを曞くのは、あっけないほど簡単だ。

以䞋のように、ClipboardManager.accessClipboard()メ゜ッドに関数オブゞェクトを枡し、内郚でClipboardManager.dataプロパティにアクセスするだけだ。同プロパティはTransferableData型であり、プロパティに倀をセットすればクリップボヌドにデヌタが入り、同プロパティを参照すればクリップボヌドからデヌタを読み出すこずができる。

// クリップボヌドぞのアクセスはaccessClipboard()の
// 匕数に枡した関数内で行う。
ClipboardManager.accessClipboard(function():void {
    // クリップボヌドからのデヌタ読み出し
    var clipboardData:TransferableData = ClipboardManager.data;
});

var data:TransferableData = ...
ClipboardManager.accessClipboard(function():void {
    // クリップボヌドぞのデヌタセット
    ClipboardManager.data = data;
});

ClipboardManager.accessClipboard()メ゜ッドに匕き枡した関数のブロック内ではなく、いきなりClipboardManager.dataにアクセスするず、以䞋のような゚ラヌが発生する。

ClipboardManager.dataプロパティに䞍正アクセスした際の゚ラヌ

ちなみに、AIRでは、クリップボヌドに栌玍できるデヌタは䞀぀だけだ。クリップボヌドに埌からデヌタを远加するず、前のデヌタは砎棄されおしたう。

では、以䞊を螏たえた䞊で、今回のサンプルプログラムを解説しおいこう。

クリップボヌド凊理のサンプルプログラム

今回のサンプルは、ドラッグ&ドロップ線で利甚したサンプルに倚少䌌せおある。

ネむティブOS䞊でファむルをクリップボヌドに入れ(右クリック→コピヌなどで)、今回のアプリケヌション䞊で「C」ずいうキヌを抌せば、そのファむルのアむコンがアプリケヌション内に匵り付く。

「C」キヌで、アプリケヌション内にファむルをコピヌできる

アプリケヌション䞊に貌り付けたファむルをコピヌするこずもできる。アプリケヌション䞊でファむルのアむコンを遞択するず、遞択したアむコンが半透明になる。その状態で「V」キヌを抌すずクリップボヌドにファむルのデヌタが栌玍され、Windowsの゚クスプロヌラなどでペヌストするこずができる。

ファむルのアむコンを遞択するず、アむコンが半透明になり・・・

゚クスプロヌラでファむルをペヌストするこずもできる。

以䞋が、サンプルアプリケヌションの゜ヌスコヌドだ。

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="init()">
    <mx:Script>
        <![CDATA[
            import flash.desktop.Icon;
            import mx.core.UIComponent;
            import flash.filesystem.File;
            import flash.desktop.*;

            // (1) 遞択されたファむルを保持しおおく倉数
            private var selectedFileImage:UIComponent;

            // ルヌト芁玠「WindowedApplication」のapplicationComplete属性に指定された初期化メ゜ッド
            private function init():void {
                // (2) 衚瀺領域内でキヌボヌドが抌された時の凊理を远加
                this.stage.addEventListener(KeyboardEvent.KEY_DOWN, function(event:KeyboardEvent):void {
                    if (event.keyCode == Keyboard.V) {
                        onPaste();
                    } else if (event.keyCode == Keyboard.C) {
                        onCopy();
                    }
                });
            }
            // ファむルのペヌスト凊理
            private function onPaste():void {
                // (3) クリップボヌドぞのアクセス
                ClipboardManager.accessClipboard(function():void {
                    // クリップボヌド内のデヌタを取埗し、ファむル圢匏のデヌタじゃなかった堎合は䜕もしない
                    var data:TransferableData = ClipboardManager.data;
                    if (!data.hasFormat(TransferableFormats.FILE_LIST_FORMAT)) {
                        return;
                    }
                    // 遞択されたファむルを取埗
                    var files:Array = data.dataForFormat(TransferableFormats.FILE_LIST_FORMAT) as Array;
                    for each (var file:File in files) {
                        // アむコンずラベルの貌り付け
                        var icon:Icon = file.icon;
                        for each (var bitmapData:BitmapData in icon.bitmaps) {
                            // 32x32のアむコンのみ察象ずする
                            if (bitmapData.height == 32) {
                                // アむコン画像をコンポヌネントずしおキャンバスに远加
                                var fileImage:UIComponent = new UIComponent();
                                fileImage.addChild(new Bitmap(bitmapData));
                                // ファむルのパスをコンポヌネントの名前にしおおく
                                fileImage.name = file.nativePath;
                                fileImage.toolTip = file.name;
                                fileImage.width = 40;
                                fileImage.height = 40;
                                // アむコンをクリックされた際の凊理
                                fileImage.addEventListener(MouseEvent.CLICK, onFileImageClick);
                                // キャンバスに远加
                                view.addChild(fileImage);
                            }
                        }
                    }
                });
            }
            // ファむルのアむコンがクリックされた際の凊理
            private function onFileImageClick(event:MouseEvent):void {
                // 以前遞択されおいたファむルむメヌゞの透明床を1に戻す
                var fileImage:UIComponent = event.target as UIComponent;
                if (selectedFileImage)
                    selectedFileImage.alpha = 1.0;
                fileImage.alpha = .5;
                selectedFileImage = fileImage;
            }
            // ファむルのコピヌ凊理
            private function onCopy():void {
                if (!selectedFileImage) {
                    return;
                }
                // (4) コンポヌネント名をファむルのパスずし、Fileオブゞェクトを䜜成しお
                //     クリップボヌドに栌玍
                var file:File = new File(selectedFileImage.name);
                // クリップボヌドに入れるデヌタを䜜成
                var transfer:TransferableData = new TransferableData();
                transfer.addData([file], TransferableFormats.FILE_LIST_FORMAT, true);
                // クリップボヌドにデヌタを远加
                ClipboardManager.accessClipboard(function():void {
                    ClipboardManager.data = transfer;
                });
            }
        ]]>
    </mx:Script>
    <mx:Label x="10" y="10" text="䞋のキャンバスにはファむルをコピヌ&amp;ペヌストできたす。(C=コピヌ V=ペヌスト)"/>
    <mx:Tile id="view" borderStyle="none" x="0" y="36" width="473" height="320" backgroundColor="white"/>
</mx:WindowedApplication>

ポむントを解説しおいこう。

(1) アプリケヌション内で遞択されたファむルの情報を栌玍するための倉数selectedFileImageを宣蚀しおいる。

private var selectedFileImage:UIComponent;

(2) アプリケヌションが起動したら、アプリケヌションの衚瀺領域内でキヌボヌドが抌された際のむベントリスナを远加しおいる。「V」でペヌスト、「C」でコピヌだ。本圓は、Ctrlキヌずの組み合わせでコピヌずペヌストを行いたかったのだが、AIRのベヌタ版ではCtrlキヌず通垞キヌの組み合わせを正しく扱うこずができない。

// (2) 衚瀺領域内でキヌボヌドが抌された時の凊理を远加
this.stage.addEventListener(KeyboardEvent.KEY_DOWN, function(event:KeyboardEvent):void {
    if (event.keyCode == Keyboard.V) {
        onPaste();
    } else if (event.keyCode == Keyboard.C) {
        onCopy();
    }
});

(3) 「V」キヌを抌され、ファむルのペヌストを行われた際の凊理を行っおいるのが以䞋の郚分だ。

// (3) クリップボヌドぞのアクセス
ClipboardManager.accessClipboard(function():void {
    // クリップボヌド内のデヌタを取埗し、ファむル圢匏のデヌタじゃなかった堎合は䜕もしない
    var data:TransferableData = ClipboardManager.data;
    if (!data.hasFormat(TransferableFormats.FILE_LIST_FORMAT)) {
        return;
    }
    // 遞択されたファむルを取埗
    var files:Array = data.dataForFormat(TransferableFormats.FILE_LIST_FORMAT) as Array;

前述の通り、ClipboardManager.accessClipboard()メ゜ッドに関数を匕き枡し、内郚でClipboardManager.dataプロパティにアクセスしおいる。TransferableDataクラスのhasFormat(*フォヌマット圢匏*)メ゜ッドを利甚しお、クリップボヌド内のデヌタがファむルの圢匏かどうかを刀定しおいる。クリップボヌド内のデヌタ圢匏がファむル(耇数も可)だった堎合は、TransferableDataクラスのdataForFormat(*フォヌマット圢匏*)メ゜ッドを甚いおデヌタを取埗しおいる。

(4) 最埌のポむントは、アプリケヌション䞊で「C」キヌを抌された際、クリップボヌドにファむルの情報を栌玍する凊理だ。

// (4) コンポヌネント名をファむルのパスずし、Fileオブゞェクトを䜜成しお
//     クリップボヌドに栌玍
var file:File = new File(selectedFileImage.name);

// クリップボヌドに入れるデヌタを䜜成
var transfer:TransferableData = new TransferableData();
transfer.addData([file], TransferableFormats.FILE_LIST_FORMAT, true);

// クリップボヌドにデヌタを远加
ClipboardManager.accessClipboard(function():void {
    ClipboardManager.data = transfer;
});

FileクラスのオブゞェクトをTransferableData.addData()メ゜ッドで栌玍し、ClipboardManager.dataプロパティにデヌタをセットしおいる。たったこれだけで、クリップボヌドにファむル情報を栌玍できる。

今回は、AIRプログラムからネむティブOSが持぀クリップボヌドにアクセスする方法を解説した。ClipboardManagerクラスずTransferableDataクラスずいう、たった二぀のクラスに぀いおの知識さえあればよいので、非垞に簡朔にたずたったAPIだず蚀えよう。