Java AWT: データ転送


最終更新: 1997年 2 月3 日

目的

今日の典型的な GUI ユーザは、切り取り/コピー/貼り付けおよびドラッグとドロップのような操作を使用して、アプリケーション間でデータ転送できることを期待しています。現在の Java 環境でのこの唯一の機構は、AWT ネイティブウィジット (TextField、TextArea) がデフォルトで提供する機能を介するものです。しかし、アプリケーションがこれらネイティブウィジット外でそのような操作を有効にする必要のあるケースがたくさんあります。そのため、Java プラットフォームは、基本的なデータ転送機能を有効化するために、 API を提供する必要があります。このドキュメントでは、様々な転送プロトコルをその上に構築できる Java オブジェクトのベースラインデータ転送を定義します。このドキュメントではまた、これら上位レベル転送プロトコルの 2 つの API、クリップボード および ドラッグとドロップ について説明します。

注: クリップボード API は JDK 1.1 にありますが、ドラッグとドロップ API は( 1.1 の時間的制約により)次のバージョンになります 。ここでは、Java Beans ドキュメントから参照ができ、できる限り早くフィードバックを得られるように、ドラッグとドロップのドキュメントを入れています。

Java データ転送

転送 API の設計目標

データ転送 API の設計目標は次のとおりです:

転送 API の概要

Transferable オブジェクト

API は転送される次のオブジェクトが実装するインタフェースを軸にしています。
	java.awt.datatransfer.Transferable
Transferable オブジェクトは、最も豊富な内容説明のフレーバから最低のフレーバまで要求された、(データフレーバと呼ばれる)データ提供フォーマットのリストを出せなければなりません。これはまた、特定のフレーバで要求されたとき、(オブジェクト参照の形式で)データを返すことができなければなりません(あるいは、そのフレーバがサポートされていない場合、またはそのデータがもはや使用できない場合には、例外をスローします)。

共通データ型に Transferable インタフェースを実装する convenience クラスは、開発者がこれらの共通型の転送を容易に行えるようにするために提供されます。例えば次のとおりです:

	java.awt.datatransfer.StringSelection

この API の目的は、特定のエレメントまたはデータ型を転送可能にする作業に入ったとき、上位レベル転送プロトコル(クリップボード、ドラッグとドロップなど)のどれかを使用して、簡単にそれを渡せることを保証することです。

データフレーバ

典型的な共通データ転送操作(クリップボート、ドラッグとドロップ)には、データを転送するフレーバ上での、プロバイダと要求者の間のネゴシエーションという様相があります。例えば、html テキストがブラウザで選択され、別個のワードプロセスアプリケーションにコピー/貼り付けされるとき、貼り付け操作の可能な対象アプリケーション数を最大化するために、ブラウザは通常データを複数のフレーバ(大抵 htmlフ ォーマットのテキストおよび単なる ASCII )で提供します。

このネゴシエーションでは、個別のアプリケーションでこれら様々なフレーバとデータ型が一意に定義され認識できる、データ型分類用名前空間の定義が必要です。「フォーマット」などの過負荷な用語との混同を避けるために、「フレーバ」という用語を選びこの概念を表します。

データフレーバは、アプリケーション間のフレーバネゴシエーションと転送を可能にするために、特定のフレーバに関する必要な情報すべてをカプセル化したオブジェクトによって表します:

	java.awt.datatransfer.DataFlavor

この情報には、フレーバの論理名(プログラム上の識別を可能にする)、人間紹介名(ユーザに紹介するために使用し、ローカライズが可能)、データを実際に転送するオブジェクトクラスを定義するために使用する表現クラスなどが入っています。

論理名としての MIME型

現在、データフレーバの論理名を表すために、MIME 型/サブ型 パラメータ表記の使用を計画しています( MIME 型の仕様については、RFC 1521を参照してください)。Java 環境に対しては、「他のデータ型分類用名前空間」を作成するより、既存のインターネット標準を採用する方が好ましいと考えます。

MIME 型の登録は、現在 Internet Assigned Numbers Authority (IANA) というサードパーティが行っており、開発者が簡単に公開データフォーマット用に使用する標準型/サブ型名を検索できるようになっています。幸い、あまり一般的でないフォーマットに対して新しい MIME 型/サブ型名を定義するためには、公式の登録は必要ありません(このような公式の要件が、基本的な Java データ転送で容認されないのは好ましいことです)。新しい型名は公式な登録はせずに、名前の前に "x-" を追加して作成できます。

