我有这段代码,即在插入n个字符后“禁用” JTextField上的用户输入:

JTextField tf = new JTextField();
tf.addKeyListener(new KeyAdapter() {
    public void keyTyped(KeyEvent e) {
        if (((JTextField) e.getSource()).getText().length() > n) {
            e.consume();
        }
    }
});


它可以工作,但是我想知道是否还有其他选择,因为我在旧的慢速计算机上尝试过,当我在文本字段中键入内容时,添加了字母,然后它消失了...我想避免使用e.consume()用户输入后直接阻止插入。

可能吗?

编辑

我忘了提到我仅在此示例中使用了JTextField,但是我希望此代码与通用文本输入组件(例如JTextPaneJTextArea等)一起使用

最佳答案

您可以使用DocumentSizeFilter

专门为此用途而设计的:
http://docs.oracle.com/javase/tutorial/uiswing/examples/components/TextComponentDemoProject/src/components/DocumentSizeFilter.java

有关在“实现文档过滤器”部分中如何执行此操作的教程:


http://docs.oracle.com/javase/tutorial/uiswing/components/generaltext.html#filter


从那里报价:


  为了限制文档中允许的字符,DocumentSizeFilter
  覆盖DocumentFilter类的insertString方法,该方法是
  每次将文本插入文档时调用。它也是
  覆盖replace方法,该方法最有可能在以下情况下被调用
  用户粘贴新文本。通常,文本插入会导致
  当用户键入或粘贴新文本时,或在setText方法中
  叫做。这是DocumentSizeFilter类的实现
  insertString方法:


public void insertString(FilterBypass fb, int offs,
                         String str, AttributeSet a)
    throws BadLocationException {

    if ((fb.getDocument().getLength() + str.length()) <= maxCharacters)
        super.insertString(fb, offs, str, a);
    else
        Toolkit.getDefaultToolkit().beep(); }

09-30 18:38