我正在开发一个使用JTextField让用户输入电话号码的Swing应用程序。为安全起见,当用户键入电话号码时,中间的四位数字需要显示为通配符。同时,当电话号码来自数据库时,此JTextField还将中间的四位数字显示为通配符。
如何自定义JTextField?任何帮助都是非常感谢的。
发布于 2013-06-30 10:01:22
使用DocumentFilter
。
查看此示例,只需根据需要更改new PhoneNumberFilter(6,10,'*')
即可。
F.I南非有10位数字的电话号码,前3位是拨号代码,其余的是唯一的号码。
因此,如果希望最后4位用*进行掩码,而整个电话号码是10位,我会执行new PhoneNumberFilter(6,10,'*')
来标记最后4位(10-6=4)。
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;
import javax.swing.text.DocumentFilter.FilterBypass;
public class Test {
public Test() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
//create instance of our custom DocumentFiler class
PhoneNumberFilter phoneNumberFilter = new PhoneNumberFilter(6, 10, '*');
JTextField jtf = new JTextField(10);
//add filter to JTextField
((AbstractDocument) jtf.getDocument()).setDocumentFilter(phoneNumberFilter);
frame.add(jtf);
frame.pack();
frame.setVisible(true);
//jtf.setText("0119887654");
}
});
}
public static void main(String[] args) {
new Test();
}
}
class PhoneNumberFilter extends DocumentFilter {
private int textLength = 0;//keeps track of length of text within the field (used to check if we should start applying the mask)
private int numberMaskStartIndex;
private int numberMaskEndIndex;
private String mask;//what the characters in the specified ranges positions will be replaced with
public PhoneNumberFilter(int start, int end, char mask) {
numberMaskStartIndex = start;
numberMaskEndIndex = end - 1;
this.mask = String.valueOf(mask);
}
@Override
public void replace(FilterBypass fb, int i, int i1, String string, AttributeSet as) throws BadLocationException {
if (string.length() > 1) {
for (int n = string.length() - 1; n >= 0; n--) {//an inserted string may be more than a single character i.e copy and pasting a number
char c = string.charAt(n);//get a single character of the string
if (n >= numberMaskStartIndex && n <= numberMaskEndIndex) {//check if its between the range which we should mask
super.replace(fb, i, i1, mask, as);
} else {
super.replace(fb, i, i1, String.valueOf(c), as);
}
textLength++;
}
} else if (textLength >= numberMaskStartIndex && textLength <= numberMaskEndIndex) {//only a singe character was inserted and its between the range which we should mask
super.replace(fb, i, i1, mask, as);
textLength++;
} else {
super.replace(fb, i, i1, string, as);
textLength++;
}
}
@Override
public void remove(FilterBypass fb, int i, int i1) throws BadLocationException {
super.remove(fb, i, i1);
if (i == 0 && i1 == textLength) {//if the text removed is the entire textfield i.e CTRL+A or Mouse dragged and DEL than we reset our counter which keeps track of the number of characters in the textfield
textLength = 0;
} else {//only a single character was deleted
textLength--;
}
}
@Override
public void insertString(FilterBypass fb, int i, String string, AttributeSet as) throws BadLocationException {
super.insertString(fb, i, string, as);
}
}
我没有添加限制用户输入的功能,因此可以输入任何内容,上面更多的是为了显示以下所需的逻辑:
为安全起见,当用户输入电话号码时,中间的四位数需要显示为通配符。同时,当电话号码来自数据库时,此JTextField还会将中间的四位数显示为通配符
您可能仍然会问,从数据库获取时,它是否可以工作?是的,因为DocumentFilter也适用于setText(..);
https://stackoverflow.com/questions/17385881
复制相似问题