Make parts of a JTextArea non editable (not the whole JTextArea!)

document, java, jtextarea, jtextcomponent, swing

Solution

You do not need to create your own component.

This can be done (as in I have done it) using a custom DocumentFilter.

You can get the document from `textPane.getDocument()` and set a filter on it by `document.setFilter()`. Within the filter, you can check the prompt position, and only allow modifications if the position is after the prompt.

For example:

private class Filter extends DocumentFilter {
    public void insertString(final FilterBypass fb, final int offset, final String string, final AttributeSet attr)
            throws BadLocationException {
        if (offset >= promptPosition) {
            super.insertString(fb, offset, string, attr);
        }
    }

    public void remove(final FilterBypass fb, final int offset, final int length) throws BadLocationException {
        if (offset >= promptPosition) {
            super.remove(fb, offset, length);
        }
    }

    public void replace(final FilterBypass fb, final int offset, final int length, final String text, final AttributeSet attrs)
            throws BadLocationException {
        if (offset >= promptPosition) {
            super.replace(fb, offset, length, text, attrs);
        }
    }
}

However, this prevents you from programmatically inserting content into the output (noneditable) section of the terminal. What you can do instead is either a passthrough flag on your filter that you set when you're about to add the output, or (what I did) set the document filter to null before appending the output, and then reset it when you're done.

Problem

I'm currently working on a console window in Swing. It's based on a JTextArea and works like a common command line. You type a command in one line and press enter. In the next line, the output is shown and under that output, you could write the next command. Now I want, that you could only edit the current line with your command. All lines above (old commands and results) should be non editable. How can I do this?

Original source