Swing/TreeDragScroll のバックアップの現在との差分(No.3)
- バックアップ一覧
- 差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- バックアップ を表示
- Swing/TreeDragScroll へ行く。
- 追加された行はこの色です。
- 削除された行はこの色です。
TITLE:JTreeの余白をドラッグしてスクロール #navi(../) #tags(MouseListener, MouseMotionListener, JViewport, JScrollPane, JTree, JComponent) RIGHT:Posted by &author(aterai); at 2011-12-26 *JTreeの余白をドラッグしてスクロール [#b1773617] ``JTree``の余白などをマウスでドラッグしてスクロールします。 --- category: swing folder: TreeDragScroll title: JTreeの余白をドラッグしてスクロール tags: [MouseListener, MouseMotionListener, JViewport, JScrollPane, JTree, JComponent] author: aterai pubdate: 2011-12-26T14:16:38+09:00 description: JTreeの余白などをマウスでドラッグしてスクロールします。 image: https://lh3.googleusercontent.com/-8b-0M5bS9Tw/Tvf_XhVVreI/AAAAAAAABHU/BdECxkBAdzU/s800/TreeDragScroll.png --- * 概要 [#summary] `JTree`の余白などをマウスでドラッグしてスクロールします。 -&jnlp; -&jar; -&zip; #download(https://lh3.googleusercontent.com/-8b-0M5bS9Tw/Tvf_XhVVreI/AAAAAAAABHU/BdECxkBAdzU/s800/TreeDragScroll.png) //#screenshot #ref(https://lh3.googleusercontent.com/-8b-0M5bS9Tw/Tvf_XhVVreI/AAAAAAAABHU/BdECxkBAdzU/s800/TreeDragScroll.png) **サンプルコード [#g24696ef] * サンプルコード [#sourcecode] #code(link){{ class DragScrollListener extends MouseAdapter { Cursor defCursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR); Cursor hndCursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR); Point pp = new Point(); private Cursor defCursor = Cursor.getDefaultCursor(); private Cursor hndCursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR); private Point pp = new Point(); @Override public void mouseDragged(MouseEvent e) { JComponent jc = (JComponent)e.getSource(); Container c = jc.getParent(); if(c instanceof JViewport) { JViewport vport = (JViewport)c; Point cp = SwingUtilities.convertPoint(jc,e.getPoint(),vport); Component c = e.getComponent(); Container p = SwingUtilities.getUnwrappedParent(c); if (p instanceof JViewport) { JViewport vport = (JViewport) p; Point cp = SwingUtilities.convertPoint(c, e.getPoint(), vport); Point vp = vport.getViewPosition(); vp.translate(pp.x-cp.x, pp.y-cp.y); jc.scrollRectToVisible(new Rectangle(vp, vport.getSize())); vp.translate(pp.x - cp.x, pp.y - cp.y); ((JComponent) c).scrollRectToVisible(new Rectangle(vp, vport.getSize())); pp.setLocation(cp); } } @Override public void mousePressed(MouseEvent e) { JComponent jc = (JComponent)e.getSource(); Container c = jc.getParent(); if(c instanceof JViewport) { jc.setCursor(hndCursor); JViewport vport = (JViewport)c; Point cp = SwingUtilities.convertPoint(jc,e.getPoint(),vport); Component c = e.getComponent(); Container p = SwingUtilities.getUnwrappedParent(c); if (p instanceof JViewport) { c.setCursor(hndCursor); JViewport vport = (JViewport) p; Point cp = SwingUtilities.convertPoint(c, e.getPoint(), vport); pp.setLocation(cp); } } @Override public void mouseReleased(MouseEvent e) { ((JComponent)e.getSource()).setCursor(defCursor); e.getComponent().setCursor(defCursor); } } }} **解説 [#qf2b1d96] 上記のサンプルでは、``JTree``に``MouseListener``, ``MouseMotionListener``を設定し、マウスドラッグを``JViewport``の座標に変換して、``scrollRectToVisible(...)``メソッドを使ったスクロールをおこなっています。 * 解説 [#explanation] 上記のサンプルでは、`JTree`に`MouseListener`と`MouseMotionListener`を設定し、マウスドラッグを`JViewport`の座標に変換して`scrollRectToVisible(...)`メソッドを使ったスクロールをおこなっています。 #code{{ MouseAdapter ma = new DragScrollListener(); tree2.addMouseMotionListener(ma); tree2.addMouseListener(ma); }} [[JScrollPaneのViewportをマウスで掴んでスクロール>Swing/HandScroll]]と、ぼぼ同じことをしていますが、``JLabel``とは異なり、``JTree``にはデフォルトで``MouseListener``, ``MouseMotionListener``が設定されているため、``JViewport``にリスナーを設定しても``JTree``までマウスイベントが伝わりません。例えば、以下のように``JComponent#dispatchEvent(...)``で、``JTree``の親の``JViewport``にイベントを投げる必要があります。 ---- - [[JScrollPaneのViewportをマウスで掴んでスクロール>Swing/HandScroll]]とほぼ同一 - ただし、`JLabel`とは異なり`JTree`にはデフォルトで`MouseListener`と`MouseMotionListener`が設定されているため、`JViewport`にリスナーを設定しても`JTree`までマウスイベントが伝達しない - 例えば以下のように`JComponent#dispatchEvent(...)`で`JTree`の親の`JViewport`にイベントを転送する必要がある #code{{ MouseAdapter ma = new HandScrollListener(); JScrollPane scroll = new JScrollPane(tree1); JViewport vport = scroll.getViewport(); vport.addMouseMotionListener(ma); vport.addMouseListener(ma); MouseAdapter dummy = new MouseAdapter() { MouseAdapter transparent = new MouseAdapter() { private void dispatchEvent(MouseEvent e) { JComponent c = (JComponent)e.getComponent(); JComponent p = (JComponent)e.getComponent().getParent(); p.dispatchEvent(SwingUtilities.convertMouseEvent(c,e,p)); JComponent c = (JComponent) e.getComponent(); JComponent p = (JComponent) e.getComponent().getParent(); p.dispatchEvent(SwingUtilities.convertMouseEvent(c, e, p)); } @Override public void mouseDragged(MouseEvent e) { dispatchEvent(e); } @Override public void mouseClicked(MouseEvent e) { dispatchEvent(e); } @Override public void mouseEntered(MouseEvent e) { dispatchEvent(e); } @Override public void mouseExited(MouseEvent e) { dispatchEvent(e); } @Override public void mousePressed(MouseEvent e) { dispatchEvent(e); } @Override public void mouseReleased(MouseEvent e) { dispatchEvent(e); } @Override public void mouseDragged(MouseEvent e) { dispatchEvent(e); } @Override public void mouseClicked(MouseEvent e) { dispatchEvent(e); } @Override public void mouseEntered(MouseEvent e) { dispatchEvent(e); } @Override public void mouseExited(MouseEvent e) { dispatchEvent(e); } @Override public void mousePressed(MouseEvent e) { dispatchEvent(e); } @Override public void mouseReleased(MouseEvent e) { dispatchEvent(e); } }; tree1.addMouseMotionListener(transparent); tree1.addMouseListener(transparent); }} **参考リンク [#p851da48] * 参考リンク [#reference] - [[JScrollPaneのViewportをマウスで掴んでスクロール>Swing/HandScroll]] - [[JScrollPane内にある複数Componentを配置したJPanelをJLayerを使ってドラッグスクロール>Swing/DragScrollLayer]] -- `JDK 1.7.0`以上の場合、`JComponent#dispatchEvent(...)`を伝搬させるリスナーを追加なくても`JLayer`を使用すればすべての子コンポーネントで`MouseEvent`が取得できる **コメント [#y1967494] * コメント [#comment] #comment #comment