当前位置: 首页 > 知识库问答 >
问题:

JTextField限制字符量输入,仅接受数字

栾弘新
2023-03-14

下面是关于如何限制字符输入长度的代码

class JTextFieldLimit extends PlainDocument {
  private int limit;
  // optional uppercase conversion
  private boolean toUppercase = false;

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

  JTextFieldLimit(int limit, boolean upper) {
   super();
   this.limit = limit;
   toUppercase = upper;
   }

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

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

可以通过txtSample实现。setDocument(新的JTextFieldLimit(30))

这是我只接受数字的东西(它接受十进制,尽管我不需要w/c)

class NumericDocument extends PlainDocument {

     protected int decimalPrecision = 0;
     protected boolean allowNegative = false;


     public NumericDocument(int decimalPrecision, boolean allowNegative) {
          super();
          this.decimalPrecision = decimalPrecision;
          this.allowNegative = allowNegative;
     }



    @Override
     public void insertString(int offset, String str, AttributeSet attr) throws BadLocationException {
          if (str != null){
               if (StringFormat.isNumeric(str) == false && str.equals(".") == false && str.equals("-") == false){ //First, is it a valid character?
                    Toolkit.getDefaultToolkit().beep();
                    return;
               }
               else if (str.equals(".") == true && super.getText(0, super.getLength()).contains(".") == true){ //Next, can we place a decimal here?
                    Toolkit.getDefaultToolkit().beep();
                    return;
               }
               else if (StringFormat.isNumeric(str) == true && super.getText(0, super.getLength()).indexOf(",") != -1 && offset>super.getText(0, super.getLength()).indexOf(",") && super.getLength()-super.getText(0, super.getLength()).indexOf(".")>decimalPrecision && decimalPrecision > 0){ //Next, do we get past the decimal precision limit?
                    Toolkit.getDefaultToolkit().beep();
                    return;
               }
               else if (str.equals("-") == true && (offset != 0 || allowNegative == false)){ //Next, can we put a negative sign?
                    Toolkit.getDefaultToolkit().beep();
                    return;
               }


               super.insertString(offset, str, attr);
          }
          return;
     }
public static class StringFormat
{
    public StringFormat()
    {
    }
    public static boolean isNumeric(String str)
    {
        try
        {
            int x = Integer.parseInt(str);
            System.out.println(x); return true;
        } catch(NumberFormatException nFE)
        {
            System.out.println("Not an Integer"); return false;
        }
    }
}

}

下面是如何使用这段代码:txtSample.setDocument(new NumericDocument(0, false));

现在的问题是txtSample只能setDocument一次。如何限制jtextfield的长度,同时只接受数字?或者有没有更简单的方法?谢谢D


共有3个答案

农均
2023-03-14
    import java.awt.event.KeyAdapter;    
    import java.awt.event.KeyEvent;    
    import javax.swing.JTextField;        

    public class Validation {

         public static void validateInt(final JTextField txt){
            txt.addKeyListener(new KeyAdapter() {

                   @Override
                   public void keyTyped(KeyEvent e) {
                        char c = e.getKeyChar();
                        if ( ((c < '0') || (c > '9')) 
                             && (c != KeyEvent.VK_BACK_SPACE)) {
                        e.consume();  // ignore event
                   }
               }
            });
        }

        public static void validatelength(final JTextField txt,final int size){    
              txt.addKeyListener(new KeyAdapter() {

              @Override 
              public void keyTyped(KeyEvent e) {     
                  String text = txt.getText();  
                  int length = text.length();  
                  if (length == size) {  
                          e.consume();// ignore event  
                  }
              }   
        });
     }  
   }
司徒隐水
2023-03-14

JFormattedTextField

 JTextComponent txt = new JFormattedTextField( new LimitedIntegerFormatter(limit) );
  txt.addPropertyChangeListener("value", yourPropertyChangeListener);


import javax.swing.text.DefaultFormatter;
import java.text.ParseException;

public class LimitedIntegerFormatter extends DefaultFormatter {

