概要
ドラッグ中のカーソル位置をDragSourceMotionListener
で取得し、そこにアイコンを追加したWindow
を移動することで、JFrame
の外側でもドラッグアイコンを表示します。
Screenshot
Advertisement
サンプルコード
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(0x0, true)); // JDK 1.7.0
DragSource.getDefaultDragSource().addDragSourceMotionListener(new DragSourceMotionListener() {
@Override public void dragMouseMoved(DragSourceDragEvent dsde) {
window.setLocation(dsde.getLocation());
}
});
View in GitHub: Java, Kotlin解説
上記のサンプルでは、JPanel
中に配置されているアイコンなどを設定したJLabel
をDrag & Drop
で別のJPanel
(例えば親のJFrame
が異なる場合も可)に移動できます。JLabel
のドラッグ開始時に元の親JPanel
からそれを削除して透明化したWindow
に移し替え、ドラッグに合わせてWindow
自体を移動しているのでJFrame
の外でもドラッグアイコンが表示可能です。
- ドラッグ中のカーソル位置取得には
MouseMotionListener
を使用する方法もあるが、このサンプルのようなTransferHandler
を使ったドラッグではMouseMotionListener
でマウスイベントを取得できないのでDefaultDragSource
にDragSourceMotionListener
を追加してドラッグ中のカーソル位置を取得している DragSourceDragEvent#getLocation()
で取得した位置はスクリーン座標系なのでそのままWindow#setLocation(...)
メソッドで使用可能Point pt = tgtLabel.getLocation()
で取得したドラッグ対象JLabel
の位置は親コンポーネントの座標系なのでSwingUtilities.convertPointToScreen(pt, parent)
で変換する必要がある