概要

ドキュメントのサイズを一定にして、JTextAreaなど表示できる行数を制限します。Swing (Archive) - JTextArea Memory Overflow ??にあるソースコードを参考にしています。

サンプルコード

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;
    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 {
      doc.remove(0, fl.getEndOffset());
    } 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);
  }
});
view all

解説

上記のサンプルでは、一行追加した時に規定の行数を越えている場合、先頭の一行を削除するDocumentListenerを作成し、これをJTextAreaに設定しています。

  • メモ
    • 10行以上になると先頭行から削除
    • 複数行の貼り付けなどには未対応
    • DocumentListenerではなく、以下のようなDocumentFilterを設定する方法もある
      //((AbstractDocument) jta.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());
          }
        }
      }
      

参考リンク

コメント