• 追加された行はこの色です。
  • 削除された行はこの色です。
TITLE:JScrollPaneのオートスクロール
#navi(../)
#tags(JScrollPane, JViewport, JScrollPane, DragAndDrop, Timer, MouseListener, MouseMotionListener)
RIGHT:Posted by &author(aterai); at 2004-11-22
* JScrollPaneのオートスクロール [#h85af000]
---
category: swing
folder: AutoScroll
title: JScrollPaneのオートスクロール
tags: [JScrollPane, JViewport, JScrollPane, DragAndDrop, Timer, MouseListener, MouseMotionListener]
author: aterai
pubdate: 2004-11-22T00:57:31+09:00
description: JScrollPane上でのマウスドラッグに応じてラベルをオートスクロールします。
image: https://lh4.googleusercontent.com/_9Z4BYR88imo/TQTH2GCzRoI/AAAAAAAAAR0/FR7seILhmaM/s800/AutoScroll.png
hreflang:
    href: https://java-swing-tips.blogspot.com/2008/06/mouse-drag-auto-scrolling.html
    lang: en
---
* 概要 [#summary]
`JScrollPane`上でのマウスドラッグに応じてラベルをオートスクロールします。

#download
#ref(https://lh4.googleusercontent.com/_9Z4BYR88imo/TQTH2GCzRoI/AAAAAAAAAR0/FR7seILhmaM/s800/AutoScroll.png)
#download(https://lh4.googleusercontent.com/_9Z4BYR88imo/TQTH2GCzRoI/AAAAAAAAAR0/FR7seILhmaM/s800/AutoScroll.png)

** サンプルコード [#nf7c2bf6]
* サンプルコード [#sourcecode]
#code(link){{
class ViewportDragScrollListener extends MouseAdapter
                                 implements HierarchyListener {
  private static final int SPEED = 4;
  private static final int DELAY = 10;
  private final Cursor dc;
  private final Cursor hc = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
  private final javax.swing.Timer scroller;
  private final Timer scroller;
  private final JComponent label;
  private Point startPt = new Point();
  private Point move    = new Point();

  public ViewportDragScrollListener(JComponent comp) {
    this.label = comp;
    this.dc = comp.getCursor();
    this.scroller = new javax.swing.Timer(DELAY, new ActionListener() {
    this.scroller = new Timer(DELAY, new ActionListener() {
      @Override public void actionPerformed(ActionEvent e) {
        JViewport vport = (JViewport)label.getParent();
        Point vp = vport.getViewPosition();
        vp.translate(move.x, move.y);
        label.scrollRectToVisible(new Rectangle(vp, vport.getSize()));
        Container c = SwingUtilities.getAncestorOfClass(
            JViewport.class, label);
        if (c instanceof JViewport.class) {
          JViewport vport = (JViewport) c;
          Point vp = vport.getViewPosition();
          vp.translate(move.x, move.y);
          label.scrollRectToVisible(
              new Rectangle(vp, vport.getSize()));
        }
      }
    });
  }

  @Override public void hierarchyChanged(HierarchyEvent e) {
    JComponent c = (JComponent)e.getSource();
    if((e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED)!=0
       && !c.isDisplayable()) {
    JComponent c = (JComponent) e.getSource();
    if ((e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0
        && !c.isDisplayable()) {
      scroller.stop();
    }
  }

  @Override public void mouseDragged(MouseEvent e) {
    JViewport vport = (JViewport)e.getSource();
    JViewport vport = (JViewport) e.getSource();
    Point pt = e.getPoint();
    int dx = startPt.x - pt.x;
    int dy = startPt.y - pt.y;
    Point vp = vport.getViewPosition();
    vp.translate(dx, dy);
    label.scrollRectToVisible(new Rectangle(vp, vport.getSize()));
    move.setLocation(SPEED*dx, SPEED*dy);
    move.setLocation(SPEED * dx, SPEED * dy);
    startPt.setLocation(pt);
  }

  @Override public void mousePressed(MouseEvent e) {
    ((JComponent)e.getSource()).setCursor(hc); //label.setCursor(hc);
    e.getComponent().setCursor(hc); // label.setCursor(hc);
    startPt.setLocation(e.getPoint());
    move.setLocation(0, 0);
    scroller.stop();
  }

  @Override public void mouseReleased(MouseEvent e) {
    ((JComponent)e.getSource()).setCursor(dc); //label.setCursor(dc);
    e.getComponent().setCursor(dc); // label.setCursor(dc);
    scroller.start();
  }

  @Override public void mouseExited(MouseEvent e) {
    ((JComponent)e.getSource()).setCursor(dc); //label.setCursor(dc);
    e.getComponent().setCursor(dc); // label.setCursor(dc);
    move.setLocation(0, 0);
    scroller.stop();
  }
}
}}

** 解説 [#i40d83e6]
上記のサンプルでは、`JViewport`内の画像ラベルをマウスでドラッグすると、その移動方向に応じて自動的にスクロールします。マウスをクリックすると停止します。
* 解説 [#explanation]
上記のサンプルでは、`JViewport`内の画像ラベルをマウスでドラッグするとその移動方向に応じて自動的にスクロールします。

`javax.swing.Timer`を使うことでスクロールの開始、継続、停止を行っています。
- `javax.swing.Timer`を使うことでスクロールの開始、継続、停止を実行
- 自動スクロール中に画像をマウスでクリックすると移動を停止

----
`JTextPane`で文字列を挿入したときに、最後まで自動スクロールしたい場合は、[[JTextPaneで最終行に移動>Swing/CaretPosition]]を参考にしてください。

** 参考リンク [#j6c969ff]
* 参考リンク [#reference]
- [[JScrollPaneのViewportをマウスで掴んでスクロール>Swing/HandScroll]]
- [[JTextPaneで最終行に移動>Swing/CaretPosition]]
-- `JTextPane`で文字列を挿入したときに最後まで自動スクロールするサンプル
- [http://sozai-free.com/ 2000ピクセル以上のフリー写真素材集]

** コメント [#paa26bcc]
- 猫の手スクロール風の動作に変更しました。 -- [[aterai]] &new{2007-05-24 (木) 19:16:16};
- ドラッグ中は、[[JScrollPaneのViewportをマウスで掴んでスクロール>Swing/HandScroll]]と同じ動作をするように変更しました。 -- [[aterai]] &new{2011-12-22 (木) 18:38:02};
* コメント [#comment]
#comment
- 猫の手スクロール風の動作に変更しました。 -- &user(aterai); &new{2007-05-24 (木) 19:16:16};
- ドラッグ中は、[[JScrollPaneのViewportをマウスで掴んでスクロール>Swing/HandScroll]]と同じ動作にるよう変更しました。 -- &user(aterai); &new{2011-12-22 (木) 18:38:02};

#comment