lishankang

博客园 首页 新随笔 联系 订阅 管理

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应用,请看下一文总结。 

 

posted on 2013-03-14 17:07  havedrop  阅读(1810)  评论(0编辑  收藏  举报