• 追加された行はこの色です。
  • 削除された行はこの色です。
TITLE:JScrollPaneのスクロールを同期
#navi(../)
*JScrollPaneのスクロールを同期 [#cd2aa3e5]
>編集者:[[Terai Atsuhiro>terai]]~
作成日:2004-04-05~
更新日:&lastmod;
---
category: swing
folder: SynchronizedScroll
title: JScrollPaneのスクロールを同期
tags: [JScrollPane, ChangeListener, JScrollBar, BoundedRangeModel]
author: aterai
pubdate: 2004-04-05T03:13:08+09:00
description: 2つのJScrollPaneのスクロールを同期します。
image: https://lh6.googleusercontent.com/_9Z4BYR88imo/TQTT_c3UmrI/AAAAAAAAAlU/adQEhxZ2FXc/s800/SynchronizedScroll.png
---
* 概要 [#summary]
`2`つの`JScrollPane`のスクロールを同期します。

#contents
#download(https://lh6.googleusercontent.com/_9Z4BYR88imo/TQTT_c3UmrI/AAAAAAAAAlU/adQEhxZ2FXc/s800/SynchronizedScroll.png)

**概要 [#efeb1bee]
2つのJScrollPaneのスクロールを同期します。
* サンプルコード [#sourcecode]
#code(link){{
ChangeListener cl = new ChangeListener() {
  private boolean adjflg;
  @Override public void stateChanged(ChangeEvent e) {
    JViewport src = null;
    JViewport tgt = null;
    if (e.getSource() == sp1.getViewport()) {
      src = sp1.getViewport();
      tgt = sp2.getViewport();
    } else if (e.getSource() == sp2.getViewport()) {
      src = sp2.getViewport();
      tgt = sp1.getViewport();
    }
    if (adjflg || tgt == null || src == null) {
      return;
    }
    adjflg = true;
    Dimension dim1 = src.getViewSize();
    Dimension siz1 = src.getSize();
    Point pnt1 = src.getViewPosition();
    Dimension dim2 = tgt.getViewSize();
    Dimension siz2 = tgt.getSize();
    // Point pnt2 = tgt.getViewPosition();
    double d;
    d = pnt1.getY() / (dim1.getHeight() - siz1.getHeight())
                    * (dim2.getHeight() - siz2.getHeight());
    pnt1.y = (int) d;
    d = pnt1.getX() / (dim1.getWidth() - siz1.getWidth())
                    * (dim2.getWidth() - siz2.getWidth());
    pnt1.x = (int) d;
    tgt.setViewPosition(pnt1);
    adjflg = false;
  }
};
sp1.getViewport().addChangeListener(cl);
sp2.getViewport().addChangeListener(cl);
}}

#screenshot
* 解説 [#explanation]
上記のサンプルでは、一方のスクロールバーを移動させると、他方も同程度の割合で移動するように設定した`ChangeListener`を使用しています。

**サンプルコード [#r45eb782]
 ChangeListener cl = new ChangeListener() {
   boolean adjflg = false;
   public void stateChanged(ChangeEvent e) {
     JViewport src = null;
     JViewport tgt = null;
     if(e.getSource()==sp1.getViewport()) {
       src = sp1.getViewport();
       tgt = sp2.getViewport();
     }else if(e.getSource()==sp2.getViewport()) {
       src = sp2.getViewport();
       tgt = sp1.getViewport();
     }
     if(adjflg || tgt==null || src==null) return;
     adjflg = true;
     Dimension dm1 = src.getViewSize();
     Dimension sz1 = src.getSize();
     Point     pt1 = src.getViewPosition();
     Dimension dm2 = tgt.getViewSize();
     Dimension sz2 = tgt.getSize();
     Point     pt2 = tgt.getViewPosition();
     double d;
     d = pt1.getY()/(dm1.getHeight()-sz1.getHeight())
                   *(dm2.getHeight()-sz2.getHeight());
     pt1.y = (int)d;
     d = pt1.getX()/(dm1.getWidth()-sz1.getWidth())
                   *(dm2.getWidth()-sz2.getWidth());
     pt1.x = (int)d;
     tgt.setViewPosition(pt1);
     adjflg = false;
   }
 };
----
- `JScrollPane`内部のコンポーネントのサイズが等しい場合はそれぞれの垂直・水平`JScrollBar`で使用する`BoundedRangeModel`を共有するだけでスクロールの同期が可能
#code{{
sp2.getVerticalScrollBar().setModel(sp1.getVerticalScrollBar().getModel());
sp2.getHorizontalScrollBar().setModel(sp1.getHorizontalScrollBar().getModel());
}}

-&jnlp;
-&jar;
-&zip;
* 参考リンク [#reference]
- [https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/event/ChangeListener.html ChangeListener (Java Platform SE 8)]
- [https://community.oracle.com/thread/1502596 Swing (Archive) - link to scrollbar]
- [https://community.oracle.com/thread/1484489 Swing (Archive) - Synchronizing scrollbars two scroll bars]

**解説 [#f398793c]
上記のサンプルでは、一方のスクロールバーを移動させると、他方も同程度移動するように設定したChangeListenerを使用しています。

内部コンポーネントのサイズが等しい場合は、参考リンクにあるように、ChangeListenerを共有するだけで、スクロールを同期することができます。

**参考リンク [#sf754937]
-[[link to scrollbar>http://forum.java.sun.com/thread.jspa?forumID=57&threadID=328988]]
-[[Synchronizing scrollbars two scroll bars>http://forum.java.sun.com/thread.jspa?forumID=57&threadID=346262]]

**コメント [#o41322f4]
* コメント [#comment]
#comment
#comment