TITLE:JFrameの外側でもドラッグアイコンを表示する
Posted by aterai at 2012-08-06

JFrameの外側でもドラッグアイコンを表示する

ドラッグ中のカーソル位置をDragSourceMotionListenerで取得し、そこにアイコンを追加したWindowを移動することで、JFrameの外側でもドラッグアイコンを表示します。
  • category: swing folder: DragSourceMotionListener title: JFrameの外側でもドラッグアイコンを表示する tags: [DragAndDrop, JWindow, ImageIcon, JFrame, JLabel] author: aterai pubdate: 2012-08-06T15:46:37+09:00 description: ドラッグ中のカーソル位置をDragSourceMotionListenerで取得し、そこにアイコンを追加したWindowを移動することで、JFrameの外側でもドラッグアイコンを表示します。 image: https://lh4.googleusercontent.com/-HM5QzW5AZlk/UB9iFlbSZMI/AAAAAAAABQM/fggojAo0b-E/s800/DragSourceMotionListener.png

概要

ドラッグ中のカーソル位置をDragSourceMotionListenerで取得し、そこにアイコンを追加したWindowを移動することで、JFrameの外側でもドラッグアイコンを表示します。
DragSourceMotionListener.png

サンプルコード

#spanend
#spanadd
* サンプルコード [#sourcecode]
#spanend
#spanadd
#code(link){{
#spanend
final JWindow window = new JWindow();
window.add(label);
#spandel
window.setAlwaysOnTop(true);
#spanend
#spandel
com.sun.awt.AWTUtilities.setWindowOpaque(window, false); // JDK 1.6.0
#spanend
#spandel
//window.setBackground(new Color(0, true)); // JDK 1.7.0
#spanend
#spanadd
// window.setAlwaysOnTop(true);
#spanend
#spanadd
// com.sun.awt.AWTUtilities.setWindowOpaque(window, false); // JDK 1.6.0
#spanend
#spanadd
window.setBackground(new Color(0x0, true)); // JDK 1.7.0
#spanend
DragSource.getDefaultDragSource().addDragSourceMotionListener(new DragSourceMotionListener() {
  @Override public void dragMouseMoved(DragSourceDragEvent dsde) {
    window.setLocation(dsde.getLocation());
    window.setVisible(true);
  }
});

解説

上記のサンプルでは、JPanel中に配置したJLabel(アイコン)をDrag&Dropで別のJPanelなど(親のJFrameが異なっても可)に移動することができます。ドラッグ中のJLabelは透明化したWindowに配置され、ドラッグに合わせてそのWindowを移動しているので、JFrameの外でもドラッグアイコンが表示可能になっています。 ドラッグ中のカーソル位置取得には、MouseMotionListener を使用する方法もありますが、このサンプルのような TransferHandlerを使ったドラッグではMouseMotionListenerでマウスイベントを取得することができないので、DefaultDragSource に DragSourceMotionListener を追加してドラッグ中のカーソル位置を取得しています。
  • 注: DragSourceDragEvent#getLocation()で取得できる位置は、スクリーン上でのマウス位置なので、MouseEvent#getPoint()の場合のようにSwingUtilities.convertPointToScreen(pt, c);で変換しなくて良い

解説

上記のサンプルでは、JPanel中に配置されているアイコンなどを設定したJLabelDrag & Dropで別のJPanel(例えば親のJFrameが異なる場合も可)に移動できます。JLabelのドラッグ開始時に元の親JPanelからそれを削除して透明化したWindowに移し替え、ドラッグに合わせてWindow自体を移動しているのでJFrameの外でもドラッグアイコンが表示可能です。

参考リンク

  • ドラッグ中のカーソル位置取得にはMouseMotionListenerを使用する方法もあるが、このサンプルのようなTransferHandlerを使ったドラッグではMouseMotionListenerでマウスイベントを取得できないのでDefaultDragSourceDragSourceMotionListenerを追加してドラッグ中のカーソル位置を取得している
  • DragSourceDragEvent#getLocation()で取得した位置はスクリーン座標系なのでそのままWindow#setLocation(...)メソッドで使用可能
  • Point pt = tgtLabel.getLocation()で取得したドラッグ対象JLabelの位置は親コンポーネントの座標系なのでSwingUtilities.convertPointToScreen(pt, parent)で変換する必要がある

参考リンク

コメント

コメント