【问题标题】:How To limit the number of characters in JTextField?如何限制 JTextField 中的字符数?
【发布时间】:2011-03-31 22:54:38
【问题描述】:

如何限制在 JTextField 中输入的字符数?

假设我想输入最多 5 个字符。之后就不能再输入字符了。

【问题讨论】:

  • 虽然使用自定义 Document 会起作用,但此解决方案的首选方法是使用 JFormattedTextField 或使用 DocumentFilter。我相信这些都是 JDK 1.3 版本中添加的功能。 Swing 教程涵盖了这两种方法(甚至从教程中删除了自定义 Document 方法)。
  • 仅供参考,从 Java 1.4 开始,不再需要此功能,建议您使用 Document,而不是使用 DocumentFilter,请参阅 Implementing a Document FilterDocumentFilter Examples 了解更多详细信息

标签: java swing


【解决方案1】:

http://www.rgagnon.com/javadetails/java-0198.html

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

public class JTextFieldLimit extends PlainDocument {
  private int limit;

  JTextFieldLimit(int limit) {
   super();
   this.limit = limit;
   }

  public void insertString( int offset, String  str, AttributeSet attr ) throws BadLocationException {
    if (str == null) return;

    if ((getLength() + str.length()) <= limit) {
      super.insertString(offset, str, attr);
    }
  }
}

然后

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

 public class DemoJTextFieldWithLimit extends JApplet{
   JTextField textfield1;
   JLabel label1;

   public void init() {
     getContentPane().setLayout(new FlowLayout());
     //
     label1 = new JLabel("max 10 chars");
     textfield1 = new JTextField(15);
     getContentPane().add(label1);
     getContentPane().add(textfield1);
     textfield1.setDocument
        (new JTextFieldLimit(10));
     }
}

(谷歌的第一个结果)

【讨论】:

  • 有没有像textfield.maximumlimit(10)这样的直接函数;
  • 不,它告诉您在 JTextField download.oracle.com/javase/6/docs/api/javax/swing/… 的 javadoc 中使用扩展 PlainDocument 的类
  • 输入上述代码时出现两个错误。 1 - 包 com.sun.java.swing.text 不存在 2 - 找不到符号 PlainDocument
  • 还可以从相关问题中考虑this answer,它显示了另一种选择。
  • 仅供参考,从 Java 1.4 开始,不再需要此功能,建议您使用 Document,而不是使用 DocumentFilter,请参阅 Implementing a Document FilterDocumentFilter Examples 了解更多详细信息
【解决方案2】:

如果您想将所有内容都放在一段代码中,那么您可以将 tim 的答案与JTextField API 上的示例方法混合使用,您将得到如下结果:

public class JTextFieldLimit extends JTextField {
    private int limit;

    public JTextFieldLimit(int limit) {
        super();
        this.limit = limit;
    }

    @Override
    protected Document createDefaultModel() {
        return new LimitDocument();
    }

    private class LimitDocument extends PlainDocument {

        @Override
        public void insertString( int offset, String  str, AttributeSet attr ) throws BadLocationException {
            if (str == null) return;

            if ((getLength() + str.length()) <= limit) {
                super.insertString(offset, str, attr);
            }
        }       

    }

}

那么由于 JTextFieldLimit 里面已经有这个功能,所以不需要在 JTextFieldLimit 中添加 Document。

【讨论】:

【解决方案3】:

阅读 Implementing a DocumentFilter 上的 Swing 教程中的部分,以获取更新的解决方案。

此解决方案适用于任何文档,而不仅仅是普通文档。

这是一种比目前接受的解决方案更新的解决方案。

