Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Limit number of lines in JTextArea?

I am trying to make a GUI for a service, which have a JTextArea to view messages in, each message is written on a single line, and wordwrapped if needed.

The messages arrive via a socket, so it is merely an .append(message) that i am using to update the JTextArea, i need to limit these lines to 50 or 100 and i have no need to limit character count on each line.

If there is a method to limit the number lines in the JTextArea or if there is an alternative method of doing it?

I could really use the assistance in this matter.

Edit

The problem is that each client can send infinite lines, all these lines have to be readable, so this is not a simple check of the number of lines in the JTextArea. I need to remove older lines in order to view newer lines.

like image 432
Ralph Andreasen Avatar asked Aug 28 '12 13:08

Ralph Andreasen


2 Answers

Use this to get row and column

Add a DocumentFilter which checks amount of rows (pass the doc.getLength() offset) and prevent adding more text.

Or you can create a dummy invisible JTextArea and add all the text there. Then measure last allowed line and cut the text.

like image 175
StanislavL Avatar answered Oct 06 '22 16:10

StanislavL


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));
like image 43
kleopatra Avatar answered Oct 06 '22 18:10

kleopatra