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).
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).
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.
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.