• 追加された行はこの色です。
  • 削除された行はこの色です。
TITLE:JTextAreaでSmoothScrollによる行移動
#navi(../)
RIGHT:Posted by [[aterai]] at 2007-08-13
*JTextAreaでSmoothScrollによる行移動 [#qdf0c9e9]
SmoothScrollアニメーション有りで任意の行まで移動します。
---
category: swing
folder: SmoothScroll
title: JTextAreaでSmoothScrollによる行移動
tags: [JScrollPane, JViewport, Animation, JTextArea]
author: aterai
pubdate: 2007-08-13T13:01:23+09:00
description: SmoothScrollアニメーション有りでJTextAreaの任意の行まで移動します。
image: https://lh3.googleusercontent.com/_9Z4BYR88imo/TQTTSaxFSzI/AAAAAAAAAkI/KtedLqwCXBY/s800/SmoothScroll.png
---
* 概要 [#summary]
`SmoothScroll`アニメーション有りで`JTextArea`の任意の行まで移動します。

-&jnlp;
-&jar;
-&zip;
#download(https://lh3.googleusercontent.com/_9Z4BYR88imo/TQTTSaxFSzI/AAAAAAAAAkI/KtedLqwCXBY/s800/SmoothScroll.png)

//#screenshot
#ref(http://lh3.ggpht.com/_9Z4BYR88imo/TQTTSaxFSzI/AAAAAAAAAkI/KtedLqwCXBY/s800/SmoothScroll.png)

**サンプルコード [#u2a76de6]
#code{{
* サンプルコード [#sourcecode]
#code(link){{
Document doc = textArea.getDocument();
Element root = doc.getDefaultRootElement();
int ln = getDestLineNumber(textField, root);
if(ln<0) { Toolkit.getDefaultToolkit().beep(); return; }
try{
  final Element elem = root.getElement(ln-1);
  final Rectangle dest = textArea.modelToView(elem.getStartOffset());
  final Rectangle current = scroll.getViewport().getViewRect();
  new Timer(20, new ActionListener() {
    public void actionPerformed(ActionEvent ae) {
      Timer animator = (Timer)ae.getSource();
      if(dest.y < current.y && animator.isRunning()) {
        int d = Math.max(1, (current.y-dest.y)/2);
        current.y = current.y - d;
        textArea.scrollRectToVisible(current);
      }else if(dest.y > current.y && animator.isRunning()) {
        int d = Math.max(1, (dest.y-current.y)/2);
        current.y = current.y + d;
        textArea.scrollRectToVisible(current);
      }else{
        textArea.setCaretPosition(elem.getStartOffset());
        animator.stop();
      }
int ln = model.getNumber().intValue();
try {
  Element elem = root.getElement(ln - 1);
  Rectangle dest = textArea.modelToView(elem.getStartOffset());
  Rectangle current = scroll.getViewport().getViewRect();
  new Timer(20, e -> {
    Timer animator = (Timer) e.getSource();
    if (dest.y < current.y && animator.isRunning()) {
      int d = Math.max(1, (current.y - dest.y) / 2);
      current.y = current.y - d;
      textArea.scrollRectToVisible(current);
    } else if (dest.y > current.y && animator.isRunning()) {
      int d = Math.max(1, (dest.y - current.y) / 2);
      current.y = current.y + d;
      textArea.scrollRectToVisible(current);
    } else {
      textArea.setCaretPosition(elem.getStartOffset());
      animator.stop();
    }
  }).start();
}catch(BadLocationException ble) {
  Toolkit.getDefaultToolkit().beep();
} catch (BadLocationException ex) {
  UIManager.getLookAndFeel().provideErrorFeedback(textArea);
}
}}

**解説 [#kad57b23]
java.swing.Timerでイベントを発生させ、目的位置と現在位置の差の半分だけViewRectのスクロールを繰り返すことで、アニメーションを行っています。
* 解説 [#explanation]
上記のサンプルでは、`java.swing.Timer`でイベントが発生すると`scrollRectToVisible(...)`メソッドを使用して目的位置と現在位置の差の半分だけ`ViewRect`のスクロールを繰り返すことで行移動アニメーションを行っています。

**参考リンク [#ua27efde]
-[[JTextAreaの任意の行に移動>Swing/GotoLine]]
* 参考リンク [#reference]
- [[JTextAreaの任意の行に移動>Swing/GotoLine]]

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