Javaのヒント61:Javaでの切り取り、コピー、貼り付け

この記事では、Javaでクリップボードから情報を送受信する方法について十分に理解できます。また、利用可能なさまざまなデータフレーバーを処理する方法についても学習します。最後に、クリップボードの複数の個性と、クリップボードが複数のデータフレーバーをサポートする方法について説明します。

Javaには、ローカルとシステムの2種類のクリップボードがあります。ローカルクリップボードは、アプレットまたはアプリケーションが実行されている仮想マシン内でのみ使用できます。ただし、クリップボードを1つだけに制限する一部のオペレーティングシステムとは異なり、Javaでは必要な数のローカルクリップボードを使用できます。特定のローカルクリップボードへのアクセスは、名前で参照するのと同じくらい簡単です。

システムクリップボードはピアオペレーティングシステムと直接リンクされているため、アプリケーションはそのオペレーティングシステムで実行されているアプリケーション間で情報を転送できます。システムクリップボードを使用することの1つの欠点は、テキストデータしか転送できないことです。他のタイプのオブジェクトは、システムクリップボードではサポートされていません。運が良ければ、この問題はJDKの次のリリースで解決される予定です。

先に進む前に、クリップボードの操作に関係するすべてのクラスを見てみましょう。以下の表にリストされているこれらのクラスは、すべてjava.awt.datatransferパッケージの一部です。

java.awt.datatransferパッケージ内のすべてのクラスのリスト
名前 タイプ 説明
Clipboard クラス 譲渡可能なすべてのものを扱います
ClipboardOwner インターフェース クリップボードを扱うすべてのクラスは、このインターフェイスを実装する必要があります。このインターフェイスは、クリップボードに最初に配置されたデータが上書きされたことを通知するために使用されます
Dataflavor クラス 転送可能なサポートがサポートするすべてのデータ型を表します
StringSelection クラス Javaで提供される転送可能なものの1つのタイプ
Transferable インターフェース クリップボードに渡されたオブジェクトへのラッパー
UnsupportedFlavor Exception クラス サポートされていないデータフレーバーに対して転送可能によってスローされる例外

クリップボードクラスの詳細

java.awt.datatransfer各クラスを詳しく見て、パッケージの調査について詳しく見ていきましょう。

クリップボードクラス

Clipboardクラスは、クリップボードにアクセスするためのあなたのリンクです。これには、次の表で定義されている3つのメソッドが含まれています。

クリップボードクラス
方法 説明
String getName () クリップボードの名前を取得します
void setContents (Transferable, ClipboardOwner) 所有者オブジェクトとともにクリップボードの内容を設定します
Transferable getContent (Object) クリップボードのコンテンツをTransferableオブジェクトの形式で取得します。パラメータとして渡されるオブジェクトは所有者です

上記の3つのClipboardクラスメソッドを使用すると、クリップボードに名前を付けたり、クリップボードに情報を送信したり、クリップボードから情報を取得したりできます。システムクリップボードへのアクセスまたはローカルクリップボードの作成は異なり、もう少し議論が必要です。システムクリップボードにアクセスするにはClipboard、次のように、システムクリップボードからクラスに参照を割り当てます。

Clipboard clipboard = getToolkit ().getSystemClipboard ();

一方、ローカルクリップボードを作成するにClipboardは、割り当てたい名前のオブジェクトを作成するだけで済みます。次に例を示します。

Clipboard clipboard = new Clipboard ("My first clipboard");

システムクリップボードへのアクセスやローカルクリップボードの作成は異なりますが、簡単です。

ClipboardOwnerインターフェース

Javaはマルチプラットフォーム言語であり、オペレーティングシステムはクリップボードに対して異なる動作をするため、Java言語の作成者は、微妙な違いに対処するメカニズムを考え出す必要がありました。これがClipboardOwnerインターフェースが存在する理由です。その唯一の機能は、クリップボードの所有者に、データが他の誰かによって上書きされていることを通知することです。また、データに関連付けられたリソースをいつ解放するかをアプリケーションに通知することもできます。

実際のアプリケーションでは、このlostOwnershipメソッドを使用して、クリップボード内のデータの可用性についてアプリケーションに通知するフラグを設定できます。Microsoft Wordは、Javaで記述されていませんが、アプリケーションで機能するこのメカニズムの良い例です。Word内のクリップボードに何かを入れて終了すると、データがクリップボードにあることを通知するダイアログボックスが表示されます。次に、データをクリップボードに残すかどうかを尋ねられます。

実装するClipboardOwnerメソッドは1つしかないため、インターフェイスの実装は比較的簡単です。この方法により、プログラムはクリップボードの所有権を放棄します。

DataFlavorクラス

