2017-10-05 124 views
1

有沒有辦法讓JTextArea的末尾可編輯,並使已經打印到它的任何內容都不可編輯?如何使JTextArea的末尾可編輯

我的意思是,如果我已經寫了「Hello World」例如一個JTextArea,我怎麼能讓它使得用戶可以在「Hello World」之後鍵入任何他們想要的內容,但是他們之前不能輸入或刪除已經打印的文本?

下面是一個小程序,以證明我的煩惱......

public class Test { 
    public static void main(String[] args) { 
     //Here I create a simple JFrame with JTextArea 
     JTextArea textArea = new JTextArea(); 
     JFrame frame = new JFrame(); 
     JFrame.setDefaultLookAndFeelDecorated(true); 
     frame.setSize(250, 250); 
     textArea.setEditable(true); 
     textArea.setVisible(true); 
     frame.add(textArea); 
     frame.setVisible(true); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 


     /*Here I print "Hello World" onto the text area.. after the ">>" I want the 
     the user to be able to type whatever they want.. however I don't want them 
     to be able to edit the "Hello World"*/ 
     textArea.append("Hello World\n>>"); 
     textArea.setCaretPosition(textArea.getDocument().getLength()); 
    } 
} 

在用戶能夠進入任何他們想要的文字..的例子就是我想要的。但是他們也能編輯我使用append打印的文本..我不想要..

我該如何解決這個問題?

+1

DocumentFilter可能工作。我會試驗一下。 –

+3

也演示了[這裏](https://stackoverflow.com/questions/15017148/jtextarea-as-io-console/15025085#15025085);) – MadProgrammer

回答

4

是的,一個DocumentFilter將工作。創建一個只允許在文檔結尾添加文本的情況 - 即偏移量等於文檔長度。也完全禁用刪除方法。事情是這樣:

import javax.swing.text.AttributeSet; 
import javax.swing.text.BadLocationException; 
import javax.swing.text.DocumentFilter; 

public class MyFilter extends DocumentFilter { 
    @Override 
    public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr) 
      throws BadLocationException { 
     // only insert text if at the end of the document 
     // if offset == document length 
     if (offset == fb.getDocument().getLength()) { 
      super.insertString(fb, offset, string, attr); 
     } 
    } 

    @Override 
    public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) 
      throws BadLocationException { 
     // only replace text if at the end of the document 
     // if offset == document length 
     if (offset == fb.getDocument().getLength()) { 
      super.replace(fb, offset, length, text, attrs); 
     } 
    } 

    @Override 
    public void remove(FilterBypass fb, int offset, int length) throws BadLocationException { 
     // do nothing. Totally inactivate this 
    } 
} 

你可以測試它像這樣:

import javax.swing.*; 
import javax.swing.text.PlainDocument; 

@SuppressWarnings("serial") 
public class LimitedTextArea extends JPanel { 
    private JTextArea textArea = new JTextArea(15, 50); 

    public LimitedTextArea() { 
     // get textArea's Document and cast to PlainDocument: 
     PlainDocument document = (PlainDocument) textArea.getDocument(); 
     // set the document's filter with "MyFilter" 
     document.setDocumentFilter(new MyFilter()); 

     textArea.setLineWrap(true); 
     textArea.setWrapStyleWord(true); 
     JScrollPane scrollPane = new JScrollPane(textArea); 
     scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 
     add(scrollPane); 
    } 

    private static void createAndShowGui() { 
     LimitedTextArea mainPanel = new LimitedTextArea(); 

     JFrame frame = new JFrame("LimitedTextArea"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> createAndShowGui()); 
    } 
} 
1

你也可以使用一個NavigationFilter

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

public class NavigationFilterPrefix extends NavigationFilter 
{ 
    private int prefixLength; 
    private Action deletePrevious; 

    public NavigationFilterPrefix(int prefixLength, JTextComponent component) 
    { 
     this.prefixLength = prefixLength; 
     deletePrevious = component.getActionMap().get("delete-previous"); 
     component.getActionMap().put("delete-previous", new BackspaceAction()); 
     component.setCaretPosition(prefixLength); 
    } 

    @Override 
    public void setDot(NavigationFilter.FilterBypass fb, int dot, Position.Bias bias) 
    { 
     fb.setDot(Math.max(dot, prefixLength), bias); 
    } 

    @Override 
    public void moveDot(NavigationFilter.FilterBypass fb, int dot, Position.Bias bias) 
    { 
     fb.moveDot(Math.max(dot, prefixLength), bias); 
    } 

    class BackspaceAction extends AbstractAction 
    { 
     @Override 
     public void actionPerformed(ActionEvent e) 
     { 
      JTextComponent component = (JTextComponent)e.getSource(); 

      if (component.getCaretPosition() > prefixLength) 
      { 
       deletePrevious.actionPerformed(null); 
      } 
     } 
    } 

    private static void createAndShowUI() 
    { 
     JTextField textField = new JTextField("Prefix_", 20); 
     textField.setNavigationFilter(new NavigationFilterPrefix(7, textField)); 

     JFrame frame = new JFrame("Navigation Filter Example"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(textField); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) 
    { 
     SwingUtilities.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       createAndShowUI(); 
      } 
     }); 
    } 
} 

這將允許用戶編輯文本,他們添加到文本字段。

這將阻止選擇固定文本。

要了解更多高級功能,請查看Protected Document,它允許您保護文檔的多個區域不被更改。

相關問題