JtextField作为Jswing的输入框,里面可以输入任何值,如果有时我们要限制用户的输入,比如保留几位小数点时,就必须加Listener, 在listener中利用getText()获取一个String,再将String转换为某种数据对象进行判断,利用setText()进行值的设定,这样就比较麻烦。
Java还为我们提供了一个直接进行input的内容检测的的输入框------JformattedTextField,的内在机制是可以将字符串自动转化为相应的数据对象,你既可以通过getText得到字符串,也可以通过getValue方法得到转化后的数据对象(该对象是一个Object对象,还需要强制转化一下),并且内部已经进行了格式的判断。
一 JformattedTextField的构造函数:
1 public JFormattedTextField() ;
2 public JFormattedTextField(Object value);
3 public JFormattedTextField(java.text.Format format);
4 public JFormattedTextField(AbstractFormatter formatter);
5 public JFormattedTextField(AbstractFormatterFactory factory);
对于第三和第四个构造函数:
public JFormattedTextField(NumberFormat/DateFormat)
或者public JFormattedTextField(NumberFormatter/DateFormatter),其中NumberFormatter的构造函数NumberFormatter(NumberFormat), DateFormatter(DateFormat),所以最终的格式还是由NumberFormat/DateFormat来确定,这两个构造函数是一回事。
二 对日期和时间的格式化输入
NumberFormat numberFormat = NumberFormat.getInstance(); numberFormat.setMinimumIntegerDigits(1); numberFormat.setMaximumIntegerDigits(3); JFormattedTextField numberField = new JFormattedTextField(numberFormat);
这段代码实现的是一个要求输入的整数位的位数最少是1位,最多是3位,如果多于3位的话,从后输入的取3位; 注意: 这只是整数位数,对于小数点后面的没有限制;如果输入非数值字符,离开焦点时候自动去除。
numberField.setFocusLostBehavior(JFormattedTextField.COMMIT)
如果不加这个方法,比如本来的值是123,你输入abc离开焦点后,显示的是123;增加改方法后,离开焦点显示的就是abc,但是getText()的值还是123。
numberField.setInputVerifier(new FormattedTextFieldVerifier()); 其中: import javax.swing.InputVerifier; import javax.swing.JComponent; import javax.swing.JFormattedTextField; class FormattedTextFieldVerifier extends InputVerifier{ public boolean verify(JComponent component) { JFormattedTextField field = (JFormattedTextField) component; //若用户的输入符合格式,则返回true,否则返回false return field.isEditValid(); } }
JformattedTextField还提供了输入校验,当输入1234,离开焦点后会显示234,因为1234都是数值,满足数值校验条件;但是当输入的是abc时,就不会失去焦点。
import javax.swing.InputVerifier; import javax.swing.JComponent; import javax.swing.JFormattedTextField; class FormattedTextFieldVerifier extends InputVerifier { public boolean verify(JComponent component) { JFormattedTextField field = (JFormattedTextField) component; //若用户的输入符合格式,则返回true,否则返回false if (!field.isEditValid()) { return false; } String fieldstrString = field.getText(); //Object object = field.getValue(); int index = Integer.parseInt(fieldstrString); if (index >=100) { return false; } return true; } }
这样更改后,当输入超过100的数值时也不会失去焦点。 注意: 这里用的是getText, 不是getValue, 因为当失去焦点时,JformattedTextField会进行格式校验,用getText取到的是现在里面填写的值,getValue取到的是以前里面填写的值,比如,以前是12, 改为234, 失去焦点时,getText获得的值是234,getValue获得值是12。
但是很遗憾,JformattedTextField没有提供当输入错误时候,在该文本框后面显示一个红叉的功能,所以,如果要实现此功能,只能在JformattedTextField后面加个JLable,并且增加失去焦点监听,如果错误,将JLable的图标显示成红叉,如果正确,图标不显示。
也可以对JformattedTextField进行禁止输入非法字符的操作,比如,要求输入数值,你输入的是字母,就不会输入进去。这个要用新的过滤器来替代JformattedTextField中格式的过滤器,所以要重载两个方法,insertString, Replace方法,在这两个方法中把禁止输入的非法字符过滤掉。
见一下引用文档:
http://blog.csdn.net/mylxiaoyi/article/details/8007261
DocumentFilter是一个类,而不是接口,所以我们必须创建一个该类的子类来过滤文本组件的文档的输入。如果我们创建一个DocumentFilter的子类,重写下面三个方法可以使得我们自定义输入:
• public void insertString(DocumentFilter.FilterBypass fb, int offset, String string, AttributeSet attributes): 当一个文本字符串被插入到文档中时调用。
• public void remove(DocumentFilter.FilterBypass fb, int offset, int length): 当某些内容被选中时调用。
• public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs): 当某些内容被插入到当前被选中的文本中时调用。
要限制输入,只需要覆盖每一个方法并且检测新内容是否合法。如果内容不合法,则拒绝。
见http://blog.sina.com.cn/s/blog_412ef3420101aoqe.html中的代码(本文的很多思想都参考该文章)
//用自定义的DocumentFilter替换格式类中默认的DocumentFilter JFormattedTextField intField3 = new JFormattedTextField( new InternationalFormatter(NumberFormat.getIntegerInstance()) { protected DocumentFilter getDocumentFilter() { return filter; } private DocumentFilter filter = new IntFilter(); }); //自定义一个DocumentFilter类 class IntFilter extends DocumentFilter { //重载insertString方法 public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException { StringBuilder builder = new StringBuilder(string); for (int i = builder.length() - 1; i >= 0; i--) { int cp = builder.codePointAt(i); if (!Character.isDigit(cp) && cp != '-') { builder.deleteCharAt(i); if (Character.isSupplementaryCodePoint(cp)) { i--; builder.deleteCharAt(i); } } } super.insertString(fb, offset, builder.toString(), attr); } //重载replace方法 public void replace(FilterBypass fb, int offset, int length, String string, AttributeSet attr) throws BadLocationException { if (string != null) { StringBuilder builder = new StringBuilder(string); for (int i = builder.length() - 1; i >= 0; i--) { int cp = builder.codePointAt(i); if (!Character.isDigit(cp) && cp != '-') { builder.deleteCharAt(i); if (Character.isSupplementaryCodePoint(cp)) { i--; builder.deleteCharAt(i); } } } string = builder.toString(); } super.replace(fb, offset, length, string, attr); } }
关于JformattedTextField的MaskFormatter应用,请看下一文总结。