Swing/DragSourceMotionListener のバックアップの現在との差分(No.9)
- バックアップ一覧
- 差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- バックアップ を表示
- Swing/DragSourceMotionListener へ行く。
- 1 (2012-08-06 (月) 15:46:37)
- 2 (2012-08-07 (火) 11:04:46)
- 3 (2012-08-07 (火) 14:19:12)
- 4 (2012-11-17 (土) 03:46:38)
- 5 (2012-12-07 (金) 18:13:23)
- 6 (2013-01-29 (火) 23:42:26)
- 7 (2013-10-25 (金) 18:04:11)
- 8 (2013-10-29 (火) 15:37:15)
- 9 (2013-10-30 (水) 21:20:06)
- 10 (2014-11-01 (土) 00:46:09)
- 11 (2015-04-02 (木) 15:10:43)
- 12 (2017-02-28 (火) 13:07:16)
- 13 (2017-11-02 (木) 15:34:40)
- 14 (2018-01-04 (木) 12:29:03)
- 15 (2018-09-27 (木) 20:48:31)
- 16 (2020-09-29 (火) 18:32:53)
- 17 (2022-06-01 (水) 16:53:24)
- 18 (2022-08-20 (土) 22:15:25)
- 追加された行はこの色です。
- 削除された行はこの色です。
TITLE:JFrameの外側でもドラッグアイコンを表示する #navi(../) #tags(DragAndDrop, JWindow, ImageIcon, JFrame) RIGHT:Posted by &author(aterai); at 2012-08-06 * JFrameの外側でもドラッグアイコンを表示する [#c4f3f6cb] --- 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 --- * 概要 [#summary] ドラッグ中のカーソル位置を`DragSourceMotionListener`で取得し、そこにアイコンを追加した`Window`を移動することで、`JFrame`の外側でもドラッグアイコンを表示します。 - &jnlp; - &jar; - &zip; #download(https://lh4.googleusercontent.com/-HM5QzW5AZlk/UB9iFlbSZMI/AAAAAAAABQM/fggojAo0b-E/s800/DragSourceMotionListener.png) #ref(https://lh4.googleusercontent.com/-HM5QzW5AZlk/UB9iFlbSZMI/AAAAAAAABQM/fggojAo0b-E/s800/DragSourceMotionListener.png) ** サンプルコード [#f394f0f4] * サンプルコード [#sourcecode] #code(link){{ 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 // 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()); } }); }} ** 解説 [#s38cbe68] 上記のサンプルでは、`JPanel`中に配置した`JLabel`(アイコン)を`Drag & Drop`で別の`JPanel`など(親の`JFrame`が異なる場合も可)に移動することができます。ドラッグ中の`JLabel`は透明化した`Window`に配置され、ドラッグに合わせてその`Window`を移動しているので、`JFrame`の外でもドラッグアイコンが表示可能になっています。 ドラッグ中のカーソル位置取得には、`MouseMotionListener`を使用する方法もありますが、このサンプルのような`TransferHandler`を使ったドラッグでは`MouseMotionListener`でマウスイベントを取得することができないので、`DefaultDragSource`に`DragSourceMotionListener`を追加してドラッグ中のカーソル位置を取得しています。 * 解説 [#explanation] 上記のサンプルでは、`JPanel`中に配置されているアイコンなどを設定した`JLabel`を`Drag & Drop`で別の`JPanel`(例えば親の`JFrame`が異なる場合も可)に移動できます。`JLabel`のドラッグ開始時に元の親`JPanel`からそれを削除して透明化した`Window`に移し替え、ドラッグに合わせて`Window`自体を移動しているので`JFrame`の外でもドラッグアイコンが表示可能です。 - 注: -- `DragSourceDragEvent#getLocation()`で取得した位置は、スクリーン座標系なので、そのまま`Window#setLocation(...)`で使用可能 -- `Point pt = tgtLabel.getLocation();`で取得した位置は、親コンポーネントの座標系なので、`SwingUtilities.convertPointToScreen(pt, parent);`で変換する必要がある - ドラッグ中のカーソル位置取得には`MouseMotionListener`を使用する方法もあるが、このサンプルのような`TransferHandler`を使ったドラッグでは`MouseMotionListener`でマウスイベントを取得できないので`DefaultDragSource`に`DragSourceMotionListener`を追加してドラッグ中のカーソル位置を取得している - `DragSourceDragEvent#getLocation()`で取得した位置はスクリーン座標系なのでそのまま`Window#setLocation(...)`メソッドで使用可能 - `Point pt = tgtLabel.getLocation()`で取得したドラッグ対象`JLabel`の位置は親コンポーネントの座標系なので`SwingUtilities.convertPointToScreen(pt, parent)`で変換する必要がある ** 参考リンク [#jda9a30f] * 参考リンク [#reference] - [[JLayerを使ってJTabbedPaneのタブの挿入位置を描画する>Swing/DnDLayerTabbedPane]] ** コメント [#y921464d] - `OSX`などの場合はどうなるか不明(テストしていない)。 -- [[aterai]] &new{2012-08-06 (月) 15:50:35}; - `OSX`でも表示しましたよ。ただクリックした時にアイコン周りに枠が表示されるのですが、その位置がアイコンとずれてます -- [[nsby]] &new{2012-08-07 (火) 11:04:46}; -- ありがとうございます。[http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4874070 Bug ID: 4874070 invoking DragSource's startDrag with an Image renders no image on drag]あたりの修正の詳しい内容がよく分かっていないので、逆に`Mac OS X`では競合する(二重になる)のでは?と思っていました。「アイコン周りの枠」はオフセットを変更するか、クリックした時点で`JPanel`からは削除してしまえば、何とかなるかもしれません。 -- [[aterai]] &new{2012-08-07 (火) 14:19:12}; - `Web Start`で起動すると、`window.setAlwaysOnTop(true);`で`AccessControlException`が発生するのを修正。 -- [[aterai]] &new{2012-12-07 (金) 18:20:23}; - ドラッグ中カーソルが点滅するので、`dragMouseMoved`内で無駄に`Window#setVisible(true);`を実行しないように修正(`TransferHandler#getSourceActions(...)`内でドラッグ開始時に一回だけ実行する)。 -- [[aterai]] &new{2013-10-25 (金) 18:04:11}; * コメント [#comment] #comment - `OSX`などの場合はどうなるか不明(テストしていない)。 -- &user(aterai); &new{2012-08-06 (月) 15:50:35}; - `OSX`でも表示しましたよ。ただクリックした時にアイコン周りに枠が表示されるのですが、その位置がアイコンとずれてます -- &user(nsby); &new{2012-08-07 (火) 11:04:46}; -- ありがとうございます。[https://bugs.openjdk.org/browse/JDK-4874070 Bug ID: 4874070 invoking DragSource's startDrag with an Image renders no image on drag]あたりの修正の詳しい内容がよく分かっていないので、逆に`Mac OS X`では競合する(二重になる)のでは?と思っていました。「アイコン周りの枠」はオフセットを変更するか、クリックした時点で`JPanel`からは削除してしまえば、何とかなるかもしれません。 -- &user(aterai); &new{2012-08-07 (火) 14:19:12}; - `Web Start`で起動すると、`window.setAlwaysOnTop(true);`で`AccessControlException`が発生するのを修正。 -- &user(aterai); &new{2012-12-07 (金) 18:20:23}; - ドラッグ中カーソルが点滅するので、`dragMouseMoved`内で無駄に`Window#setVisible(true);`を実行しないように修正(`TransferHandler#getSourceActions(...)`内でドラッグ開始時に一回だけ実行する)。 -- &user(aterai); &new{2013-10-25 (金) 18:04:11}; #comment