Java Tips Weblog

  • Blog Stats

    • 2,076,561 hits
  • Categories

  • Archives

  • Advertisements

Limit Lines in Document

Posted by Rob Camick on October 15, 2008

You may want to use a JTextArea or JTextPane as a simple console type component. That is, messages from your application will be added to the console as they are generated. Now you will probably need the ability to limit the total number of messages in the console so that you don’t run out of memory. How can we do this?

Well, we must remember that every text component uses a Document to store the text. Therefore, we will need to monitor changes to the Document. This is easily accomplished by adding a DocumentListener to the Document. Now all we have to do is handle the insertUpate(…) method of the DocumentListener interface and we are in business.

The LimitLinesDocumentListener class does just this. Every time even a single character is added to the Document, this class will check the current number of lines. When the curent number of lines exceeds the maximum, lines of text will be removed from the Document. The only other choice you need to make is whether you remove the lines from the start or end of the Document:

  • start (the default) – would be used when your application appends text to the Document (ie. all new text is displayed at the botton of your console)
  • end – would be used when your application inserts text at the start of the Document (ie. all the new text is displayed at the top of your console)

You get all this functionality with a single line of code:

textComponent.getDocument().addDocumentListener(
    new LimitLinesDocumentListener(50) );

Get The Code

LimitLinesDocumentListener.java

Related Reading

How to Write a Document Listener

Advertisements

7 Responses to “Limit Lines in Document”

  1. Anonymous said

    thanks, my GUI has no exceptions anymore :)

  2. teo said

    thank you thank you thank you very much!

  3. Anonymous said

    thanks a lot!

  4. seebs said

    On at least one system, this resulted in a very weird infinite loop, because Java reported 0 for getEndOffset() for a line. More generally, though, the performance is insanely bad; if you need to remove more than one line, you’re doing a lot of very expensive large copies and recounts over and over again.

    • Rob Camick said

      Agreed, this class was implemented for the common case where you add 1 line and remove one line. Think about the Message Console class found in the this blog where each System.out.println(…) statement adds a single lines and therefore potentially removes a single line. This is done with minimal calculations. If you have usage cases where you insert block of lines at one time, then you may want to add additional code to calculate start/end offset to optimize the code for your usage. The main purpose of the blog is to promote ideas.

    • Rob Camick said

      Regarding the 0 offset, maybe your code is incorrect. Updates to Swing components must be done on the Event Dispatch Thread or you can have concurrency issues. The code attempts to prevent this by using the invokeLater() method.

      • seebs said

        The code appears to have been just this code, and I don’t know much about the Swing side of things, but it appeared to be unique to Windows, and some releases of Java. Changing it to search ahead for more than one line did fix it, though. The actual use case was a Minecraft launcher, and it was common for things to dump 20+ lines into the log at once (say, an entire stack trace), and they had a 10k+ line buffer, so the copying/allocating was huge. (I also did add the invokeLater thing.)

        See:

        https://github.com/SKCraft/Launcher/pull/82

        I get that this is mostly about promoting ideas, but I feel like it’s important to teach good habits, and stripping one line at a time from a large buffer seems like a bad habit. The garbage collection load from lots of data copies is gonna add up.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s