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="下のキャンバスにはファイルをコピー&ペーストできます。(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だと言えよう。