2017-10-05 81 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,它允许您保护文档的多个区域不被更改。

相关问题