我的目的是设想掉屏蔽几个字母,比如不允许输入T,L,Z,J,S等字母,就想不能输入所有字母一样,查看网上资料简单介绍了几种方法。我首先的思路是监听按键,可是只能获取键值,不能将键值修改后再次传入消息队列,紧接着就试另外一种方法。每个JTextField都有一个文档类和其邦定,所以我换成监听文档,增加doc.addDocumnetListener()重载InsertUpdate(),
RemoveUpdate()和changeUpdate()等函数,我的方法是在InsertUpdate()函数中获取文本框的内容,判断后再次设置正确的,可是存在一个异常bug。我想可能是在设置文本框的内容时肯定也调用了上述函数,以致嵌套调用。当然我是菜鸟,没有办法得到验证。虽然可以运行,但是存在异常我还是有点担心,所以采取了另外一种办法。就是继承文档类,重载insertString()函数来建立新的文档类,同时继承文本框建立新的子类和新的文档类绑定。因为文本框的更新是通过文档类的insertString函数插入字符进去的。所以只要在insertString中判断合理的字符才允许插入,否则丢弃直接返回。因此我成功了,呵呵。举一反三,我也实现了密码框的同样功能。代码如下:
class JSpecField extends JTextField{
private static final long serialVersionUID = 1L;
public JSpecField(int size) {
super(size);
}
protected Document createDefaultModel(){
return new IntTextDocument();
}
}
class JSpecPwd extends JPasswordField{
private static final long serialVersionUID = 1L;
public JSpecPwd(int size) {
super(size);
}
protected Document createDefaultModel(){
return new IntTextDocument();
}
}
class IntTextDocument extends PlainDocument {//中写方法实现需求
private static final long serialVersionUID = 1L;
public void insertString(int offs, String str, AttributeSet a)
throws BadLocationException {
if (str == null){
return;
}
int length = str.length();
String des = "";
for(int i = 0; i < length; i++){
char c = str.charAt(i);
if(c == 'd'){
des += "m";
}
else if(c != 'm' && c != '-'){
des += c;
}
}
if(des.length() == 0){
return;
}
//String oldString = getText(0, getLength());
//String newString = oldString.substring(0, offs) + str
//+ oldString.substring(offs);
try {
//向Document中插入文本前判断
super.insertString(offs, des, a);
}
catch (NumberFormatException e) {
}
}
}