SteveJP
SteveJP

Reputation: 261

Memory use with Java JScrollPane

I have a Java (Swing) data logging application writing text to a JTextArea inside a JScrollPane. The applications appends text to the JTextArea and it scrolls up accordingly. There is only 5 lines of text in the viewable area and it would be acceptable if the user were only able to scroll back a 100 or so lines, but it appears to me that the amount of memory consumed will continue to grow without limit.

Is there anything I can do to limit the number of lines retained or otherwise limit the amount of memory used?

Upvotes: 1

Views: 996

Answers (2)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285403

The scroll pane has nothing to do with this. You could limit the data held by the PlainDocument that is used by the JTextArea. I think that a DocumentFilter could be used for this purpose.

Edit 1
Here's a simple DocumentFilter version of camickr's code (Rob: sorry for the out and out theft!).

import javax.swing.text.*;

public class LimitLinesDocumentFilter extends DocumentFilter {
   private int maxLineCount;

   public LimitLinesDocumentFilter(int maxLineCount) {
      this.maxLineCount = maxLineCount;
   }

   @Override
   public void insertString(FilterBypass fb, int offset, String string,
            AttributeSet attr) throws BadLocationException {
      super.insertString(fb, offset, string, attr);

      removeFromStart(fb);
   }

   @Override
   public void replace(FilterBypass fb, int offset, int length, String text,
            AttributeSet attrs) throws BadLocationException {
      super.replace(fb, offset, length, text, attrs);

      removeFromStart(fb);
   }

   private void removeFromStart(FilterBypass fb) {
      Document doc = fb.getDocument();
      Element root = doc.getDefaultRootElement();
      while (root.getElementCount() > maxLineCount) {
         removeLineFromStart(doc, root);
      }
   }

   private void removeLineFromStart(Document document, Element root) {
      Element line = root.getElement(0);
      int end = line.getEndOffset();

      try {
         document.remove(0, end);
      } catch (BadLocationException ble) {
         ble.printStackTrace();
      }
   }

}

And the code to test it on:

import javax.swing.*;
import javax.swing.text.PlainDocument;

public class LimitLinesDocumentFilterTest {
   private static void createAndShowUI() {
      int rows = 10;
      int cols = 30;
      JTextArea textarea = new JTextArea(rows , cols );
      PlainDocument doc = (PlainDocument)textarea.getDocument();
      int maxLineCount = 9;
      doc.setDocumentFilter(new LimitLinesDocumentFilter(maxLineCount ));

      JFrame frame = new JFrame("Limit Lines Document Filter Test");
      frame.getContentPane().add(new JScrollPane(textarea));
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      java.awt.EventQueue.invokeLater(new Runnable() {
         public void run() {
            createAndShowUI();
         }
      });
   }
}

Upvotes: 2

camickr
camickr

Reputation: 324108

Is there anything I can do to limit the number of lines retained

See: Limit Lines in Document.

Upvotes: 2

Related Questions