Below is a crude DocumentFilter which appears to work. Its basic approach is to let the insert/append happen, query the number of lines after the fact, if more the the max, remove lines from the start as appropriate.
Beware: the lines counted with the textArea methods are (most probably, waiting for confirmation from @Stani) lines-between-cr, not the actual lines as layouted. Depending on your exact requirement, they may or may not suite you (if not, use the Stan's utility methods)
I was surprised and not entirely sure if it's safe
- surprised: the insert method isn't called, needed to implement the replace method instead (in production ready code probably both)
- not sure if the textArea is guaranteed to return up-to-date values in the filter methods (probably not, then the length check can be wrapped in an invokeLater)
Some code:
public class MyDocumentFilter extends DocumentFilter {
private JTextArea area;
private int max;
public MyDocumentFilter(JTextArea area, int max) {
this.area = area;
this.max = max;
}
@Override
public void replace(FilterBypass fb, int offset, int length,
String text, AttributeSet attrs) throws BadLocationException {
super.replace(fb, offset, length, text, attrs);
int lines = area.getLineCount();
if (lines > max) {
int linesToRemove = lines - max -1;
int lengthToRemove = area.getLineStartOffset(linesToRemove);
remove(fb, 0, lengthToRemove);
}
}
}
// usage
JTextArea area = new JTextArea(10, 10);
((AbstractDocument) area.getDocument()).setDocumentFilter(new MyDocumentFilter(area, 3));