• 追加された行はこの色です。
  • 削除された行はこの色です。
TITLE:JTextAreaから一行ずつ文字列を取得
#navi(../)
*JTextAreaから一行ずつ文字列を取得して [#sce4576b]
>編集者:[[Terai Atsuhiro>terai]]~
作成日:2006-10-09~
更新日:&lastmod;
---
category: swing
folder: GetLineText
title: JTextAreaから一行ずつ文字列を取得
tags: [JTextArea, StringTokenizer, LineNumberReader]
author: aterai
pubdate: 2006-10-09T22:13:19+09:00
description: JTextAreaなどのテキストコンポーネントから一行ずつ文字列を取り出してそれを処理します。
image: https://lh3.googleusercontent.com/_9Z4BYR88imo/TQTNWn74dWI/AAAAAAAAAao/pNdeF8CSOfM/s800/GetLineText.png
---
* 概要 [#summary]
`JTextArea`などのテキストコンポーネントから一行ずつ文字列を取り出してそれを処理します。

#contents
#download(https://lh3.googleusercontent.com/_9Z4BYR88imo/TQTNWn74dWI/AAAAAAAAAao/pNdeF8CSOfM/s800/GetLineText.png)

**概要 [#i4a502e8]
JTextAreaなどのテキストコンポーネントから一行ずつ文字列を取り出してそれを処理します。
* サンプルコード [#sourcecode]
#code(link){{
int count = 0;
StringTokenizer st = new StringTokenizer(textArea.getText(), "\n");
while (st.hasMoreTokens()) {
  if (st.nextToken().codePointAt(0) == '#') {
    count++;
  }
}
}}

#screenshot
* 解説 [#explanation]
上記のサンプルでは、`JTextArea#getText()`ですべてのテキストを取得してから`StringTokenizer`を使って行毎に分解しています。`returnDelims`フラグが`false`なのでトークンが空行になることはありません。

**サンプルコード [#cba0b2ee]
----
- `String#split(...)`を使用する場合
-- 空行あり

#code{{
EventQueue.invokeLater(new Runnable() {
  public void run() {
    int count = 0;
    StringTokenizer st = new StringTokenizer(textArea.getText(), "\n") ;
    while(st.hasMoreTokens()) {
      if(st.nextToken().startsWith("#")) {
      count = count + 1;
for (String line: textArea.getText().split("\\n")) {
  if (!line.isEmpty() && line.codePointAt(0) == '#') {
    count++;
  }
}
}}

- `LineNumberReader`を使用する場合
-- 空行あり

#code{{
try (LineNumberReader lnr = new LineNumberReader(new StringReader(txa.getText()))) {
  String line = null;
  while ((line = lnr.readLine()) != null) {
    if (!line.isEmpty() && line.codePointAt(0) == '#') {
      count++;
    }
  }
//Document doc = textArea.getDocument();
//Element root = doc.getDefaultRootElement();
//try{
//  for(int i=0;i<root.getElementCount();i++) {
//    Element elem = root.getElement(i);
//    String line = doc.getText(elem.getStartOffset(),
//                              elem.getEndOffset()-elem.getStartOffset());
//    if(line.startsWith("#")) {
//      count = count + 1;
//    }
//  }
//}catch(BadLocationException ble) {
//  ble.printStackTrace();
//  count = -1;
//}
......
} catch (IOException ioe) {
  ioe.printStackTrace();
}
}}
-&jnlp;
-&jar;
-&zip;

**解説 [#v1446cab]
上記のサンプルでは、JTextArea#getText() ですべてのテキストを取得し、StringTokenizer を使って行毎に分解しています。
- `Element#getElementCount()`を使用する場合
-- 空行なし(`Element`には少なくとも長さ`1`の改行が存在する)

コメントアウトしたコードのようにドキュメントが行を取り出した方が若干速い気((まだ実験したわけではない))がするのですが、行数が少ない場合は簡単なStringTokenizerを使用する方法で問題ないと思います。
#code{{
Document doc = textArea.getDocument();
Element root = doc.getDefaultRootElement();
try {
  for (int i = 0; i < root.getElementCount(); i++) {
    Element elm = root.getElement(i);
    String line = doc.getText(
        elm.getStartOffset(), elm.getEndOffset() - elm.getStartOffset());
    if (line.codePointAt(0) == '#') {
      count++;
    }
  }
} catch (BadLocationException ble) {
  ble.printStackTrace();
}
}}

//**参考リンク
**コメント [#ee4fa454]
* 参考リンク [#reference]
- [https://docs.oracle.com/javase/jp/8/docs/api/java/util/StringTokenizer.html StringTokenizer (Java Platform SE 8)]
- [https://docs.oracle.com/javase/jp/8/docs/api/java/io/LineNumberReader.html LineNumberReader (Java Platform SE 8)]
- [https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/text/Element.html#getElementCount-- Element#getElementCount() (Java Platform SE 8)]

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