package example;
//-*- mode:java; encoding:utf-8 -*-
// vim:set fileencoding=utf-8:
//@homepage@
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;

public class MainPanel extends JPanel {
    private static String str = "Can only edit last line, version 0.0\n";
    public MainPanel() {
        super(new BorderLayout());
        JTextArea textArea = new JTextArea();
        textArea.setMargin(new Insets(2,5,2,2));
        textArea.setText(str + NonEditableLineDocumentFilter.PROMPT);
        ((AbstractDocument)textArea.getDocument()).setDocumentFilter(new NonEditableLineDocumentFilter());

        add(new JScrollPane(textArea));
        setPreferredSize(new Dimension(320, 240));
    }
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override public void run() {
                createAndShowGUI();
            }
        });
    }
    public static void createAndShowGUI() {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch(Exception e) {
            e.printStackTrace();
        }
        JFrame frame = new JFrame("@title@");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.getContentPane().add(new MainPanel());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

class NonEditableLineDocumentFilter extends DocumentFilter {
    public static final String PROMPT = "> ";
    @Override public void insertString(DocumentFilter.FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException {
        if(string == null) {
            return;
        }else{
            replace(fb, offset, 0, string, attr);
        }
    }
    @Override public void remove(DocumentFilter.FilterBypass fb, int offset, int length) throws BadLocationException {
        replace(fb, offset, length, "", null);
    }
    @Override public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
        Document doc = fb.getDocument();
        Element root = doc.getDefaultRootElement();
        int count = root.getElementCount();
        int index = root.getElementIndex(offset);
        Element cur = root.getElement(index);
        int promptPosition = cur.getStartOffset()+PROMPT.length();
        if(index==count-1 && offset-promptPosition>=0) {
            if(text.equals("\n")) {
                String line = doc.getText(promptPosition, offset-promptPosition);
                String[] args = line.split(" ");
                String cmd = args[0];
                if(cmd.isEmpty()) {
                    text = "";
                }else{
                    text = String.format("\n%s: command not found", cmd);
                }
                text += "\n"+PROMPT;
            }
            fb.replace(offset, length, text, attrs);
        }
    }
}

@@ -2823,17 +2823,17 @@
 format(%22
-%5C
+%25
 n%25s: com

Findbugs format string uses newline