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

前端 未结 5 1626
甜味超标
甜味超标 2020-12-16 18:42

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

5条回答
  •  臣服心动
    2020-12-16 19:18

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.text.*;
    public class OnlyEditCurrentLineTest {
      public JComponent makeUI() {
        JTextArea textArea = new JTextArea(8,0);
        textArea.setText("> aaa\n> ");
        ((AbstractDocument)textArea.getDocument()).setDocumentFilter(
            new NonEditableLineDocumentFilter());
        JPanel p = new JPanel(new BorderLayout());
        p.add(new JScrollPane(textArea), BorderLayout.NORTH);
        return p;
      }
      public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
          @Override public void run() { createAndShowGUI(); }
        });
      }
      public static void createAndShowGUI() {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        f.getContentPane().add(new OnlyEditCurrentLineTest().makeUI());
        f.setSize(320,240);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
      }
    }
    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();
         //As Reverend Gonzo says:
         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    xxxxxxxxxx\n" + PROMPT;
             }
           }
           fb.replace(offset, length, text, attrs);
         }
      }
    }
    

提交回复
热议问题