概要

2つのJScrollPaneのスクロールを同期します。

サンプルコード

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);
View in GitHub: Java, Kotlin

解説

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


  • JScrollPane内部のコンポーネントのサイズが等しい場合はそれぞれの垂直・水平JScrollBarで使用するBoundedRangeModelを共有するだけでスクロールの同期が可能
    sp2.getVerticalScrollBar().setModel(sp1.getVerticalScrollBar().getModel());
    sp2.getHorizontalScrollBar().setModel(sp1.getHorizontalScrollBar().getModel());
    

参考リンク

コメント