package textfield;
/*
* 此程序使用JAVA标准控件JFormattedTextField
* 它与JTextField一样,只是多了对输入文本的验证功能
* 程序例子对IP与端口号进行验证,若用户的输入不能通过
* 验证,程序将不能继续进行.
* 参考<<JAVA核心技术卷1>>
*/
import java.awt.Font;
import java.awt.GridLayout;
import java.text.ParseException;
import java.util.StringTokenizer;
import javax.swing.InputVerifier;
import javax.swing.JComponent;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultFormatter;
import javax.swing.text.DocumentFilter;
public class TextVerifier extends JFrame {
private JFormattedTextField ipTf = null;
private JFormattedTextField portTf = null;
private JLabel ipLb = null;
private JLabel portLb = null;
private JPanel p = null;
public TextVerifier() {
p =new JPanel();
p.setLayout(new GridLayout(2,2,1,1));
Font font = new Font("/u65b0/u5b8b/u4f53", Font.PLAIN, 12);
ipLb = new JLabel("IP地址:");
ipLb.setFont(font);
ipTf = new JFormattedTextField(new IPAddressFormatter());
ipTf.setInputVerifier(new IPAddressVerifier());
ipTf.setValue(new byte[] { (byte) 192, (byte) 168, 0, (byte) 156 });
ipTf.setEditable(true);
ipTf.setFont(font);
portLb = new JLabel("端口:");
portLb.setFont(font);
portTf = new JFormattedTextField(new DefaultFormatter() {
private DocumentFilter filter = new PortFilter();
protected DocumentFilter getDocumentFilter() {
return filter;
}
});
portTf.setInputVerifier(new PortVerifier());
portTf.setEditable(true);
portTf.setFont(font);
p.add(ipLb);
p.add(ipTf);
p.add(portLb);
p.add(portTf);
add(p);
}
/**
* IP地址文本域的验证器
*/
class IPAddressVerifier extends InputVerifier {
private boolean b = false;
@Override
public boolean verify(JComponent component) {
// TODO Auto-generated method stub
JFormattedTextField field = (JFormattedTextField) component;
b = field.isEditValid();
System.out.println(b);
if (b == false) {
String opt = new String("确定");
Object[] options = { "确定" };
JOptionPane.showOptionDialog(null, "IP地址输入有误请重新输入", "警告",
JOptionPane.DEFAULT_OPTION,
JOptionPane.WARNING_MESSAGE, null, options, options[0]);
field.setText(null);
}
return field.isEditValid();
}
}
/**
* IP地址文本域的过滤器
*/
class IPAddressFormatter extends DefaultFormatter {
public String valueToString(Object value) throws ParseException {
if (!(value instanceof byte[])) {
throw new ParseException("Not a byte[]", 0);
}
byte[] a = (byte[]) value;
if (a.length != 4)
throw new ParseException("Length!=4", 0);
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 4; i++) {
int b = a[i];
if (b < 0)
b += 256;
builder.append(String.valueOf(b));
if (i < 3)
builder.append('.');
}
return builder.toString();
}
public Object stringToValue(String text) throws ParseException {
StringTokenizer tokenizer = new StringTokenizer(text, ".");
byte[] a = new byte[4];
for (int i = 0; i < 4; i++) {
int b = 0;
if (!tokenizer.hasMoreElements()) {
System.out.println("few");
throw new ParseException("Too few bytes", 0);
}
try {
b = Integer.parseInt(tokenizer.nextToken());
} catch (NumberFormatException e) {
throw new ParseException("Not an integer", 0);
}
if (b < 0 || b >= 256)
throw new ParseException("Byte out of range", 0);
a[i] = (byte) b;
}
if (tokenizer.hasMoreElements())
throw new ParseException("Too many bytes", 0);
return a;
}
}
/**
* 端口文本框过滤器类
*/
class PortFilter extends DocumentFilter {
/*
* public void insertString(FilterBypass fb,int offset,String string,
* javax.swing.text.AttributeSet attr)throws BadLocationException{
* System.out.println("InsertString"); StringBuilder builder = new
* StringBuilder(string); for(int i=builder.length()-1;i>=0;i--){ int
* cp=builder.codePointAt(i); if(!Character.isDigit(cp)){
* builder.deleteCharAt(i); if(Character.isSupplementaryCodePoint(cp)){
* i--; builder.deleteCharAt(i); }
*
*
* } } System.out.println("InsertString"); super.insertString(fb,
* offset, builder.toString(), attr); }
*/
public void replace(FilterBypass fb, int offset, int length,
String string, AttributeSet attr) throws BadLocationException {
System.out.println("replace");
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)) {
builder.deleteCharAt(i);
if (Character.isSupplementaryCodePoint(cp)) {
i--;
builder.deleteCharAt(i);
}
}
}
string = builder.toString();
}
super.replace(fb, offset, length, string, attr);
}
}
/**
* 端口文本框验证器类
*/
class PortVerifier extends InputVerifier {
private boolean b = false;
@Override
public boolean verify(JComponent component) {
// TODO Auto-generated method stub
JFormattedTextField field = (JFormattedTextField) component;
b = field.isEditValid();
if (b == true) {
try {
int n = Integer.parseInt(field.getText());
if (n < 1024 || n > 65535) {
Object[] options = { "确定" };
JOptionPane.showOptionDialog(null,
"端口必须在1024-65535之间,请重新输入!", "Warning",
JOptionPane.DEFAULT_OPTION,
JOptionPane.WARNING_MESSAGE, null, options,
options[0]);
field.setText("");
b = false;
}
} catch (NumberFormatException e) {
// 如果输入的字符串在转换为整数时超出整数范围由此异常处理
Object[] options = { "确定" };
JOptionPane.showOptionDialog(null,
"端口必须在1024-65535之间,请重新输入!", "Warning",
JOptionPane.DEFAULT_OPTION,
JOptionPane.WARNING_MESSAGE, null, options,
options[0]);
field.setText("");
b = false;
}
}
return b;
}
}
public static void main(String[] args) {
TextVerifier frame = new TextVerifier();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 200);
frame.setVisible(true);
}
}