JTextField限制字符数量input并仅接受数字
这里是我如何限制字符input长度的代码
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(new JTextFieldLimit(30));
这里是我只接受数字数字(它接受小数,虽然w / ci不需要)
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; } } } }
和inheritance人如何使用此代码: txtSample.setDocument(new NumericDocument(0,false));
现在的问题是txtSample
只能设置一次setDocument
。 我如何限制一个jtextfield长度,并只接受数字只在同一时间? 还是有更简单的方法来做到这一点? 谢谢。 :d
你在正确的轨道上,除了你会想要使用DocumentFilter而不是实现自己的文档。
MDP的博客有许多优秀的例子(包括限制长度和字符types)。
现在到你的问题,你可以创build级联filter,在那里你可以链接一系列的filter。
这将允许您依次调用每个筛选器。
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); } } }
现在如果filter实际上能够告诉链条是否改变了文档,那就好了,但是我会把它留给你
更新
你所做的和DocumentFilters
工作方式基本相同。 好处是,您不是将自己限制在PlainDocument
,理论上可以将其应用于JTextPane
或JEditorPane
。
过滤链的基本思想很简单。
ChainableFilter chainableFilter = new ChainableFilter(); chainableFilter.addFilter(new RestrictedLengthFilter()); // User supplied filter chainableFilter.addFilter(new NumericFilter()); // User supplied filter ((AbstractDocument)textField.getDocument()).setDocumentFilter(chainableFilter);
至于实际的filter,我会检查我之前发布的链接。 尽pipe如此,你的思路是正确的
更新
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(); } } }
再次,我知道它编译,但我没有testing它(特别是数字filter),但这将是一个很好的练习,在debugging;)
的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将被调用
新的PropertyChangeEvent(“价值”,整数oldValue,整数newValue)
(oldValue或newValue在文本情况下将为空)
在每一个有效的编辑
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 } } }); } }
public static boolean validateInt(String txt) { String regx = "^[(0-9),;]+$"; Pattern pattern = Pattern.compile(regx, Pattern.CASE_INSENSITIVE); Matcher matcher = pattern.matcher(txt); boolean b = matcher.find(); return b; }
我目前正在用一个数独解算器开发一个小型项目。 我通过检查input是否在string数组中,将input限制为只有数字。 我直接写在JTextFieldLimit。
class JTextFieldLimit extends PlainDocument { private int limit; //Added the following 2 lines String[] numbers = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}; boolean isAccepted = false; // JTextFieldLimit(int limit) { super(); this.limit = limit; } public void insertString(int offset, String str, AttributeSet attr) throws BadLocationException { if (str == null) return; //And the following 2 lines for (String thisnumber : numbers) { isAccepted = str.equals(thisnumber); if (isAccepted) { // if ((getLength() + str.length()) <= limit) { super.insertString(offset, str, attr); } } } } }
import java.awt.Component; import java.awt.KeyboardFocusManager; import java.awt.event.KeyEvent; import javax.swing.JTextField; import javax.swing.KeyStroke; import javax.swing.SwingUtilities; import javax.swing.text.AbstractDocument; import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; import javax.swing.text.Document; import javax.swing.text.DocumentFilter; import javax.swing.text.JTextComponent; import org.apache.commons.lang.StringUtils; public class NumberTextField extends JTextField { protected int maxlength = 0; public NumberTextField() { this(10); } public NumberTextField(int length) { super(); this.maxlength = length; initializeForNumbers(); } public void setMaxLength(int length) { this.maxlength = length; } protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed) { int keyCode = e.getKeyCode(); if (keyCode == KeyEvent.VK_ENTER || keyCode == KeyEvent.VK_ESCAPE) { return false; } return super.processKeyBinding(ks, e, condition, pressed); } private void initializeForNumbers() { Document document = getDocument(); if (document != null) { ((AbstractDocument) document).setDocumentFilter(new DocumentHandler()); } } private class DocumentHandler extends DocumentFilter { public void insertString(DocumentFilter.FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException { if (string == null) { return; } else { replace(fb, offset, 0, string, attr); } } public void remove(DocumentFilter.FilterBypass fb, int offset, int length) throws BadLocationException { replace(fb, offset, length, "", null); } public void replace(final DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException { Document doc = fb.getDocument(); int currentLength = doc.getLength(); String currentContent = doc.getText(0, currentLength); String before = currentContent.substring(0, offset); String after = currentContent.substring(length + offset, currentLength); String newValue = before + (text == null ? "" : text) + after; if (newValue.length() > maxlength) { return; } else { checkInput(newValue, offset); fb.replace(offset, length, text, attrs); if (doc.getLength() >= maxlength) { SwingUtilities.invokeLater(new Runnable() { public void run() { Component c = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); if (c != null && c instanceof JTextComponent) { JTextComponent component = (JTextComponent) c; Document compDoc = component.getDocument(); if (compDoc.equals(fb.getDocument())) { KeyboardFocusManager.getCurrentKeyboardFocusManager().focusNextComponent(); } } } }); return; } } } private void checkInput(String proposedValue, int offset) throws BadLocationException { if (proposedValue.length() > 0 && !StringUtils.isNumeric(proposedValue)) { throw new BadLocationException( proposedValue, offset); } } } }
yourJTextField.addKeyListener(new KeyAdapter() { @Override public void keyTyped(KeyEvent e) { // Here limiting the character of your number. for examlpe this wil only accept one digit if (yourJTextField.getText().length() == 1) { e.consume(); } // Here limiting your input to only number char c = e.getKeyChar(); if(!((c >= '0') && (c <= '7') || (c == KeyEvent.VK_BACK_SPACE) || (c == KeyEvent.VK_DELETE))) { //do what so ever you want } else { //do what so ever you want } } })