目次 | 前の項目 | 次の項目 ドラッグ&ドロップ


2.5 データ転送段階

有効なドロップが発生した場合は、DropTargetListener の drop() メソッドは、ジェスチャーに関連付けられたデータの転送に取りかかります。 DropTargetDropEvent は、転送されるデータオブジェクトを表す Transferable オブジェクトを取得する手段を提供します。

まず、drop() メソッドにより、DropTargetListener が、rejectDrop() を呼び出してドロップを拒否するか (この場合はすぐに復帰する)、または getSourceActions() によって返された操作から選択された操作を指定する acceptDrop() を呼び出してドロップを受け入れます。

acceptDrop() のあとは、getTransferable() が呼び出され、返された Transferable の getTransferData() メソッドを介してデータ転送が行われます。 最後に、ドロップの転送先で転送元からのオブジェクトの転送が完了すると、DropTargetContext.dropComplete() が呼び出され、転送の成功または即時失敗が通知されます。

DropTargetContext.dropComplete() メソッドから復帰するときに、Transferable および DragSourceContext のインスタンスが有効であるという保証がなくなるため、後でガベージコレクトできるように、受け取り側によりインスタンスへのすべての参照が破棄されます。

ACTION_REFERENCE 操作を使う場合は、転送元と転送先でオブジェクトおよび関連付けられた転送のセマンティクスを一致させる必要があります。 一般に、JVM 内の転送では、転送元と転送先の間でライブオブジェクト参照が渡されますが、JVM 間の転送、またはネイティブアプリケーションと Java アプリケーションの間では、ライブオブジェクト参照は無意味で、URL などのほかの参照の種類が交換されます。 転送が JVM 内の転送かどうかは、DragSource と DropTarget の両方で検出できます。


2.5.1 FlavorMap および SystemFlavorMap

ターゲットとなるすべてのドラッグ&ドロッププラットフォームは、同様の機構を使って転送データの型を表しますが、この表現方法には違いがあります。 Java プラットフォームでは、DataFlavor 内にカプセル化された MIME 形式を使ってデータ型を表します。 Java とプラットフォームにネイティブなアプリケーションとの間でのデータ転送を許可するには、これらのプラットフォーム名の存在が公開される必要があります。 このため、これらのプラットフォームに依存する型名、それらの表現方法、および Java MIME ベースの DataFlavors 間で、プラットフォームに依存しない拡張可能なマッピングを作成するための機構が必要です。

この実装は、プラットフォームにネイティブなデータ型 (文字列) と DataFlavors の構築に使われる MIME 形式 (文字列) との間のマッピングを外部で指定する機構を提供します。 この外部マッピングは、背後のプラットフォームのドラッグ&ドロップ機構によって転送元から転送先にエクスポートされる適切な DataFlavors (MIME 形式) を公開するために、背後のプラットフォーム固有の実装コードで使われます。

背後のシステムは、DragSource クラスおよび DropTarget クラスのどちらを使っても、プラットフォームに依存する名前と DataFlavors 間のマッピングにアクセスできます。

public interface java.awt.datatransfer.FlavorMap {
	java.util.Map getNativesForFlavors(DataFlavor[] dfs);
	java.util.Map getFlavorsForNatives(String[] natives);
}


getNativesForFlavors() メソッドは、DataFlavor の配列をパラメータにとり、実パラメータ dfs から、関連付けられた String 型の値 (その MIME 形式に対応するプラットフォームに依存する型名に一致) とともに、DataFlavor 型のゼロ個以上のキーを含む Map オブジェクトを返します。

getFlavorsForNatives() メソッドは、String 型の配列をパラメータにとり、実パラメータ natives から、関連付けられた DataFlavor 型の値 (そのプラットフォームに依存する型名に対応するプラットフォームに依存しない型名に一致) とともに、String 型のゼロ個以上のキーを含む Map オブジェクトを返します。

これらのメソッドによって返される Map オブジェクトは可変の場合もありますが、必ずしもその必要はありません。

