Release only the last line for writing

Asked

Viewed 136 times

3

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

2 answers

6


In this answer from 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);
            }
        }
    }
}

Upshot:

custom prompt

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

2

I don’t know if it’s possible to do that directly. But you can create a simple Jtextfield and send the typed text to a Jtextarea, which would not be available for change.

Jtextarea would work only as a buffer and would be located above Jtextfield.

  • I already did it this way, but I really wanted to know a way to style a terminal, cmd, java console, etc....

Browser other questions tagged

You are not signed in. Login or sign up in order to post.