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

Posted by aterai at 2012-08-06

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

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

  • &jnlp;
  • &jar;
  • &zip;
DragSourceMotionListener.png

サンプルコード

final JWindow window = new JWindow();
window.add(label);
window.setAlwaysOnTop(true);
com.sun.awt.AWTUtilities.setWindowOpaque(window, false); // JDK 1.6.0
//window.setBackground(new Color(0, true)); // JDK 1.7.0
DragSource.getDefaultDragSource().addDragSourceMotionListener(new DragSourceMotionListener() {
  @Override public void dragMouseMoved(DragSourceDragEvent dsde) {
    window.setLocation(dsde.getLocation());
    window.setVisible(true);
  }
});
View in GitHub: Java, Kotlin

解説

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

  • 注: DragSourceDragEvent#getLocation() で取得できる位置は、スクリーン上でのマウス位置なので、MouseEvent#getPoint() の場合のようにSwingUtilities.convertPointToScreen(pt, c); で変換しなくて良い

参考リンク

コメント

  • OSXなどの場合はどうなるか不明(テストしていない)。 -- aterai