Release only the last line for writing

3

How do I allow the user to be able to write only the last line of a JTextArea , that is, without being able to make modifications in the upper rows? (such as CMD or Terminal, for example).

    
asked by anonymous 30.06.2016 / 03:02

2 answers

7

In this answer of SOEn, there is an example that fits perfectly as a solution for you, see:

import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;

public class CustomPromptTest {

    public JComponent makeUI() {
        JTextArea textArea = new JTextArea(8, 0);
        textArea.setText("> ");

        //define a cor de fundo do componente
        textArea.setBackground(Color.BLACK);
        //define a cor principal(primeiro plano) do componente
        textArea.setForeground(Color.WHITE);
        //define tipo e tamanho da fonte do componente
        textArea.setFont(new Font("Lucida Console", 1, 12));
        //define a cor do cursor
        textArea.setCaretColor(Color.WHITE);

        ((AbstractDocument) textArea.getDocument()).setDocumentFilter(new NonEditableLineDocumentFilter());
        JPanel p = new JPanel(new BorderLayout());
        p.setPreferredSize(new Dimension(300, 200));
        p.add(new JScrollPane(textArea));
        return p;
    }

    public static void createAndShowGUI() {
        JFrame f = new JFrame();
        f.setTitle("Custom Prompt Java");
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        f.getContentPane().add(new CustomPromptTest().makeUI());
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> createAndShowGUI());
    }

    class NonEditableLineDocumentFilter extends DocumentFilter {

        @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);
        }

        private static final String PROMPT = "> ";

        @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 cmd = doc.getText(promptPosition, offset - promptPosition);
                    if (cmd.isEmpty()) {
                        text = "\n" + PROMPT;
                    } else {
                        text = "\n" + cmd + "\n" + PROMPT;
                    }
                }
                fb.replace(offset, length, text, attrs);
            }
        }
    }
}

Result:

I made some modifications but just modify background, foreground and font in method MakeUI if you want to modify the visual.

    
01.11.2016 / 13:42
2

I do not know if you can do this directly. But you can create a simple JTextField and send the text typed in it to a JTextArea, which would not be available for change.

The JTextArea would only function as a buffer and would be located above the JTextField.

    
30.06.2016 / 13:35