• 追加された行はこの色です。
  • 削除された行はこの色です。
TITLE:JTextAreaの任意の行まで移動
#navi(../)
*JTextAreaの任意の行に移動 [#f76f67cc]
>編集者:[[Terai Atsuhiro>terai]]~
作成日:2006-10-02~
更新日:&lastmod;
---
category: swing
folder: GotoLine
title: JTextAreaの任意の行まで移動
tags: [JTextArea, JScrollPane, Caret]
author: aterai
pubdate: 2006-10-02T01:43:48+09:00
description: 指定した行番号がJTextAreaの中で先頭にくるようにジャンプします。
image: https://lh4.googleusercontent.com/_9Z4BYR88imo/TQTNdpDdyKI/AAAAAAAAAa0/cOjr09yncHI/s800/GotoLine.png
---
* 概要 [#summary]
指定した行番号が`JTextArea`の中で先頭にくるようにジャンプします。

#contents
#download(https://lh4.googleusercontent.com/_9Z4BYR88imo/TQTNdpDdyKI/AAAAAAAAAa0/cOjr09yncHI/s800/GotoLine.png)

**概要 [#def596ab]
指定した行番号がJTextAreaの中で先頭にくるようにジャンプします。

#screenshot

**サンプルコード [#he8c09bc]
#code{{
 JButton button = new JButton(new AbstractAction("Goto Line") {
   public void actionPerformed(ActionEvent e) {
     Document doc = textArea.getDocument();
     Element root = doc.getDefaultRootElement();
     int i = 1;
     try{
       i = Integer.parseInt(textField.getText().trim());
       i = Math.max(1, Math.min(root.getElementCount(), i));
     }catch(NumberFormatException nfe) {
       java.awt.Toolkit.getDefaultToolkit().beep();
       return;
     }
     try{
       Element elem = root.getElement(i-1);
       Rectangle rect = textArea.modelToView(elem.getStartOffset());
       Rectangle vr = scroll.getViewport().getViewRect();
       rect.setSize(10, vr.height);
       textArea.scrollRectToVisible(rect);
       textArea.setCaretPosition(elem.getStartOffset());
       //textArea.requestFocus();
     }catch(BadLocationException ble) {
       java.awt.Toolkit.getDefaultToolkit().beep();
     }
   }
 });
 frame.getRootPane().setDefaultButton(button);
* サンプルコード [#sourcecode]
#code(link){{
JButton button = new JButton(new AbstractAction("Goto Line") {
  @Override public void actionPerformed(ActionEvent e) {
    Document doc = textArea.getDocument();
    Element root = doc.getDefaultRootElement();
    int i = Integer.parseInt(textField.getText().trim());
    i = Math.max(1, Math.min(root.getElementCount(), i));
    try {
      Element elem = root.getElement(i - 1);
      Rectangle rect = textArea.modelToView(elem.getStartOffset());
      Rectangle vr = scroll.getViewport().getViewRect();
      rect.setSize(10, vr.height);
      textArea.scrollRectToVisible(rect);
      textArea.setCaretPosition(elem.getStartOffset());
    } catch (BadLocationException ex) {
      Toolkit.getDefaultToolkit().beep();
    }
  }
});
EventQueue.invokeLater(() -> getRootPane().setDefaultButton(button));
}}
-&jnlp;
-&jar;
-&zip;

**解説 [#qa71cf1b]
上記のサンプルでは、任意の行番号を指定してリターン、またはボタンをクリックすると、1から最大行数までの範囲で、その行が先頭にくるように表示位置が変更されます。
* 解説 [#explanation]
上記のサンプルでは、`JTextField`に任意の行番号を指定してKBD{Enter}キー、またはボタンをクリックするとその行が`JViewport`の表示範囲の最上部に配置されるよう表示領域を更新します。

JTextArea#setCaretPosition(int)メソッドによるキャレットの位置変更だけでは、移動先を移動元より大きな行番号にした場合、JTextAreaの下までしかスクロールしないので、JTextArea#modelToView(int)メソッドで取得した座標が出来るだけ上部にくるように処理しています。
- `JTextArea#setCaretPosition(int)`メソッドによる`Caret`の位置変更だけでは移動先を移動元より大きな行番号にしたとき`JTextArea`の下部までしかスクロールしない
- そのため`Caret`の位置変更のまえに`JTextArea#modelToView(int)`メソッドで取得した座標が可能なかぎり上部にくるように`JTextArea#scrollRectToVisible(...)`メソッドで表示位置を変更

//**参考リンク
**コメント [#f180c8f9]
* 参考リンク [#reference]
- [[JTextAreaでSmoothScrollによる行移動>Swing/SmoothScroll]]

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