DataFlavorクラスが表現するために使用されるタイプのオブジェクトのを。オブジェクトごとに1つのデータフレーバー(またはタイプ)に制限されません。そして、私たちのように、あなたのオブジェクトは複数の個性を持つことができます!たとえば、画像クラスは、Javaクラスまたはビットの配列(GIF、JPEGなど)として表すことができます。実際には、DataFlavorクラスはMIMEタイプのラッパーです。 MIME標準は広範囲にわたるため、クリップボードに転送できるデータに実質的に制限はありません。 (MIME標準に関する説明はこの記事の範囲外ですが、追加情報は「リソース」セクションにあります。)

データフレーバーの例として、StringSelectionクラスにはMIMEタイプに基づいた2つのフレーバーがあることがわかります。実装時は「application / x-java-serialized-object」で、2番目は「text / plain; charset = unicode」です。実際、この実装は、クリップボードからテキストをStringクラス(application/x-java-serialized-object)またはプレーンテキスト(text/plain; charset=unicode)として取得できることを示しています。

を作成するには2つの方法がありますDataFlavor。あなたは書ける:

public DataFlavor (representationClass, String humanRepresentationName)

このコンストラクターは、Javaクラスを表す新しいデータフレーバーを作成します。返さDataFlavorれるにはとがrepresentationClass = representationClassありますmimeType = application/x-java-serialized-object。例として、次のように作成しますDataFlavorのためにjava.awt.Button

DataFlavor (Class.forName ("java.awt.Button"), "AWT Button");

さて、この2番目のコンストラクター

public DataFlavor (String mimeType, String humanRepresentationName)

DataFlavor使用してを構築しMimeTypeます。返さDataFlavorれるのはに基づいていMimeTypeます。場合MimeTypeであるapplication/x-java-serialized-objectあなたは、以前のコンストラクタを呼ばれるかのように、結果は同じになります。それにもかかわらず、返さDataFlavorれるのはですrepresentationClass= InputStream and mimeType =mimeType。例として、次の呼び出しはプレーンテキストフレーバーを作成します。

public DataFlavor ("text/plain; charset=unicode", "Unicode");

次の表に、DataFlavorクラスのメソッドを示します。

DataFlavorクラス
メソッド 説明
boolean equals (DataFlavor) 提供されたDataFlavorがこのクラスで表されるDataFlavorと等しいかどうかをテストします
String getHumanPresentableName () このDataFlavorが表す形式の人間が表現できる名前を返します
void setHumanPresentableName (String) このDataFlavorの人間表現名を設定します
String getMimeType () このDataFlavorで表されるMIMEタイプの文字列を取得します
Class getRepresentationClass () このクラスを表すクラスを返します

転送可能なインターフェース

Transferableインターフェースはあなたがクリップボードに送信するすべてのクラスによって実装される必要があり、それゆえにClipboardクラスは唯一で包まれたクラスを理解するTransferableインターフェイスを。Transferableインターフェースは三つの方法で構成されています。

転送可能なインターフェース
メソッド 説明
DataFlavor getTransferDataFlavor () オブジェクトを表すDataFlavorの配列を返します
boolean isDataFlavorSupported (DataFlavor) 提供されたDataFlavorがサポートされているかどうかをテストします
Object getTransferData (DataFlavor) 提供されたDataFlavorによって表されるオブジェクトを返します

これで、クリップボードの処理に関係するすべてのクラスのツアーは終了です。クリップボードにアクセスするには、Clipboardオブジェクトを作成するか、システムクリップボードへの参照を取得する必要があることを確認しました。クリップボードはタイプのオブジェクトのみを受け入れるため、クリップボードTransferableに送信するオブジェクトはこのインターフェイスを実装する必要があります。最後に、クリップボード内のすべてのオブジェクトには、DataFlavorクラスによって表されるフレーバーがあります。これは、実際にはMIMEタイプのラッパーです。

次のセクションでは、私たちが学んだことを実践します。

クリップボード利用のレシピ

これらのさまざまなクラスがクリップボードにアクセスする方法は、混乱を招く可能性があります。幸いなことに、次の手順を含む簡単なレシピがあります。

手順1.xxxxSelectionというクラスを作成します。ここで、xxxはこのフレーバーによって表されるタイプに名前を付ける必要があります。たとえばImageSelection、画像フレーバーの良い名前になります。もちろん、この命名規則は単なる提案にすぎません。私はStringSelectionJDKで提供されている使用規則に従っていますが、このクラスには任意の名前を付けることができます。このオブジェクトはTransferableClipboardOwnerインターフェイスを実装する必要があることを覚えておくことが重要です。テキストの転送を計画している場合は、StringSelection代わりにクラスを使用する必要があります。

手順2.クリップボードにアクセスするためのクラスを定義します。ローカルクリップボードにアクセスするには、次の呼び出しを使用しますClipboard clipboard = new Clipboard ("name")。ピアオペレーティングシステムのクリップボードにアクセスするには、代わりに次の呼び出しを使用しますClipboard clipboard = getToolkit ().getSystemClipboard ()

手順3.クリップボードの内容を設定します。これを行うにsetContentは、Clipboardクラスのメソッドを使用します。最初のパラメーターはTransferablexxxxSelectionステップ1で作成されたクラス)を実装するオブジェクトであり、2番目のパラメーターはこのメソッドを呼び出すクラスへの参照です。

手順4.クリップボードの内容を取得します。クラスのgetContentメソッドを使用しClipboardます。このメソッドは、タイプのクラスを返しTransferableます。

ステップ5.「カット操作」を実装します。これを行うには、データがクリップボードにコピーされたら、手動でデータを消去する必要があります。Javaは、カット操作の実装を提供しません。

クリップボードの操作を含むクラスのこの簡単なツアーの後、提案されたレシピに従って、テキストをシステムクリップボードに転送する簡単なアプレットを作成します。

リスト1

このアプレットを調べてみましょう。

リスト1

以下は、リスト1の特定のコード行の説明です。

9行目:クラスapplet1を定義してクラスを拡張しAppletClipboardOwnerインターフェースを実装します。

17行目:クリップボードオブジェクトを定義します。

26行目:クリップボードオブジェクトをピアオペレーティングシステムのクリップボードに設定します。

45行目から47行目:このインターフェースに唯一のメソッドを実装します。この記事では、このlostOwnership方法を使用せず、コンソールにメッセージを出力するだけです。このアプレットを使用してテキストをクリップボードにコピーし、別のアプリケーションから別のテキストをコピーすることで、この方法を試すことができます。(Javaアプレットを使用して)クリップボードに配置されたデータが他のアプリケーションによって上書きされたため、所有権が失われたというメッセージがJavaコンソールに表示されるはずです。

52行目:StringSelectionテキストデータフレーバーを実装するタイプのクラスを定義します。次に、ソーステキストフィールドのコンテンツを取得します。

53行目:クリップボードの内容をfieldContent前の行で定義したクラスに設定します。このクラスの所有者、この場合はこのアプレットを提供する必要があることに注意してください。

61行目:Transferableクリップボードのコンテンツを受け取るタイプのオブジェクトを定義します。

63行目: 2つのことを検証します。まず、クリップボードは空ですか?第二に、クリップボードの内容は正しい味ですか?この場合、を探していstringFlavorます。

67行目:クリップボードの内容を文字列変数で取得します。これを行うには、getTransferData必要なフレーバーを使用してメソッドを呼び出します。この場合、DataFlavor.stringFlavorタイプが必要です。

69行目:宛先テキストフィールドの内容をクリップボードの内容に設定します。

このアプレットと別のJavaアプレットの間、またはJavaアプレットとメモ帳などのネイティブプログラムの間でテキストを転送することで、このアプレットを試すことができます(Microsoft Windowsを実行している場合)。

リスト2

2番目の例では、画像をクリップボードにコピーするアプレットを作成します。画像は独自のフレーバーを実装します。

リスト2

以下は、リスト2の特定のコード行の説明です。

27行目:ローカルクリップボードを参照するクリップボードオブジェクトを作成します。

41行目:sourImageコントロールをに設定しImage.gifます。

44行目から50行目:lostOwnershipメソッドを実装します。Javaコンソールにメッセージを出力するだけです。

6行目:コントロールのImageSelection画像に基づいてオブジェクトを作成しますsourceImage

57行目:クリップボードの内容をImageSelectionオブジェクトで設定します。

66行目:クリップボードの内容を取得します。

68行目:コンテンツがnullでないこと、および探しているフレーバーがサポートされていることを確認します。

71行目:適切なフレーバーでデータを取得します。

72行目:destinationImageコントロールを取得したばかりのコンテンツに設定します。

90行目:ImageSelectionクラスを定義します。

93行目: 1つの要素()でDataFlavor呼び出された配列を定義します。supportedFlavorsimageFlavor

102行目:画像フレーバーを作成します。作成されるフレーバーはjava.awt.Image、表現名「Image」のに基づいています。

111行目から130行目:Transferableメソッドを実装します。

123行目:このメソッドを使用してクリップボードの内容を返します。

125行目:フレーバーを検証します。要求されたフレーバーがサポートされている場合、画像オブジェクトが返されます。それ以外の場合は、例外がスローされます。

リスト1では、デフォルトのデータフレーバー(StringSelection)を使用してテキストをシステムクリップボードに送信しました。リスト2では、独自のデータフレーバーを実装することでさらに進んでいますjava.awt.Image