• 追加された行はこの色です。
  • 削除された行はこの色です。
TITLE:JTextAreaに表示できる行数を制限
#navi(../)
#tags()
RIGHT:Posted by &author(aterai); at 2006-02-27
*JTextAreaに表示できる行数を制限 [#e59bb955]
ドキュメントのサイズを一定にして、JTextAreaなど表示できる行数を制限します。[http://forums.sun.com/thread.jspa?threadID=409418 Swing (Archive) - JTextArea Memory Overflow ??]にあるソースコードを参考にしています。
---
category: swing
folder: FIFODocument
title: JTextAreaに表示できる行数を制限
tags: [JTextArea, DocumentListener]
author: aterai
pubdate: 2006-02-27T11:11:21+09:00
description: ドキュメントのサイズを一定にして、JTextAreaなど表示できる行数を制限します。
image: https://lh5.googleusercontent.com/_9Z4BYR88imo/TQTMafjL8xI/AAAAAAAAAZI/-KMSGPcn0jM/s800/FIFODocument.png
---
* 概要 [#summary]
ドキュメントのサイズを一定にして、`JTextArea`など表示できる行数を制限します。[https://community.oracle.com/thread/1479784 Swing (Archive) - JTextArea Memory Overflow ??]にあるソースコードを参考にしています。

-&jnlp;
-&jar;
-&zip;
#download(https://lh5.googleusercontent.com/_9Z4BYR88imo/TQTMafjL8xI/AAAAAAAAAZI/-KMSGPcn0jM/s800/FIFODocument.png)

//#screenshot
#ref(http://lh5.ggpht.com/_9Z4BYR88imo/TQTMafjL8xI/AAAAAAAAAZI/-KMSGPcn0jM/s800/FIFODocument.png)

**サンプルコード [#x24ef034]
* サンプルコード [#sourcecode]
#code(link){{
jta.setEditable(false);
jta.getDocument().addDocumentListener(new DocumentListener() {
  @Override public void insertUpdate(DocumentEvent e) {
    final Document doc = jta.getDocument();
    final Element root = doc.getDefaultRootElement();
    if(root.getElementCount()<=maxLines) return;
    if (root.getElementCount() <= maxLines) return;
    EventQueue.invokeLater(new Runnable() {
      @Override public void run() {
        removeLines(doc, root);
      }
    });
    jta.setCaretPosition(doc.getLength());
  }

  private void removeLines(Document doc, Element root) {
    Element fl = root.getElement(0);
    try{
    try {
      doc.remove(0, fl.getEndOffset());
    }catch(BadLocationException ble) {
    } catch (BadLocationException ble) {
      System.out.println(ble);
    }
  }

  @Override public void removeUpdate(DocumentEvent e) {}

  @Override public void changedUpdate(DocumentEvent e) {}
});
final Timer timer = new Timer(100, new ActionListener() {
  @Override public void actionPerformed(ActionEvent e) {
    String s = new Date().toString();
    jta.append((jta.getDocument().getLength()>0)?"\n"+s:s);
  }
Timer timer = new Timer(100, () -> {
  String s = new Date().toString();
  jta.append((jta.getDocument().getLength() > 0) ? "\n" + s : s);
});
}}

**解説 [#v8d4dbca]
一行追加された時に、規定の行数を越えている場合は、先頭から一行を削除しています。
* 解説 [#explanation]
上記のサンプルでは、`1`行追加した時に規定の行数を越えている場合、先頭の`1`行を削除する`DocumentListener`を作成し、これを`JTextArea`に設定しています。

上記のサンプルでは、10行以上になると先頭行から削除されていきます。また、複数行の入力やペーストには対応していません。それらにも対応する場合は、[http://forums.sun.com/thread.jspa?threadID=409418 Swing (Archive) - JTextArea Memory Overflow ??]を参考にしてみてください。
- `10`行以上になると先頭行から削除
- 複数行テキストのペーストには未対応
-- 参考: [https://community.oracle.com/thread/1479784 Swing (Archive) - JTextArea Memory Overflow ??]は複数行貼り込みに対応している
- `DocumentListener`ではなく以下のような`DocumentFilter`を設定する方法もある
#code{{
((AbstractDocument) ta.getDocument()).setDocumentFilter(new FIFODocumentFilter());
// ...
class FIFODocumentFilter extends DocumentFilter {
  private static final int MAX_LINES = 10;
  @Override public void insertString(
      DocumentFilter.FilterBypass fb, int offset,
      String string, AttributeSet attr)
      throws BadLocationException {
    fb.insertString(offset, string, attr);
    Element root = fb.getDocument().getDefaultRootElement();
    if (root.getElementCount() > MAX_LINES) {
      fb.remove(0, root.getElement(0).getEndOffset());
    }
  }
}
}}

**参考リンク [#z483e8cb]
-[http://forums.sun.com/thread.jspa?threadID=409418 Swing (Archive) - JTextArea Memory Overflow ??]
* 参考リンク [#reference]
- [https://community.oracle.com/thread/1479784 Swing (Archive) - JTextArea Memory Overflow ??]

**コメント [#ba2d344b]
- sample実行できないよ -- [[cinik]] &new{2006-11-16 (木) 01:09:03};
-- jnlpファイルの名前をsampleからexampleに変更しているので、一旦キャッシュを消してみるとうまくいくかもしれません。(じゃなくてExceptionなどが発生しているのでしょうか?) -- [[aterai]] &new{2006-11-16 (木) 12:39:54};
* コメント [#comment]
#comment
- `sample`実行できないよ -- &user(cinik); &new{2006-11-16 (木) 01:09:03};
-- `jnlp`ファイルの名前を`sample`から`example`に変更しているので、一旦キャッシュを消してみるとうまくいくかもしれません。(そうではなく`Exception`などが発生しているのでしょうか?) -- &user(aterai); &new{2006-11-16 (木) 12:39:54};

#comment