目次 | 前の項目 | 次の項目 | ドラッグ&ドロップ |
DragSource (ドラッグ元) は、ドラッグ&ドロップ操作を開始する構成要素です。
DragSource および関連付けられた定数のインタフェースは、次のように定義されています。DnDConstants クラスは、転送対象に適用される可能性のある操作を定義しています。
public class java.awt.dnd.DnDConstants { public static int ACTION_NONE = 0x0; public static int ACTION_COPY = 0x1; public static int ACTION_MOVE = 0x2; public static int ACTION_COPY_OR_MOVE = ACTION_COPY | ACTION_MOVE; public static int ACTION_REFERENCE = 0x40000000; } public class java.awt.dnd.DragSource { public static Cursor getDefaultCopyDropCursor(); public static Cursor getDefaultMoveDropCursor(); public static Cursor getDefaultLinkDropCursor(); public static Cursor getDefaultCopyNoDropCursor(); public static Cursor getDefaultMoveNoDropCursor(); public static Cursor getDefaultLinkNoDropCursor(); public static DragSource getDefaultDragSource(); public void startDrag(Component c, AWTEvent trigger, int actions, Cursor dragCursor, Image dragImage, Point dragImageOffset, Transferable transferable, DragSourceListener dsl) throws InvalidDnDOperationException; protected DragSourceContext createDragSourceContext( DragSourceContextPeer dscp, Component c, int actions, Cursor dragCursor, Image dragImage, Point dragImageOffset, Transferable transferable, DragSourceListener dsl ); public FlavorMap getFlavorMap(); }
DragSource は、数多くの状況で使用される可能性があります。
制御オブジェクトであるドラッグイニシエータは、ドラッグ操作を処理するために、ユーザのジェスチャーの前またはジェスチャー時に DragSource のインスタンスを取得します。ユーザのジェスチャーの最初の解釈時、およびそれに続くドラッグ操作の開始時に、Component または関連付けられた制御エンティティが実装されます。
ジェスチャーが発生すると、ユーザによる操作ジェスチャーを処理し、ドラッグ&ドロッププロトコルの通知を配布するために、DragSource の startDrag() メソッドが呼び出されます。
ドラッグ操作を開始するために、startDrag() メソッドの呼び出し元は、次のパラメータを提供します。
この機能をサポート可能なプラットフォーム上では、ドラッグイメージを操作に関連付けて、より忠実に Drag Over をフィードバックできます。このイメージは、通常は、ドラッグされる 1 つまたは複数のオブジェクトの小さな「アイコン」の表示で、背後のシステムは、Cursor アニメーションの動きを追跡しながらこのイメージを読み込みます。イメージは、Cursor アニメーションと同時に動きますが、通常は、Cursor アニメーションとは別のものです。この機能が利用できない箇所、または背後のシステムが描画するのにイメージだと適切でない場所では、このパラメータは無視され、Cursor の Drag Over アニメーションだけが表示されるので、アプリケーションは、この機能に依存しません。
Transferable のインスタンスは、ドラッグ操作の開始時に DragSource に関連付けられ、ドラッグ&ドロップのオペランドまたは対象である、オブジェクトまたはデータを表しています。これは、ドラッグ操作のあと、DropTarget に関連付けられた Component 上でドロップが成功した結果として、DragSource から DropTarget に渡される情報です。コンテナオブジェクトを作成し、転送の対象にして Transferable を実装することによって、同じ種類または異なる種類のオブジェクトの複数コレクションをドラッグ&ドロップ操作の対象にすることも可能です。ただし、ターゲットとなるどのネイティブプラットフォームシステムでも、このようなコレクションを記述および転送するメカニズムは標準ではサポートされていません。そのため、透過的かつプラットフォーム移植性の高い方法では、このような転送を実装することはできません。
前述したように、startDrag() メソッドの主な役割は、ユーザのためにドラッグを開始することです。このためには、startDrag() メソッドは、DragSourceContext のインスタンスを作成してメソッドの操作を独自に追跡する必要があります。さらに重要なことは、このメソッドは、背後のプラットフォーム実装内で、操作を独自に開始しなければならないことです。これを行うために、DragSource は、まず背後のシステムから (通常は java.awt.Toolkit.createDragSourceContextPeer() メソッドの呼び出しにより) DragSourceContextPeer を取得してから、新しく作成された DragSourceContextPeer (背後のシステムの機能にプラットフォームに依存しないインタフェースを提供する) を DragSourceContext に関連付ける必要があります。startDrag() は、createDragSourceContext() メソッドを呼び出して、適切な DragSourceContext のインスタンスを生成し、DragSourceContextPeer を関連付けます。ドラッグ&ドロップシステムが、なんらかの理由でドラッグ操作を開始できない場合は、startDrag() メソッドは、java.awt.dnd.InvalidDnDOperationException を発行してその状態を示します。一般的に、この例外は、背後のプラットフォームシステムがドラッグを開始する状態にない場合か、または指定されたパラメータが無効な場合に発行されます。
ドラッグ操作中には、転送元に対する操作のセット、またはドラッグ操作の開始時に Transferable によって公開された DataFlavors のセットは、変更できないことに注意してください。ドラッグ操作中は、DragSource に関する操作およびデータが一定である必要があります。
セキュリティの理由から、startDrag() メソッドの呼び出し元には、AWTPermission startDrag がある必要があります。このアクセス権を持たずにこのメソッドを呼び出すと、SecurityException が発行されます。
getFlavorMap() メソッドは、Transferable によって公開された DataFlavors を、背後のドラッグ&ドロッププラットフォームのデータ型名にマップするために、背後のシステムによる FlavorMap オブジェクトの取得に使われます。[FlavorMapの詳細は、以降を参照]
DragSource の startDrag() メソッドが正常に呼び出された結果、DragSourceContext クラスのインスタンスが作成されます。このインスタンスは、DragSource のために操作の状態を追跡し、状態の変化を DragSourceListener に配布する役割を果たします。DragSourceContext クラスは、次のように定義されています。
public class DragSourceContext implements DragSourceListener { protected DragSourceContext( DragSource ds, DragSourceContextPeer dscp, int actions, Cursor dragCursor, Image dragImage, Point dragOffset, Transferable transferable, DragSourceListener dsl ); public DragSource getDragSource(); public Component getComponent(); public AWTEvent getTrigger(); public Image getDragImage(); public Point getDragImageOffset(); public int getSourceActions(); Cursor getCursor(); void setCursor(Cursor Cursor) throws InvalidDnDOperationException; void cancelDrag() throws InvalidDnDOperationException; void addDragSourceListener(DragSourceListener dsl) throws TooManyListenersException; void removeDragSourceListener(DragSourceListener dsl); }
DragSourceContext 自体が DragSourceListener を実装することに注目してください。これにより、DragSource によって作成されたプラットフォームのピアである DragSourceContextPeer のインスタンスは、DragSourceContext に進行中の操作状態の変化について通知できるようになり、したがって DragSourceContext は、プラットフォームと操作のイニシエータによって提供された DragSourceListener の間に割り込むことができるようになります。転送元に関しプラットフォームが示す状態、またはドラッグ&ドロップ操作のイニシエータの詳細を次に示します。
ドラッグ&ドロップ操作中のイニシエータに関する状態の変化の通知は、上に示したように、DragSourceContextPeer から適切な DragSourceContext に配布されます。DragSourceContext は通知を、ユニキャスト JavaBeans に準拠した EventListener サブインタフェースを介して、startDrag() で DragSource に登録された DragSourceListener を実装する任意のオブジェクトに委譲します。
DragSourceListener の主な役目は、ドラッグ&ドロップ操作中にユーザ操作の進行を監視して、Drag-Over 効果をユーザにフィードバックすることです。一般的に、フィードバックは、Drag Cursor を変更することで行われます。
各 DragSource オブジェクトには、2 種類の論理カーソルの状態が関連付けられています。
Cursor の状態は、DragSourceContext の setCursor() メソッドを呼び出すことによって、変更できます。
DragSourceListener インタフェースは、次のように定義されています。
public interface java.awt.dnd.DragSourceListener extends java.util.EventListener { void dragEnter (DragSourceDragEvent dsde); void dragOver (DragSourceDragEvent dsde); void dragGestureChanged(DragSourceDragEvent dsde); void dragExit (DragSourceEvent dse); void dragDropEnd (DragSourceDropEvent dsde); }
ドラッグ操作が進行するに従って、DragSourceListener の dragEnter()、dragOver()、および dragExit() メソッドが呼び出されます。これは、ユーザがカーソルを移動することによって、DropTarget が関連付けられている GUI Component のジオメトリに、論理 Drag カーソルの位置が交差した結果です。[Drop Target's プロトコルの相互作用に関する詳細は以下を参照]DragSourceListener の dragEnter() メソッドは、次の条件が満たされたときに呼び出されます。
- 論理カーソルのホットスポットが、ある GUI Component の可視ジオメトリに最初に交わった
- その Component に、アクティブな DropTarget が関連付けられている
- DropTarget の登録された DropTargetListener dragEnter() メソッドが呼び出され、正常に復帰した
- 登録された DropTargetListener が、DropTargetDragEvent の acceptDrag() メソッドを呼び出して、転送元が実行する可能性のあるドロップ動作、および利用可能なデータ型 (DataFlavors) を調べた上で、ドラッグを受け入れた
DragSourceListener の dragOver() メソッドは、次の条件が満たされたときに呼び出されます。
DragSourceListener の dragExit() メソッドは、次の条件のうちの 1 つが満たされたときに呼び出されます。
DragSourceListener の dragGestureChanged() メソッドは、ドラッグ操作を実行するためにユーザが対話している、マウスボタンやキーボードのキーなどの入力デバイスの状態が変わったときに呼び出されます。dragDropEnd() メソッドは、操作が完了したことを示すために呼び出されます。DragSourceDropEvent の isDropAborted() および isDropSuccessful() メソッドは、終了状態を決定するために使用します。getDropAction() メソッドは、DropTarget が DropTargetDropEvent の acceptDrop() パラメータを介してドロップ操作に適用するために選択した操作を返します。1
このメソッドが完了すると、DragSourceContext および関連付けられたリソースが無効になります。
DragSourceEvent クラスは、DragSource に属するすべてのイベントのルート Event クラスで、次のように定義されています。
public class java.awt.dnd.DragSourceEvent extends java.util.EventObject { public DragSourceEvent(DragSourceContext dsc); public DragSourceContext getDragSourceContext(); };
このイベントのインスタンスは、DragSourceListener dragExit() メソッドに渡されます。
DragSourceDragEvent クラスは、次のように定義されています。
public class java.awt.dnd.DragSourceDragEvent extends DragSourceEvent { public int getTargetActions(); public int getGestureModifiers(); public boolean isDropTargetLocal(); }
このクラスのインスタンスは、DragSourceListener の dragEnter()、dragOver()、および dragGestureChanged() の各メソッドに渡されます。getDragSourceContext() メソッドは、現在のドラッグ&ドロップ操作に関連付けられた DragSourceContext を返します。
getTargetActions() メソッドは、現在の DropTarget がサポートする、またその DropTarget が返すドロップ動作を返します。dragGestureChanged() が呼び出された場合は、ドロップ動作があれば返します。
getGestureModifiers() は、ユーザのジェスチャーに関連付けられた入力デバイスの識別子の現在の状態を返します。通常、入力デバイスの識別子は、マウスボタンおよびキーボードのキーです。 isDropTargetLocal() メソッドは、現在の DropTarget が DragSource と同じ JVM 内にある場合に ture を返し、そうでない場合には false を返します。これは、特定のローカルの最適化を実現するために、DragSource の Transferable を実装する場合に便利な情報です。
DragSourceDropEvent クラスは、次のように定義されています。
public public class java.awt.dnd.DragSourceDropEvent extends java.util.EventObject { public DragSourceDropEvent(DragSourceContext dsc); public DragSourceDropEvent(DragSourceContext dsc, int action, boolean success); public boolean isDropAborted(); public boolean isDropSuccessful(); public int getDropAction(); }
このクラスのインスタンスは、DragSourceListener の dragDropEnd() メソッドに渡されます。このイベントはドラッグ&ドロップ操作の終了時の DragSource の状態をカプセル化します。ドロップが発生して、ドロップに参加した DropTarget が DropTargetContext の dropComplete() メソッドを介してデータ転送の成功または失敗を示した場合、この状態は、isDropSuccessful() メソッドを介してイニシエータが取得できるようになります。ドロップ先である DropTarget がドラッグの対象に実行する操作は、(DropTarget の acceptDrop() メソッドにより渡され) getDropAction() メソッドを介して返されます。
ユーザが DropTarget の外でジェスチャーを終了したり、DropTarget が rejectDrop() を呼び出した場合など、なんらかの理由でドロップが発生する前にドラッグ操作が中止された場合は、isDropAborted() は false を返します。その他の場合は true を返します。