目次 | 前の項目 | 次の項目 | ドラッグ&ドロップ |
DragSource (ドラッグ元) は、ドラッグ&ドロップ操作を開始する構成要素です。
DragSource および関連付けられた定数のインタフェースは、次のように定義されています。DnDConstants クラスは、転送対象に適用される可能性のある操作を定義しています。
public final 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 DefaultCopyDrop; public static Cursor DefaultMoveDrop; public static Cursor DefaultLinkDrop; public static Cursor DefaultCopyNoDrop; public static Cursor DefaultMoveNoDrop; public static Cursor DefaultLinkNoDrop; public static DragSource getDefaultDragSource(); public static boolean isDragImageSupported(); public void startDrag(DragGestureEvent trigger, Cursor dragCursor, Image dragImage, Point dragImageOffset, Transferable transferable, DragSourceListener dsl, FlavorMap fm) throws InvalidDnDOperationException; protected DragSourceContext createDragSourceContext( DragSourceContextPeer dscp, DragGestureEvent trigger, Cursor dragCursor, Image dragImage, Point dragImageOffset, Transferable transferable, DragSourceListener dsl ); public FlavorMap getFlavorMap(); public DragGestureRecongizer createDragGestureRecognizer( Class abstractRecognizerClass, Component c, int srcActions, DragGestureListener dgl ); public DragGestureRecongizer createDefaultDragGestureRecognizer( Component c, int srcActions, DragGestureListener dgl ); }
DragSource は、数多くの状況で使用される可能性があります。
制御オブジェクトは、ドラッグ操作を処理するために、ユーザのジェスチャーの前に DragSource のインスタンスを取得して、関連する Component に影響を与えます。インスタンスを取得したら、DragGestureRecognizer を取得して、DragSource を Component に関連付ける必要があります。ユーザのジェスチャーの最初の解釈、およびそれに続くドラッグ操作の開始は、Component の実装によって行われます。通常これは、DragGestureRecognizer によって実装されます。
ジェスチャーが発生すると、ユーザによる操作ジェスチャーを処理し、ドラッグ&ドロッププロトコルの通知を配布するために、DragSource の startDrag() メソッドが呼び出されます。DragSource では、あらゆる時点で複数のドラッグ&ドロップ操作をカレントにすることはできません。現在の操作が完了するまでは、startDrag() 要求を追加しようとすると、IllegalDnDOperationException がスローされて拒否されます。
ドラッグ操作を開始するために、startDrag() メソッドの呼び出し元は、次のパラメータを提供します。
この機能をサポート可能なプラットフォーム上では、「ドラッグ」イメージを操作に関連付けて、より忠実に「Drag Over」をフィードバックできます。このイメージは、通常は、ドラッグされる 1 つまたは複数のオブジェクトの小さな「アイコン」で表示され、背後のシステムは、Cursor アニメーションの動きを追跡しながらこのイメージを読み込みます。イメージは、Cursor アニメーションと同時に動きますが、通常は、Cursor アニメーションとは別のものです。この機能が利用できない箇所、または背後のシステムが描画するのに適切でない種類のイメージの場合、このパラメータは無視され、結果的に Cursor の「Drag Over」アニメーションだけになるのでので、アプリケーションは、この機能に依存しません。特定のプラットフォーム上にこの機能が存在するかどうかは、static メソッド isDragImageSupported() を呼び出すことによってテストできます。
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 を発行してその状態を示します。一般的に、この例外は、基本的なプラットフォームシステムがドラッグを開始する状態にない場合か、または指定されたパラメータが無効な場合に発行されます。
ドラッグ操作中には、ソースがドラッグ操作の開始時に公開した操作のセットのいずれも変更できないことに注意してください。つまり、ドラッグ操作中は、DragSource に関する操作が一定になります。
getFlavorMap() メソッドは、Transferable によって公開された DataFlavors を、 基盤のドラッグ&ドロッププラットフォームのデータ型名にマップするために、基本的なシステムによる FlavorMap オブジェクトの取得に使われます。[FlavorMapの詳細は、以降を参照]
private FlavorMap は、DragSource の startDrag() メソッドに渡すことができます。 null も渡すことができますが、この場合は、その DragSource クラスまたはインスタンスの「デフォルト」の FlavorMap が使用されます。
DragSource の startDrag() メソッドが正常に呼び出された結果、DragSourceContext クラスのインスタンスが作成されます。このインスタンスは、DragSource のために操作の状態を追跡し、状態の変化を DragSourceListener に配布する役割を果たします。DragSourceContext クラスは、次のように定義されています。
public class DragSourceContext implements DragSourceListener { protected DragSourceContext( DragSourceContextPeer dscp, DragGestureEvent trigger, Cursor dragCursor, Image dragImage, Point dragOffset, Transferable transferable, DragSourceListener dsl ); public DragSource getDragSource(); public Component getComponent(); public DragGestureEvent getTrigger(); public Image getDragImage(); public Point getDragImageOffset(); public void transferablesFlavorsChanged(); public int getSourceActions(); public Cursor getCursor(); pbulic void setCursor(Cursor Cursor) throws InvalidDnDOperationException; public void addDragSourceListener(DragSourceListener dsl) throws TooManyListenersException; public void removeDragSourceListener(DragSourceListener dsl); protected updateCurrentCursor(int dropOperation, int targetActions, int status ); // values for status parameter above. protected static final int DEFAULT = 0; protected static final int ENTER = 1; protected static final int OVER = 2; protected static final int CHANGED = 3; protected boolean cursorDirty; }
DragSourceContext 自体が DragSourceListener を実装することに注目してください。これにより、DragSource によって作成されたプラットフォームのピアである DragSourceContextPeer のインスタンスは、DragSourceContext に進行中の操作状態の変化について通知できるようになり、したがって DragSourceContext は、プラットフォームと操作のイニシエータによって提供された DragSourceListener の間に割り込むことができるようになります。転送元、またはドラッグ&ドロップ操作のイニシエータに関してプラットフォームが公開する状態の変化の詳細は、次のとおりです。
ドラッグ&ドロップ操作中のイニシエータに関する状態の変化の通知は、上に示したように、DragSourceContextPeer から適切な DragSourceContext に配布されます。DragSourceContext は通知を、ユニキャスト JavaBeans に準拠した EventListener サブインタフェースを介して、startDrag() で DragSource に登録された DragSourceListener を実装する任意のオブジェクトに委譲します。
DragSourceListener の主な役目は、ドラッグ&ドロップ操作中にユーザ操作の進行を監視して、Drag-Over 効果をユーザにフィードバックすることです。一般的に、フィードバックは、Drag Cursor を変更することで行われます。
各ドラッグ操作には、次の 2 種類の論理カーソル (ドラッグカーソル) の状態が関連付けられています。
Cursor の状態は、DragSourceContext の setCursor() メソッドを呼び出すことによって、変更できます。
DragSourceListener インタフェースは、次のように定義されています。
public interface java.awt.dnd.DragSourceListener extends java.util.EventListener { void dragEnter (DragSourceDragEvent dsde); void dragOver (DragSourceDragEvent dsde); void dropActionChanged (DragSourceDragEvent dsde); void dragExit (DragSourceEvent dse); void dragDropEnd (DragSourceDropEvent dsde); }
ドラッグ操作が進行するに従って、DragSourceListener の dragEnter()、dragOver()、および dragExit() メソッドが呼び出されます。これは、DragTarget が関連付けれられている GUI Component のジオメトリに交差するように、論理 "Drag" カーソルの位置をユーザがナビゲートした結果です (Drop Target's プロトコルの交差に関する詳細は以下を参照してください)。
DragSourceListener の dragEnter() メソッドは、次の条件が満たされたときに呼び出されます。
DropTarget の登録された DropTargetListener dragEnter() メソッドが呼び出され、正常に復帰した登録された DropTargetListener が、DropTargetDragEvent の acceptDrag() メソッドを呼び出して、転送元が実行する可能性のあるドロップ動作、および利用可能なデータ型 (DataFlavors) を調べた上で、ドラッグを受け入れた
DragSourceListener の dragOver() メソッドは、次の条件が満たされたときに呼び出されます。
DragSourceListener の dragExit() メソッドは、次の条件のうちの 1 つが満たされたときに呼び出されます。
または
または
DragSourceListener の dropActionChanged() メソッドは、ドラッグ操作を実行するためにユーザが対話している、マウスボタンやキーボードのキーなどの入力デバイスの状態が変わったときに呼び出されます。dragDropEnd() メソッドは、操作が完了したことを示すために呼び出されます。DragSourceDropEvent の getDropSuccess() メソッドは、終了状態を決定するために使用されます。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 getUserAction(); public int getGestureModifiers(); public boolean isDropTargetLocal(); public int getDropAction(); }
このクラスのインスタンスは、DragSourceListener の dragEnter()、dragOver()、および dragGestureChanged() の各メソッドに渡されます。getDragSourceContext() メソッドは、現在のドラッグ&ドロップ操作に関連付けられた DragSourceContext を返します。
getTargetActions() メソッドは、現在の DropTarget がサポートする、またその DropTarget が返すドロップ動作を返します。dropActionChanged() が呼び出された場合は、ドロップ動作があれば返します。
getDropAction() メソッドは、ユーザジェスチャーによって現在選択されているアクションを返します。
getTargetActions() メソッドは、現在の DropTarget によってサポートされているアクションのセットを返します。
この 2 つの結果の論理和によって、ドロップによる実際の影響が定義されます。
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 getDropSuccess(); public int getDropAction(); }
このクラスのインスタンスは、DragSourceListener の dragDropEnd() メソッドに渡されます。このイベントはドラッグ&ドロップ操作の終了時の状態を DragSource のためにカプセル化します。ドロップが発生して、ドロップに参加した DropTarget が DropTargetContext の dropComplete() メソッドを介してデータ転送の成功または失敗を示した場合、この状態は、getDropSuccess() メソッドを介してイニシエータが取得できるようになります。ドロップ先である DropTarget がドラッグの対象に実行する操作は、(DropTarget の acceptDrop() メソッドにより渡され) getDropAction() メソッドを介して返されます。
ユーザが DropTarget の外部でジェスチャーを終了したり、DropTarget が rejectDrop() を呼び出した場合など、なんらかの理由でドロップが発生する前にドラッグ操作が中止された場合は、isGetDropSuccess() メソッドは false を返します。その他の場合は true を返します。
* この Web サイトで使用されている用語「Java 仮想マシン」または「JVM」は、Java プラットフォーム用の仮想マシンを表します。