Swing/HandDragScrollableTable の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/HandDragScrollableTable へ行く。
- Swing/HandDragScrollableTable の差分を削除
--- category: swing folder: HandDragScrollableTable title: JTableをスクロールバー無しのドラッグでスクロールする tags: [JTable, JScrollPane, MouseMotionListener, Timer] author: aterai pubdate: 2017-12-25T14:36:51+09:00 description: JTableをスクロールバーではなく、内部の行をマウスでドラッグすることでスクロール可能になるよう設定します。 image: https://drive.google.com/uc?id=10Tv7RlmeMiqhXBuq5fgixQ3v4KR8p5_9 --- * 概要 [#summary] `JTable`をスクロールバーではなく、内部の行をマウスでドラッグすることでスクロール可能になるよう設定します。 #download(https://drive.google.com/uc?id=10Tv7RlmeMiqhXBuq5fgixQ3v4KR8p5_9) * サンプルコード [#sourcecode] #code(link){{ class DragScrollingListener extends MouseAdapter { protected static final int VELOCITY = 5; protected static final int DELAY = 10; protected static final double GRAVITY = .95; protected final Cursor dc = Cursor.getDefaultCursor(); protected final Cursor hc = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR); protected final Timer scroller; protected final Point startPt = new Point(); protected final Point delta = new Point(); protected DragScrollingListener(JComponent c) { super(); this.scroller = new Timer(DELAY, e -> { JViewport vport = (JViewport) SwingUtilities.getUnwrappedParent(c); Point vp = vport.getViewPosition(); vp.translate(-delta.x, -delta.y); c.scrollRectToVisible(new Rectangle(vp, vport.getSize())); if (Math.abs(delta.x) > 0 || Math.abs(delta.y) > 0) { delta.setLocation((int) (delta.x * GRAVITY), (int) (delta.y * GRAVITY)); } else { ((Timer) e.getSource()).stop(); } }); } @Override public void mousePressed(MouseEvent e) { Component c = e.getComponent(); c.setCursor(hc); c.setEnabled(false); Container p = SwingUtilities.getUnwrappedParent(c); if (p instanceof JViewport) { JViewport vport = (JViewport) p; Point cp = SwingUtilities.convertPoint(c, e.getPoint(), vport); startPt.setLocation(cp); scroller.stop(); } } @Override public void mouseDragged(MouseEvent e) { 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(startPt.x - cp.x, startPt.y - cp.y); delta.setLocation(VELOCITY * (cp.x - startPt.x), VELOCITY * (cp.y - startPt.y)); ((JComponent) c).scrollRectToVisible(new Rectangle(vp, vport.getSize())); startPt.setLocation(cp); } } @Override public void mouseReleased(MouseEvent e) { Component c = e.getComponent(); c.setCursor(dc); c.setEnabled(true); scroller.start(); } } }} * 解説 [#explanation] - [[JTreeの余白をドラッグしてスクロール>Swing/TreeDragScroll]]の`MouseMotionListener`に[[JScrollPaneでキネティックスクロール>Swing/KineticScrolling]]の`Timer`を使った慣性処理を適用して、行のドラッグスクロールを実行 - `JScrollBar`を常に非表示にしているので、マウスホイールによるスクロールは不可 - `JScrollBar`を常に非表示にしているのでマウスホイールによるスクロールは不可 -- [[JScrollBarが非表示でもMouseWheelでScrollする>Swing/MouseWheelScroll]]で回避可能 - 行選択と干渉する場合があるので、ドラッグ中は`JTable#setEnabled(false)`で行選択などを無効化 - 行選択と干渉する場合があるのでドラッグ中は`JTable#setEnabled(false)`で行選択などを無効化 -- 複数行の選択が不可になる * 参考リンク [#reference] - [[JTreeの余白をドラッグしてスクロール>Swing/TreeDragScroll]] - [[JScrollPaneでキネティックスクロール>Swing/KineticScrolling]] - [[JScrollBarが非表示でもMouseWheelでScrollする>Swing/MouseWheelScroll]] - [[JTableのドラッグスクロールをタッチスクリーンで実行する>Swing/TableScrollOnTouchScreen]] * コメント [#comment] #comment #comment