Swing/HandDragScrollableTable のバックアップ(No.3)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/HandDragScrollableTable へ行く。
- 1 (2017-12-25 (月) 14:39:50)
- 2 (2018-02-15 (木) 14:23:42)
- 3 (2019-07-15 (月) 19:46:18)
- 4 (2019-10-15 (火) 17:35:31)
- 5 (2021-05-25 (火) 08:26:46)
- 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
概要
JTable
をスクロールバーではなく、内部の行をマウスでドラッグすることでスクロール可能になるよう設定します。
Screenshot
Advertisement
サンプルコード
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.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
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();
}
}
View in GitHub: Java, Kotlin解説
- JTreeの余白をドラッグしてスクロールの
MouseMotionListener
にJScrollPaneでキネティックスクロールのTimer
を使った慣性処理を適用して、行のドラッグスクロールを実行 JScrollBar
を常に非表示にしているので、マウスホイールによるスクロールは不可- 行選択と干渉する場合があるので、ドラッグ中は
JTable#setEnabled(false)
で行選択などを無効化- 複数行の選択が不可になる