表現クラス

データを実際に返す次の Transferable メソッドは、「Object」クラスのインスタンスを返すように緩やかに定義されているために、DataFlavor が定義した表現クラスは転送操作の終端では重要になります。それは返されたオブジェクトが明瞭にデコードされるようにするからです。
	Object getTransferData(DataFlavor flavor)

現在の DataFlavorクラスは、次の 2 つの一般的なデータフレーバを定義します。

	     MIME-type="application/x-java-serialized-object; class=<implemenation class>"
	     RepresentationClass=<implemenation class>

        たとえば、AWT GUI コンポーネントを表す DataFlavor:

	     MIME-type="application/x-java-serialized-object; class=java.awt.Component"
	     RepresentationClass=java.awt.Component
	  転送操作の要求側がこのフレーバのデータを求める場合、Componentクラスのインスタンスが戻されます。
	     MIME-type="application/<mime-subtype>"
	     RepresentationClass=java.io.InputStream

        たとえば、RTFテキストを表す DataFlavor:

	     MIME-type="application/rtf"
	     RepresentationClass=java.io.InputStream
	  転送操作の要求側がこのフレーバのデータを求める場合、それから
           RTFフォーマットのテキストを読み込み/解析できる InputStream
           インスタンスが戻されます。

与えられた MIME 型(上記型 #2)については、Java プログラムは異なる表現クラスを持つ複数のフレーバを自由に作成できます。例えば、MIME 型 application/rtf にフレーバを提供することに加えて、プログラムは別のフレーバを指定することもできます:

        たとえば、RTFテキストを表す DataFlavor:

	     MIME-type="application/rtf"
	     RepresentationClass=foobar.fooRTF

カプセル化の原理

最初は、(単なる MIME 型文字列でなく)データフレーバを定義するためにクラスを使用することは、過剰であると思えるかもしれません。しかし、このカプセル化は次の理由から利点があるものといえます:
  1. 使用性 - 論理文字列にだけ奇異なほどに関連付けることができますが、データフォーマットに対する人間紹介名のように、データフォーマットに関連付けるべき属性があります。 DataFlavor オブジェクトについては、これらの属性は直接カプセル化している DataFlavor オブジェクトに関連付けられています。
  2. 利便性 - DataFlavor オブジェクトの使用は、データフォーマット比較処理の便利な方法です。isMimeTypeEqual() メソッドはプログラマを開放したり、またはプログラマの MIME 型を正規の形式に変換することを忘れずに実行する必要があります。( MIME 型、サブ型、パラメータ名には大文字小文字の区別があり、パラメータはどんな順序でも表示されるため、これは問題です)。
  3. 拡張性 - 抽象化によって、必要ならばいつでもフレーバ属性/メソッドを拡張できるようになります。
  4. 性能 - Motif および Windows は、データフォーマットを識別するために、文字列でなくアトムを使用します。各データフォーマットを識別するためにオブジェクトを使用することで、必要なアトムの収容数を縮小しながら、MIME 型名に対応するアトムをキャッシュする手頃な場所が与えられます。同様に、"text/plain" などの MIME 型を、 Windows の CF_TEXT や Macintoshの 'TEXT' などのプラットフォーム固有のクリップボードフォーマットに割り当てた結果は、キャッシュが可能になります。

DataFlavor の概念は複雑で困惑させるように思えるかもしれませんが、意図しているのは、共通に使用するデータフレーバのセットを定義して、これを開発者にとってできる限り使用しやすくすることです。

複数項目の転送

転送プロトコルが、単一の転送操作で複数の別個なデータの転送をサポートすること(すなわち、ファイルマネジャーアプリケーションから、複数ファイルのアイコンをドラッグ、ドロップすること)は、一般的ではありません。転送 API は、複数データ項目の同時転送をある形式でサポートする必要があり、現在の提案は、個別データオブジェクトの集まりを扱うことができる Transferable を実装して、この機能をカプセル化することです。この計画は現在綿密に調査されており、この提案を将来改訂するときに詳細に検討されます。

Transferableオブジェクト作成のコード例

次のコードは StringSelection クラスソースを示します。これは当提案で単なる Unicode{tm} テキストを転送できるクラスを作成するための API の使用方法の例です。

package java.awt.datatransfer;

import java.io.*;

/**
 * A class which implements the capability required to transfer a
 * simple java String in plain text format.
 */
public class StringSelection implements Transferable, ClipboardOwner {

    final static int STRING = 0;
    final static int PLAIN_TEXT = 1;

    DataFlavor flavors[] = {DataFlavor.stringFlavor, DataFlavor.plainTextFlavor};

    private String data;
						   
    /**
     * Creates a transferable object capable of transferring the
     * specified string in plain text format.
     */
    public StringSelection(String data) {
        this.data = data;
    }

    /**
     * Returns the array of flavors in which it can provide the data.
     */
    public synchronized DataFlavor[] getTransferDataFlavors() {
	return flavors;
    }

    /**
     * Returns whether the requested flavor is supported by this object.
     * @param flavor the requested flavor for the data
     */
    public boolean isDataFlavorSupported(DataFlavor flavor) {
	return (flavor.equals(flavors[STRING]) || flavor.equals(flavors[PLAIN_TEXT]));
    }

    /**
     * If the data was requested in the "java.lang.String" flavor, return the
     * String representing the selection, else throw an UnsupportedFlavorException.
     * @param flavor the requested flavor for the data
     */
    public synchronized Object getTransferData(DataFlavor flavor) 
			throws UnsupportedFlavorException, IOException {
	if (flavor.equals(flavors[STRING])) {
	    return (Object)data;
	} else if (flavor.equals(flavors[PLAIN_TEXT])) {
	    return new StringReader(data);
	} else {
	    throw new UnsupportedFlavorException(flavor);
	}
    }

    public void lostOwnership(Clipboard clipboard, Transferable contents) {
    }
}


クリップボード

アプリケーション内部およびアプリケーション間の両方で、データ転送の手段として、切り取り/コピー/貼り付け操作を提供することは、現在ほとんどのアプリケーションで一般的で期待されている機能です。JDK 1.0 の AWT API では、現在、(ネイティブテキストウィジットでデフォルトとして存在する以外、)この基本的なクリップボード操作の機能をなにも提供していません。そしてこの機能は、 Java プログラムをユーザ環境にうまく統合するためには欠かすことができません。

クリップボード API の設計目標

この API の設計目標は次のとおりです:

クリップボード APIの概要

クリップボード API は、 Java プログラム内で切り取り/コピー/貼り付け操作を実装する標準機能を提供します。異なるクリップボードを異なる目的で作成し名前付けできます(プログラムは自分自身の private クリップボードの作成を好む可能性があります)。しかし、( System と名付けられた)単一のクリップボードインスタンスがあり、これは Java プログラムが非 Java アプリケーションとのデータ転送を可能にするために、プラットフォームのネイティブ機能とのインタフェースを持つものです。

クリップボードアーキテクチャは、Java データ転送 API が定義するデータ転送機構に依存しています。クリップボード API には、標準クリップボード用のデータ転送モデルを実装する次の単一のクラスがあります:

	java.awt.datatransfer.Clipboard 

そして、データをクリップボードに書き込んでいるクラスが実装する次のインタフェースがあります:

	java.awt.datatransfer.ClipboardOwner

Clipboardクラスは、クリップボードとの読み込み/書き込み用の次の 2 つの基本的メソッドを提供します:

	void setContents(Transferable content, ClipboardOwner owner)
	Transferable getContents(Object requestor)

ClipboardOwner インタフェースは次の単一のメソッドからなり、これは別のオブジェクトがクリップボードの所有権を主張した場合に呼び出されます。

	void lostOwnership(Clipboard clipboard)

開発者が一般的なデータ型にクリップボード操作を実装するジョブを簡単に行えるように、標準的な方法で ClipboardOwner インタフェースを実装する convenience クラスが提供されます:

	java.awt.datatransfer.StringSelection

java.awt.Toolkit 内の次のメソッドは、ネイティブプラットフォーム機能とのインタフェースを持つクリップボードインスタンスへのアクセスを提供します:

	Clipboard getSystemClipboard();

クリップボード API を使用しての切り取り/コピー/貼り付けの実装

「切り取り」/「コピー」を実装するプログラムの一般的操作手順:
  1. 切り取り/コピーするデータの Transferable インタフェースを実装するオブジェクトのインスタンスを生成します。
  2. ClipboardOwner インタフェースを実装するオブジェクトのインスタンスを生成します( Transferable を実装するオブジェクトと同じ可能性があります)。
  3. この Transferable および ClipboardOwner オブジェクトを、クリップボードの setContents() メソッドに渡します; これでクリップボードの所有権が確立します。
  4. 別のオブジェクトがクリップボードの所有権を主張した場合に呼び出される、クリップボード所有者の lostOwnership() メソッドへの呼び出しを処理します(所有権を失うときに何もする必要がない場合、このメソッドは空で構いません)。

「貼り付け」を実装するプログラムの一般的操作手順:

  1. Transferable インタフェースを実装するオブジェクトに処理を返す、getContents() メソッドを使用してクリップボードのコンテンツを要求します。
  2. getTransferDataFlavors() メソッドを使用して、transferable オブジェクトからデータの使用可能なフレーバのリストを要求します。
  3. transferableオブジェクトの getTransferData() メソッドを使用して、希望する使用可能なフレーバのデータを取得します。

遅延データモデル

クリップボードモデルは、クリップボードコンテンツの持続レベルを暗示しますが、切り取り/コピー時に不要なパフォーマンスの劣化を避けるために、顧客が要求するまでデータは実際には転送されない可能性があります(これは「遅延」データモデルとして知られています)。クリップボードの所有者が破壊された場合、プロバイダが終了した後、その使用可能性を保証するために、そのデータを取得しクリップボード内に格納しようと試みることが必要です。しかし、クリップボードの所有者は、転送がいつ起こるかという仮定をしてはいけません。そして lostOwnership() メソッドが呼び出されるまで、データを使用可能にするよう試みなければなりません(無期限にデータを使用可能にしておくことができない場合、データが要求され、それが使用可能でないならば、IOException をスローする必要があります)。

セキュリティ

ダウンロードされたアプレットがネイティブシステムのクリップボードへアクセスできるようにすることに関して、そのコンテンツに対する読み込み可能(これは微妙な問題になりえます)、および書き込みという点から、明確なセキュリティ上の問題があります。初期には、認可されていないアプレットは、*システム*のクリップボードに直接アクセスすることは認められません(ここにはクリップボードアクセス用の SecurityManager メソッドがあります)。操作の初期化がユーザ生成イベント (「切り取り」または「貼り付け」キーボードイベントなど)からなされた場合、認可されていないアプレットがクリップボード操作に参加できるようにする機構を、今探索中です。

クリップボード API を使用したサンプルコード

単なるテキストの切り取り/コピー/貼り付けを実装しているプログラムの簡単な例を次に示します

(注: 簡単にするために、コピー/貼り付け操作の元/先として TextArea を使用します; ほとんどのプラットフォームで、切り取り/コピー/貼り付けは既にネイティブピア内の TextArea および TextField 用に実装されています)

								       

import java.awt.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.datatransfer.*;

public class ClipboardTest extends Frame 
                           implements ClipboardOwner, ActionListener {

    TextArea srcText, dstText;
    Button copyButton, pasteButton;

    Clipboard clipboard = getToolkit().getSystemClipboard();

    public ClipboardTest() {
        super("Clipboard Test");
        GridBagLayout gridbag = new GridBagLayout();
        GridBagConstraints c = new GridBagConstraints();
        setLayout(gridbag);

        srcText = new TextArea(8, 32);
        c.gridwidth = 2;
        c.anchor = GridBagConstraints.CENTER;
        gridbag.setConstraints(srcText, c);
        add(srcText);

        copyButton = new Button("Copy Above");
        copyButton.setActionCommand("copy");
        copyButton.addActionListener(this);
        c.gridy = 1;
        c.gridwidth = 1;
        gridbag.setConstraints(copyButton, c);
        add(copyButton);

        pasteButton = new Button("Paste Below");
        pasteButton.setActionCommand("paste");
        pasteButton.addActionListener(this);
        pasteButton.setEnabled(false);
        c.gridx = 1;
        gridbag.setConstraints(pasteButton, c);
        add(pasteButton);

        dstText = new TextArea(8, 32);
        c.gridx = 0;
        c.gridy = 2;
        c.gridwidth = 2;
        gridbag.setConstraints(dstText, c);
        add(dstText); 

        pack();
    }

    public void actionPerformed(ActionEvent evt) {
        String cmd = evt.getActionCommand();

        if (cmd.equals("copy")) { 
           // Implement Copy operation
           String srcData = srcText.getText();
           if (srcData != null) {
                StringSelection contents = new StringSelection(srcData);
                clipboard.setContents(contents, this);
                pasteButton.setEnabled(true);
            }
        } else if (cmd.equals("paste")) {
            // Implement Paste operation
            Transferable content = clipboard.getContents(this);
            if (content != null) {
                try {
                    String dstData = (String)content.getTransferData(
                                                DataFlavor.stringFlavor);
                    dstText.append(dstData);
                } catch (Exception e) {
                    System.out.println("Couldn't get contents in format: "+
                           DataFlavor.stringFlavor.getHumanPresentableName()); 
                }
             }
        }
    }
    public void lostOwnership(Clipboard clipboard, Transferable contents) {
       System.out.println("Clipboard contents replaced");
    }
     public static void main(String[] args) {
        ClipboardTest test = new ClipboardTest();
        test.show();
     }
}

ドラッグとドロップ

ドラッグとドロップは一般的に期待される機構になっており、これによってユーザは、ファイルのコピー、印刷ジョブの開始、新しい制御やグラフィックスの作成などの操作を速く行うことができます。JDK1.0 では、限定されたアプリケーション内のドラッグとドロップ操作を実装できますが、ドラッグとドロップを使用して別個のアプリケーション間で対話を行うことはできません( Java から Java または Java とネイティブ相互間どちらも不可能です)。 このドキュメントは、強力なクロスアプリケーションのドラッグとドロップ操作を可能にする AWT API の初期の仕様を提供します。

注: ドラッグとドロップ APIは、このバージョンの時間的制約によって、JDK1.1 には入っていません。

ドラッグとドロップAPI の設計目標

この API の設計目標は次のとおりです:

各ネイティブプラットフォームは、ドラッグとドロップに関してやや異なるモデルと 機能セットを提供しています。この API は、機能と動作の組み合わせにおいて、 OLE のドラッグとドロップに最も近いものです。このアーキテクチャの決定は、多数の Windows ユーザによるものではありませんが、Motif の制限によって制約された設計は受け入れがたく、かたや Macintosh のドラッグとドロップ機能のすべてを包含したアーキテクチャは実装不可能であるという理解に基づいています。

ドラッグとドロップ APIの概要

DragSources および DropTargets

ドラッグとドロップ操作については、通常ユーザが指定してドラッグするオブジェクトを表す「ドラッグソース」、およびドロップを受け取ることができる画面上のオブジェクトである0 個以上の「ドロップターゲット」があります。

コンポーネントは、インタフェースを実装することによって、ドラッグ可能であると宣言します:

	java.awt.dnd.DragSource 

DragSources は次のことに対して責任を持ちます:

コンポーネントは次のインタフェースを実装し、ドロップを受け取ることができると宣言します:

	java.awt.dnd.DropTarget 

DropTarget は次のことに責任を持ちます:

アクション

DragSource から DropTarget ,へオブジェクトをドラッグするとき、ユーザは有効なドロップが発生した場合、DragSource が供給するセットの中からどのアクションをオブジェクトに適用するかを選択できます。このアクションは、ビットマスクを作成するために結合できる定数として表されます。使用可能なアクションは次のとおりです:

注: ACTION_LINK は、 API の複雑さを減少させるために除外されています。

Javaデータ転送およびドラッグとドロップ

ドラッグとドロップは単なる転送、またはある位置から別の位置へのオブジェクトのコピーであるため、プログラマがオブジェクトをドラッグソースとドロップターゲットの両方でだけ扱う必要がある場合、便利です。すなわち、プログラマに関する限り、モデルプログラミングとは単に、ドラッグソースからのオブジェクトがドロップターゲットにコピーされることを指します。

もちろん、異なるアプリケーションまたは Java Virtual Machine 間でドラッグとドロップをするとき、ターゲットが希望するオブジェクトをソースからコピーすることはできません。各ケースで実際なにが起こるかというと、これはかなり複雑で、ネイティブのドラッグとドロップ機構の例として OLE ドラッグとドロップを使用して次に概要を述べます。

ドラッグとドロップによって転送するためには、Java オブジェクトは Transferable インタフェースをサポートする必要があります。このインタフェースは、オブジェクト(Transferable インタフェースの getTransferDataFlavors() メソッド) がサポートする異なる DataFlavorを列挙し、元のオブジェクトの所定の DataFlavor を表す新しいオブジェクトを返す責任を持っています。

DragSource が、ドラッグされるオブジェクトの集まりに Java オブジェクトを追加するとき、AWT 実装はオブジェクトの周囲に IDataObject インタフェースをラップします。IDataObject->EnumFormatEtc() はオブジェクトの getTransferFormats() メソッドに結び付けられ、IDataObjectGetData() は getTransferData() に結び付けられます。

EnumFormatEtc() が返す値は、DragSource が供給する DataFlavor の MIME 型によって決定されます。各 MIME 型文字列は、MIME 型を Windows のクリップボードフォーマットに割り当てるレジストリで参照されます。割り当てが見つかった場合 (例えば、text/plain = CF_TEXT)、その割り当ては FormatEtc.cfFormat の値のために使用されます。見つからない場合、MIME 型の呼び出ししている RegisterClipboardFormat() から返された値が使用されます。

ターゲットがソースからドラッグされる Java オブジェクトの 1 つの固有の DataFlavorを要求するとき、ドラッグされるオブジェクトの getTransferData() メソッドが、指定した DataFlavor で呼び出されます。これは次の 2 つのうち 1 つを実行する必要があります:

これは Windows の下でのドラッグとドロップの実装についての動作ですが、 Macintosh と Motif についても基本的に同様です。重要なことは、DragSource 側と DropTargets 側の動作は常にお互いに独立しており、他の側が別の Java アプリケーションでも気にかけないということです。DragSource 側は常に、 Java オブジェクトと DataFlavor をネイティブのドラッグとドロップ概念に変換し、DropTarget 側は常に、ネイティブのドラッグとドロップを Java に変換します。この分離によって、Java アプリケーション間のドラッグとドロップが、 Java とネイティブアプリケーション間のドラッグとドロップに同等となります。後者の点で、DragSource と DropTarget が同じ Java Virtual Machine 内にあるとき、直列化を短絡し、可能ならばオブジェクトを単にクローン化することによって、パフォーマンスを常に向上することができます。

ドラッグとドロップおよび複数オブジェクト

ユーザは、しばしば異なる型の複数オブジェクトを同時に転送しようと試みます。これらオブジェクトの各々は型が異なる可能性があり、転送される各オブジェクトは、それがサポートする DataFlavor の独自のリストを持っている必要があります。DropTarget は、ドラッグしているオブジェクトの各々に対して最低 1 つの DataFlavor を受け入れることができる場合、ドロップだけを有効と考える必要があります。

例えば、ユーザが emacs 上のグラフィカルレイアウトエディタから矩形とテキストフィールドをドラッグする場合、emacs はフィードバックを返し、テキストフィールドのコンテンツは受け入れられるが矩形のコンテンツは受け入れられないので、ドロップを受け入れないということを示す必要があります。

[個別オブジェクトを今のようにさらしておくか、または列挙が渡される OLE に近いアプローチを使用するかは、いまだ明確ではありません。]

DragContextおよび DropContext

DragContext と DropContext は、ドラッグが一度始まるとドラッグとドロップ実装によって使用されるソース側とターゲット側の構築物です。これらは、Java DragSource と DropTarget がドラッグの間基礎をなすプラットフォーム固有のドラッグとドロップ実装に通じるインタフェースを供給します。これらはクラスによって表されます:
	java.awt.dnd.DragContext 
	java.awt.dnd.DropContect 

DragContext は、ドラッグが始まったとき DragSource の dragBegin() によって作成され、返されます。これには、このドラッグのドロップターゲットのオブジェクトと許されるアクションのリストが含まれます。さらにまた、DragSource の dragOver() メソッド内部で呼び出される次の関数をサポートします:

DropContext はドラッグとドロップ実装によって作成され、すべての DropTarget メソッドに渡されます。これは、ドラッグについての情報を決定するための次の関数を供給します:

セキュリティ

セキュリティおよび質の悪い Java アプリケーションの問題は、クリップボードに対するドラッグとドロップの問題ほどたいしたものではありません。それは、ユーザだけがドラッグとドロップトランザクションを起動できるからです。システム管理者はそれでも、ドラッグとドロップトランザクションを開始する、またはネイティブアプリケーションと共に受け取る Java アプリケーションの機能を制限する必要を感じているかもしれません。このような機能は簡単にセキュリティマネージャに追加し、もっと一般的なデータ転送許可に昇華できるでしょう。

DragSources および DropTargets は自らを private DataFlavors に限定することで、その乱雑さを制限することができます。しかし、もっと率直な設計をして、 DragContext に現在の DropTarget を得るためのメソッドを追加したり、DropContext に現在の DragSource を取得するためのメソッドを追加したりできるかもしれません。これらのルーチンは、ドラッグが同じ Java VM 内にない場合、null を返します。これは、各項目がそのどちらかに存在するという、ある一対のテキストリストのようなユーザインタフェースを実装可能にします。



フィードバックは java-awt@java.sun.com 宛てに送ってください。
Copyright (C) 1996, Sun Microsystems, Inc. All rights reserved.