【讨论】:

    【解决方案4】:

    很好的问题,奇怪的是 Swing 工具包没有为 JTextFields 原生地包含这个功能。但是,这是我的 Udemy.com 课程“像孩子一样学习 Java”的一个很好的答案:

    txtGuess = new JTextField();
    txtGuess.addKeyListener(new KeyAdapter() {
        public void keyTyped(KeyEvent e) { 
            if (txtGuess.getText().length() >= 3 ) // limit textfield to 3 characters
                e.consume(); 
        }  
    });
    

    这会将猜谜游戏文本字段中的字符数限制为 3 个字符,方法是覆盖 keyTyped 事件并检查文本字段是否已经有 3 个字符 - 如果是,您正在“消耗”键事件(e ) 这样它就不会像平常一样被处理。

    【讨论】:

    • 这也会阻止退格或删除关键事件,因此一旦达到 3 个字符,就无法再删除它们。
    【解决方案5】:

    试试这个:

    textfield.addKeyListener(new java.awt.event.KeyAdapter() {
        public void keyTyped(java.awt.event.KeyEvent evt) {
            if(textfield.getText().length()>=5&&!(evt.getKeyChar()==KeyEvent.VK_DELETE||evt.getKeyChar()==KeyEvent.VK_BACK_SPACE)) {
                getToolkit().beep();
                evt.consume();
             }
         }
    });
    

    【讨论】:

    • 仅供参考,从 Java 1.4 开始,不再需要并建议您使用 Document 来实现此功能,而是使用 DocumentFilter,请参阅 Implementing a Document FilterDocumentFilter Examples 了解更多详细信息, KeyListener 对于文本组件从来都不是一个好主意
    • 像魅力一样工作!谢谢。这个问题至少有 3 个答案是这个答案的副本。对SO的抄袭没有任何控制吗?如果答案已经存在,为什么要添加与新答案相同的答案??
    【解决方案6】:

    我已经通过使用以下代码段解决了这个问题:

    private void jTextField1KeyTyped(java.awt.event.KeyEvent evt) {
        boolean max = jTextField1.getText().length() > 4;
        if ( max ){
            evt.consume();
        }        
    }
    

    【讨论】:

      【解决方案7】:
      import java.awt.KeyboardFocusManager;
      import javax.swing.InputVerifier;
      import javax.swing.JTextField;
      import javax.swing.text.AbstractDocument;
      import javax.swing.text.AttributeSet;
      import javax.swing.text.BadLocationException;
      import javax.swing.text.DocumentFilter;
      import javax.swing.text.DocumentFilter.FilterBypass;
      
      /**
       *
       * @author Igor
       */
      public class CustomLengthTextField extends JTextField {
      
          protected boolean upper = false;
          protected int maxlength = 0;
      
          public CustomLengthTextField() {
              this(-1);
          }
      
          public CustomLengthTextField(int length, boolean upper) {
              this(length, upper, null);
          }
      
          public CustomLengthTextField(int length, InputVerifier inpVer) {
              this(length, false, inpVer);
          }
      
          /**
           *
           * @param length - maksimalan length
           * @param upper - turn it to upercase
           * @param inpVer - InputVerifier
           */
          public CustomLengthTextField(int length, boolean upper, InputVerifier inpVer) {
              super();
              this.maxlength = length;
              this.upper = upper;
              if (length > 0) {
                  AbstractDocument doc = (AbstractDocument) getDocument();
                  doc.setDocumentFilter(new DocumentSizeFilter());
              }
              setInputVerifier(inpVer);
          }
      
          public CustomLengthTextField(int length) {
              this(length, false);
          }
      
          public void setMaxLength(int length) {
              this.maxlength = length;
          }
      
          class DocumentSizeFilter extends DocumentFilter {
      
              public void insertString(FilterBypass fb, int offs, String str, AttributeSet a)
                      throws BadLocationException {
      
                  //This rejects the entire insertion if it would make
                  //the contents too long. Another option would be
                  //to truncate the inserted string so the contents
                  //would be exactly maxCharacters in length.
                  if ((fb.getDocument().getLength() + str.length()) <= maxlength) {
                      super.insertString(fb, offs, str, a);
                  }
              }
      
              public void replace(FilterBypass fb, int offs,
                      int length,
                      String str, AttributeSet a)
                      throws BadLocationException {
      
                  if (upper) {
                      str = str.toUpperCase();
                  }
      
                  //This rejects the entire replacement if it would make
                  //the contents too long. Another option would be
                  //to truncate the replacement string so the contents
                  //would be exactly maxCharacters in length.
                  int charLength = fb.getDocument().getLength() + str.length() - length;
      
                  if (charLength <= maxlength) {
                      super.replace(fb, offs, length, str, a);
                      if (charLength == maxlength) {
                          focusNextComponent();
                      }
                  } else {
                      focusNextComponent();
                  }
              }
      
              private void focusNextComponent() {
                  if (CustomLengthTextField.this == KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner()) {
                      KeyboardFocusManager.getCurrentKeyboardFocusManager().focusNextComponent();
                  }
              }
          }
      }
      

      【讨论】:

        【解决方案8】:

        只需将此代码放入 KeyTyped 事件中:

            if ((jtextField.getText() + evt.getKeyChar()).length() > 20) {
                evt.consume();
            }
        

        其中“20”是您想要的最大字符数。

        【讨论】:

          猜你喜欢
          • 2012-05-22
          • 1970-01-01
          • 1970-01-01
          • 2014-01-25
          • 1970-01-01
          • 2014-10-14
          • 1970-01-01
          • 2012-09-29
          • 1970-01-01
          相关资源
          最近更新 更多