NULL がこれらのメソッドのうちのいずれかに渡されると、呼び出しの時点で実装にとって既知であるすべてのキーと値の現在のマップが返されます。

たとえば、Win32 では、シンプルテキストのクリップボード形式の名前は、CF_TEXT (実際にはこれは整数 1) ですが、Motif では、STRING という名前の X11 Atom です。 MIME 形式を使ってこれを表現する場合は、text/plain charset=us-ascii です。 プラットフォームに対する移植性のある FlavorMap は、Win32 上の CF_TEXT と Motif/X11 上の STRING 間のマッピングを行います。

一般に、これらのマッピングは、SystemFlavorMap に実装する時に、外部の固定された設定形式 (プロパティファイルまたは URL) に保持し、プラットフォームからロードして、特定のプラットフォームに適切に FlavorMap を設定するようにします。

SystemFlavorMap クラスは、全システムに共通なマッピングのセットを指定するための、プラットフォームで設定が可能な単純な機構を実装するために提供されています。 次のように定義されています。

public class      java.awt.datatransfer.SystemFlavorMap 
       implements FlavorMap {
	public static FlavorMap getSystemFlavorMap();

	public synchronized Map
		getNativesForFlavors(DataFlavor[] dfs);

	public synchronized Map
		getFlavorsForNatives(String[] natives);

	public static String
		encodeJavaMIMEType(DataFlavor df);

	public static String
		encodeJavaMimeType(java.util.mime.MimeType mime);

	public static boolean
		isEncodedJavaMimeType(String mimeStr);

	public static DataFlavor
		createFlavorFromEncodedJavaMimeType(String ejmts);

	public static java.util.mime.MimeType
		createMimeTypeFromEncodedJavaMimeType(
							String ejmts
		);
}

SystemFlavorMap クラスは、固定プラットフォームの FlavorMap のプロパティファイル (java.awt.Properties を参照) を使って、単純な実装を提供します。 このクラスは、AWT のプロパティである AWT.flavorMapFileURL (Toolkit.getProperty() を参照) の値か、または System.getProperty("java.home") + File.separator + "lib" + File.separator + "flavormap.properties" のデフォルトのファイル位置を使って、そのプロパティから適切な Map を作成します。

さらに、このクラスは、Java MimeType とプラットフォームに依存した名前空間のコード化または復号化に使う、いくつかの有用な静的機能を提供します。 プロパティファイルの構文は、次のとおりです。

{ <platform_type_name> `=' <IETF_MIME_RFC_conformant_specification> <nl> } *

DragSource および DropTarget のデフォルト実装は、その他の実装によってオーバーライドされていなければ、getFlavorMap() メソッドからの SystemFlavorMap を返します。


2.5.2 JVM 境界を越えるデータの転送

この API では、Java とネイティブアプリケーションの間でデータをドラッグ&ドロップできることが大きな特長の 1 つになっています。このため、この API では、Java Virtual Machine* の境界を越えてデータが渡されたときに、実際のデータ符号化およびデータ交換の方法および機構に重要な変更が行われています。

このようなデータ交換では、転送元または受け側が Java のデータ型を認識しないネイティブアプリケーションであるため、このドラッグ&ドロップのシステムでは単純に Java オブジェクトの参照を渡すことができません。転送元または受け側で Java のデータ型の認識または操作を行うことができない可能性があるためです。

データ交換が発生すると、転送元と受け側の実装に関係なく、よく使用されるデータ型および符号化の方式が共有されているときに限り、そのデータ交換が実現されます。 つまり、交換で発生する問題は、ほとんどの場合、転送元および受け側のアプリケーションが原因です。

実質的には、プラットフォームに依存したイメージ、ドキュメント、その他の「Content-Type」など、「ネイティブな」データ形式の場合は、それらに関連付けられた外部データ形式を符号化および復号化したものが、転送元および転送先となります。

このドラッグ&ドロップシステムでは、そのような Java Virtual Machine の境界を越える「ネイティブな」データ型の外部表現が、java.io.InputStream またはそのサブクラス内にカプセル化されて公開されます。

つまり、java.io.InputStream を継承する表象クラスを含むすべての DataFlavor が、Java Virtual Machine の境界を越えて転送可能であり、転送のために公開されることになります。

このようなネイティブなデータ型の交換を実装するには、DataFlavor を MIME の「Content-Type」に定義します。MIME の「Content-Type」には、「ネイティブな」データ型の特性が、java.io.InputStream クラスを継承する表象クラスを使って記述されています。java.io.InputStream クラスによって、カプセル化されたデータがバイトストリームに符号化されます。

特に、このような InputStream サブクラスによって、次のセマンティクスが実装されます。

java.io.InputStream のサブクラスによってこのコンストラクタが提供されるため、DropTarget に関連付けられた ドラッグ&ドロップシステムでは、要求された DataFlavor に指定されている表象クラスのインスタンスが自動的に再構築されます。そのインスタンスは、サブクラスの要求に応じてフォーマットされたカプセル化データを含む InputStream によって初期化されます。 このインスタンスは、初期化されると、Transferable.getTransferData() メソッドの呼び出し側に返されます。次に、呼び出し側では、データストリームが転送されると、フォーマットされた内容が読み取られ解釈されます。

このメソッドの提供 (またはサブクラス実装の継承) によって、DropTarget に関連付けられたドラッグ&ドロップシステムでは、符合化されたカプセル化データストリームが Transferable から自動的に抽出されます。この結果、このデータは JVM* の境界を越えて、DataFlavor のリクエスタに単純なバイトストリームとして転送されます。


2.5.3 JVM 境界を越えるファイルリストの転送

ドラッグ&ドロップ転送の典型的な対象として、プラットフォームに依存する 1 つ以上のファイル名のリストを挙げることができます。 ファイル名リストの作成または処理を行うプログラムを簡単に開発できるように、ドラッグ&ドロップシステムでは、ファイル名リストは独自に処理されます。

DataFlavor が application/x-java-file-list;class=java.util.List という MIME「Content-Type」に指定されている場合、ドラッグ&ドロップシステムでは、リストの要素が java.io.File 型のオブジェクトのリストと同質であることを前提としています。したがって、転送元では、ファイルリストの転送がサポートされている場合は、この DataFlavor が要求されるとその File オブジェクトの List が構築されます。また、受け側では、転送元の有効な DataFlavor を要求した場合は、その File オブジェクトの List を受け取ります。 転送元とターゲット間でファイルリストを転送するときは、この独自の処理による簡単な機構が使用されます。


2.5.4 JVM 境界を越える java.rmi.Remote 参照の転送

RMI 機構の機能を使用すれば、JVM 間でオブジェクト参照をドラッグ&ドロップすることができます。 ドラッグ&ドロップシステムでは、次の要件を満たすように、オブジェクト参照の転送が自動的に構成されます。

(MIME の「Content-Type」には、任意の適合したデータ型、または application/x-java-remote-object を指定できます。)

(効果的に実装するには、転送されたオブジェクト実装クラスは、java.rmi.server.UnicastRemoteObject から継承されていなければなりません。RMI システムには必要な初期化がいくつか実装されているためです。その初期化が実装されていない場合は、転送は正常に完了しません。)

これらの条件が満たされている場合は、適切な DataFlavor が要求されると、リクエスタ (転送元と異なる JVM に存在する場合) に返されるオブジェクトは、DataFlavor の表象クラスとして指定されている Remote オブジェクトサブインタフェースのインスタンスへの RMI 参照になります。

* この Web サイトで使用されている用語「Java Virtual Machine」または「JVM」は、Java プラットフォーム用の仮想マシンを表します。


目次 | 前の項目 | 次の項目
Copyright © 1997, 1998 Sun Microsystems, Inc. All Rights Reserved.