  static final long serialVersionUID = 1l;
  private int limit;

  public LimitedIntegerFormatter( int limit ) {
    this.limit = limit;
    setValueClass(Integer.class);
    setAllowsInvalid(false);
    setCommitsOnValidEdit(true);
  }
  @Override
  public Object stringToValue(String string) throws ParseException {
    if (string.equals("")) return null;
    if (string.length() > limit) throw new ParseException(string, limit);
    return super.stringToValue(string);
  }
}

将使用调用yourPropertyChangeListener

new PropertyChangeEvent(“值”、整数oldValue、整数newValue)

(oldValue或newValue在“”文本框中为空)

每次有效编辑之后

仉明知
2023-03-14

你的思路是正确的,除非你想使用DocumentFilter,而不是实现自己的文档。

MDP的Weblog有很多很好的例子(包括限制长度和字符类型)。

现在,对于您的问题,您可以创建级联过滤器,在这里您可以将一系列过滤器链接在一起。

这将允许您依次调用每个过滤器。

public class ChainableFilter extends DocumentFilter {

    private List<DocumentFilter> filters;
    private AttributeSet attr;

    public ChainableFilter() {
        filters = new ArrayList<DocumentFilter>(25);
    }

    public void addFilter(DocumentFilter filter) {
        filters.add(filter);
    }

    public void removeFilter(DocumentFilter filter) {
        filters.remove(filter);
    }

    public void insertString(DocumentFilter.FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException {
        for (DocumentFilter filter : filters) {
            filter.insertString(fb, offset, string, attr);
        }
    }        

    public void remove(DocumentFilter.FilterBypass fb, int offset, int length) throws BadLocationException {
        for (DocumentFilter filter : filters) {
            filter.remove(fb, offset, length);
        }
    }

    public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
        for (DocumentFilter filter : filters) {
            filter.replace(fb, offset, length, text, attrs);
        }
    }

}

现在,如果过滤器能够真正告诉链是否更改了文档,那就太好了,但我会把它留给你

已更新

你所做的事情和DocumentFilters的工作原理基本相同。好处是,你不会把自己局限于一个普通文档,理论上,你可以将它应用于JTextPaneJEditorPane

过滤链的基本思想很简单。

ChainableFilter chainableFilter = new ChainableFilter();
chainableFilter.addFilter(new RestrictedLengthFilter()); // User supplied filter 
chainableFilter.addFilter(new NumericFilter()); // User supplied filter 

((AbstractDocument)textField.getDocument()).setDocumentFilter(chainableFilter);

至于实际的过滤器,我会查看我之前发布的链接。不过,你的想法是正确的

已更新

SizeFilter sizeFilter = new SizeFilter(12);
NumberFilter numFilter = new NumberFilter();
ChainableFilter chainFilter = new ChainableFilter();
chainFilter.addFilter(sizeFilter);
chainFilter.addFilter(numFilter);

JTextField field = new JTextField();
((AbstractDocument) field.getDocument()).setDocumentFilter(chainFilter);



    public class NumberFilter extends DocumentFilter {

        private int decimalPrecision = 2;
        private boolean allowNegative = false;

        public NumberFilter() {
        }

        public NumberFilter(int decimals, boolean negatives) {
            decimalPrecision = decimals;
            allowNegative = negatives;
        }

        protected boolean accept(FilterBypass fb, int offset, String str) throws BadLocationException {
            boolean accept = true;    
            int length = fb.getDocument().getLength();
            String currentText = fb.getDocument().getText(0, length);

            if (str != null) {
                if (!isNumeric(str) && !str.equals(".") && !str.equals("-")) { //First, is it a valid character?
                    Toolkit.getDefaultToolkit().beep();
                    accept = false;
                } else if (str.equals(".") && currentText.contains(".")) { //Next, can we place a decimal here?
                    Toolkit.getDefaultToolkit().beep();
                    accept = false;
                } else if (isNumeric(str)
                                && currentText.indexOf(",") != -1
                                && offset > currentText.indexOf(",")
                                && length - currentText.indexOf(".") > decimalPrecision
                                && decimalPrecision > 0) { //Next, do we get past the decimal precision limit?
                    Toolkit.getDefaultToolkit().beep();
                    accept = false;
                } else if (str.equals("-") && (offset != 0 || !allowNegative)) { //Next, can we put a negative sign?
                    Toolkit.getDefaultToolkit().beep();
                    accept = false;
                }
            }
            return accept;
        }

