Swing/DragScrollLayer のバックアップソース(No.4)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- バックアップ を表示
- Swing/DragScrollLayer へ行く。
- 1 (2013-08-05 (月) 11:49:22)
- 2 (2013-08-06 (火) 13:26:01)
- 3 (2013-08-07 (水) 20:02:01)
- 4 (2014-11-21 (金) 18:11:05)
- 5 (2015-02-03 (火) 16:22:29)
- 6 (2016-08-11 (木) 21:31:34)
- 7 (2016-09-29 (木) 17:14:01)
- 8 (2017-03-28 (火) 15:10:45)
- 9 (2017-03-29 (水) 19:48:54)
- 10 (2018-02-28 (水) 19:07:59)
- 11 (2020-03-04 (水) 16:54:39)
- 12 (2021-08-17 (火) 20:09:08)
--- title: JScrollPane内にある複数Componentを配置したJPanelをJLayerを使ってドラッグスクロール tags: [JScrollPane, JPanel, JLayer] author: aterai pubdate: 2013-08-05T11:49:22+09:00 description: 複数のネストしたComponentを配置したJPanelのドラッグイベントを、JScrollPaneをラップしたJLayerで受け取ってスクロール可能にします。 --- * 概要 [#s1cfff1c] 複数のネストした`Component`を配置した`JPanel`のドラッグイベントを、`JScrollPane`をラップした`JLayer`で受け取ってスクロール可能にします。 #download(https://lh5.googleusercontent.com/-5zBF0JOr6kM/UfuiEj7Do7I/AAAAAAAABxg/7tKYnrOl9eo/s800/DragScrollLayer.png) * サンプルコード [#k3c044c8] #code(link){{ class DragScrollLayerUI extends LayerUI<JScrollPane> { private final Point pp = new Point(); @Override public void installUI(JComponent c) { super.installUI(c); JLayer jlayer = (JLayer)c; jlayer.setLayerEventMask( AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK); } @Override public void uninstallUI(JComponent c) { JLayer jlayer = (JLayer)c; jlayer.setLayerEventMask(0); super.uninstallUI(c); } @Override protected void processMouseEvent( MouseEvent e, JLayer<? extends JScrollPane> l) { Component c = e.getComponent(); if(c instanceof JScrollBar || c instanceof JSlider) { return; } if(e.getID()==MouseEvent.MOUSE_PRESSED) { JViewport vport = l.getView().getViewport(); Point cp = SwingUtilities.convertPoint(c, e.getPoint(), vport); pp.setLocation(cp); } } @Override protected void processMouseMotionEvent( MouseEvent e, JLayer<? extends JScrollPane> l) { Component c = e.getComponent(); if(c instanceof JScrollBar || c instanceof JSlider) { return; } if(e.getID()==MouseEvent.MOUSE_DRAGGED) { JViewport vport = l.getView().getViewport(); JComponent cmp = (JComponent)vport.getView(); Point cp = SwingUtilities.convertPoint(c, e.getPoint(), vport); Point vp = vport.getViewPosition(); vp.translate(pp.x-cp.x, pp.y-cp.y); cmp.scrollRectToVisible(new Rectangle(vp, vport.getSize())); pp.setLocation(cp); } } } }} * 解説 [#u8652939] - 左: `DragScrollListener` -- [[JTreeの余白をドラッグしてスクロール>Swing/TreeDragScroll]] -- このリスナーを追加した一つの`Component`をドラッグしてスクロールが可能 -- `JPanel`を掴んでスクロールすることができるが、その子コンポーネントの`JTabbedPane`などをドラッグしてもスクロールはできない - 右: `DragScrollLayer` -- すべての下位コンポーネントの`MouseEvent`をキャッチするよう`JLayer#setLayerEventMask(...)`と設定した`JLayer`を作成 -- この`JLayer`で`JScrollPane`をラップし、子にマウスイベントを消費するコンポーネントがあっても、ビューである`JPanel`をドラッグに応じてスクロール -- `JScrollBar`や`JSlider`のように、ノブのドラッグを使用するコンポーネントは二重にスクロールしてしまうので除外 * 参考リンク [#y3afd013] - [http://java-swing-tips.blogspot.jp/2009/03/mouse-dragging-viewport-scroll.html Java Swing Tips: Mouse Dragging ViewPort Scroll] - [[JTreeの余白をドラッグしてスクロール>Swing/TreeDragScroll]] - [[JScrollPaneのViewportをマウスで掴んでスクロール>Swing/HandScroll]] * コメント [#i29c712d] #comment #comment