How to trim a Document's size
I have a Swing app that displays fire alarm messages. It needs to be on all the time. Because I need to display the output in different colors (according to the alarm), I am using a StyledDocument in a jTextPane:
private JTextPane ep;
ep.setCaretPosition(0);
StyledDocument styledDoc = ep.getStyledDocument();
if (styledDocinstanceof AbstractDocument){
doc = (AbstractDocument)styledDoc;
// Add an undoableEditListener
doc.addUndoableEditListener(new MyEditListener());
} ...
If the document gets too big, I remove() its beginning:
// Keep the document to a manageable size
int docLength = doc.getLength();
if(docLength > 20000){
doc.remove(0, docLength - 20000);
}
Much to my surprise (after I used the NetBeans memory profiler), I found that all my cut text seems to be going into an undo buffer! javax.swing.text.GapContent$UndoPosRef
Which is why I added the UndoableEditListener:
publicclass MyEditListenerimplements UndoableEditListener{
public MyEditListener(){
}
publicvoid undoableEditHappened(UndoableEditEvent e){
UndoableEdit edit = e.getEdit();
edit.die();
}
}
The listener gets called after every insert and deletion, and I thought the call to die() should have removed the things from the UndoManager. But it does not.
Since my app needs to be on all the time, how do I keep my document size to a fixed size?
In general, I think the StyledDocument needs to have a method to control the amount of the undo stack.
[2334 byte] By [
jamesromea] at [2007-11-26 15:39:23]

# 5
It doesn't matter if you don't add an UndoableEditListener. The UndoableEdit object is created and returned by the remove() and insertString() methods of the document's Content object. Then it gets added to the DocumentEvent in the handleRemove() and handleInsertString() methods of AbstractDocument. As long as there's a reference to that DocumentEvent somewhere, the UndoableEdit will continue to exist. And DocumentEvents are used all over the place.
The handleXXX() methods are package-private, so you can't override them. However, they both do a check first, and only add the UndoableEdit if it's not null. You may be able to create your own Content class that extends GapContent and returns null from its remove() and insertString() methods. The UndoableEdits will still get created, but they'll become eligible for garbage collection as soon as the method returns. public UndoableEdit insertString(int where, String str)
throws BadLocationException {
super.insertString(where, str);
return (UndoableEdit)null;
}
public UndoableEdit remove(int where, int nitems)
throws BadLocationException {
super.remove(where, nitems);
return (UndoableEdit)null;
}
You can pass an instance of your derived Content class to the appropriate constructor of the DefaultStyledDocument, then pass that document to the JTextPane constructor.
# 7
After making those changes and running for a while, javax.swing.text.GapContent$UndoPosRef is still growing. It is up to 315kB. Why is this still growing if I tell it to not do any Undos? Here is what I did....
ep = client.getOutputTextPane();
ep.setCaretPosition(0);
attrs = initAttributes(3);
StyleContext context = new StyleContext();
DefaultStyledDocument styledDoc = new DefaultStyledDocument(new MyGapContent(), context);
doc = (AbstractDocument)styledDoc;
ep.setDocument(doc);
Message was edited by:
jamesrome