        @Override
        public void insertString(FilterBypass fb, int offset, String str, AttributeSet as) throws BadLocationException {
            if (accept(fb, offset, str)) {
                super.insertString(fb, offset, str, as);
            }
        }

        @Override
        public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
            if (accept(fb, offset, text)) {
                super.replace(fb, offset, length, text, attrs);
            }
        }

        public boolean isNumeric(String str) {
            try {
                int x = Integer.parseInt(str);
                System.out.println(x);
                return true;
            } catch (NumberFormatException nFE) {
                System.out.println("Not an Integer");
                return false;
            }
        }
    }

    public class SizeFilter extends DocumentFilter {

        private int maxCharacters;

        public SizeFilter(int maxChars) {
            maxCharacters = maxChars;
        }

        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();
            }
        }

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

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

再次,我知道它编译,但我还没有测试它(特别是数字过滤器),但这将是一个很好的调试练习;)

 类似资料:
  • 问题内容: 我想创建JTextField,输入字符限于“ abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYWZZ0123456789 +&@#/%?=〜_- |!:,。;”之类的输入字符。所以我尝试覆盖 但这不是我想要的,因为用户无法再按ctrl-c ctrl-v ctrl-x …所以我添加了 到if条件,但现在用户可以粘贴不适当的输入,即’(’

  • 问题内容: 我在AngularJS中使用ngChange来触发自定义函数,该函数将删除用户添加到输入中的所有字母。 问题是我需要定位触发的输入,以便删除输入的字母。我已经在Google上寻找了很长时间,并且对此一无所获。 我能做什么? 问题答案: 简单的方法 ,如果适用于您的用例,请使用type =“ number” : 另一种简单的方法: ng- pattern 也可用于定义正则表达式,以限制字

  • 所以我做了一个测试窗口,里面有一个JTextField。我不知道出了什么问题。下面是主要代码。问题是,无论我做什么,我都无法编辑文本字段,也无法编辑我创建的第二个文本字段。我有一个带有文本字段的示例程序,它也可以工作,但根本不工作。 我不确定是否需要发布它,但我可以在这里获得完整程序的示例罐。我只发布了处理文本字段的区域 编辑:完整的源代码可在此处获得:GITHUB 我移除了一些东西,它成功了,我

  • 问题内容: 请看下面的代码。 在这里,我试图将字符数限制为5。好,当达到5时,它将不再插入任何字符,但实际情况是,它也不允许删除插入的字符,进行替换或其他操作。如何解决这个问题? 问题答案: 只需更改您当前的删除方法: 为此: 现在应该可以了。

  • 我需要一个React Native组件,它只允许输入数字字符(0-9)。我可以将设置为,这几乎可以让我在那里输入,除了句点()。但是,这并不能阻止将非数字字符粘贴到字段中。 到目前为止,我想出的是使用事件来查看输入的文本。我从文本中删除任何非数字字符。然后将文本放在状态字段中。然后通过它的值属性更新。代码片段如下。 这似乎工作,但它似乎像一个黑客。还有别的办法吗?

  • 问题内容: 我希望用户仅输入字母或空格(如果用户输入其他字符),我想给jOptionPane消息,我已经搜索过,并且尝试了以下代码 但是现在无论我输入什么都会给出错误 现在我更改了代码 现在它仅在用户输入数字时发出消息。我该如何解决 问题答案: 使用一个,这是我制作的一个示例,它将仅接受字母字符和空格: