转自 http://hi.baidu.com/zhjie_space/blog/item/ca7634339c298bfe1a4cffee.html
2008-08-19 23:54
在使用 Swing的JTextField时,我们常常希望只接受那些符合我们要求的录入,如数字、电话号码、邮政编码、E-mail等。JFC工作组在这方面也做了很多工作,每一次新的Java Se发布,往往都提供了新的、更方便和强大的有效性验证方式,在这里列举几种不同的验证方式。
这是最直觉的方式。利用 KeyListener来选择允许的字符,且添加FocusListener,使得
内容不符合要求时不允许焦点转移。这种方式很繁琐, Sun的建议是不推荐使用这种方式。
我们知道, Swing组件是基于MVC实现的。JTextComponent的Model是一个叫做Document的Interface,我们可以通过限制Document的内容来达到有效性验证的目的。javax.swing.text包中有多个不同的Document的实现,JTextField使用的是PlainDocument。如果我们希望JTextField只接受数字,可以实现我们特定的Document并使之替换默认的Document:
package sdn;
import javax.swing.text.*;
public class IntegerDocument extends PlainDocument {
int currentValue = 0;
public int getValue() {
return currentValue;
}
public void insertString(int offset, String string,
AttributeSet attributes) throws BadLocationException {
if (string == null) {
return;
} else {
String newValue;
int length = getLength();
if (length == 0) {
newValue = string;
} else {
String currentContent = getText(0, length);
StringBuffer currentBuffer =
new StringBuffer(currentContent);
currentBuffer.insert(offset, string);
newValue = currentBuffer.toString();
}
currentValue = checkInput(newValue, offset);
super.insertString(offset, string, attributes);
}
}
public void remove(int offset, int length)
throws BadLocationException {
int currentLength = getLength();
String currentContent = getText(0, currentLength);
String before = currentContent.substring(0, offset);
String after = currentContent.substring(length+offset,
currentLength);
String newValue = before + after;
currentValue = checkInput(newValue, offset);
super.remove(offset, length);
}
public int checkInput(String proposedValue, int offset)
throws BadLocationException {
if (proposedValue.length() > 0) {
try {
int newValue = Integer.parseInt(proposedValue);
return newValue;
} catch (NumberFormatException e) {
throw new BadLocationException(proposedValue, offset);
}
} else {
return 0;
}
}
}
然后用 IntegerDocument去替换JTextField默认的Document:
package sdn;
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.*;
public class NumericInput {
public static void main(String args[]) {
Runnable runner = new Runnable() {
public void run() {
JFrame frame = new JFrame("Numeric Input");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(2, 2));
frame.add(new JLabel("Number"));
JTextField fieldOne = new JTextField();
Document doc= new IntegerDocument();
fieldOne.setDocument(doc);
frame.add(fieldOne);
frame.add(new JLabel("All"));
JTextField fieldTwo = new JTextField();
frame.add(fieldTwo);
frame.setSize(250, 90);
frame.setVisible(true);
}
};
EventQueue.invokeLater(runner);
}
}
代码很简单,一目了然。这里说点题外话, Sun建议的Swing Application的main函数写法如上所示:先建一个Runnable,然后把这个Runnable放到event-dispatch thread中去执行。另外,以前有的Developer(比如我)喜欢用SwingUtilities.invokeLater(runner)来将一个thread放到event-dispatch thread中,现在Sun也建议用EventQueue.invokeLater(runner),因为SwingUtilities方法版本仅仅是对EventQueue方法版本的一个包装。
在 J2SE 1.3中加入了一个名为InputVerifier的抽象类,可用于任何JComponent。其中定义了boolean verifiy(JComponent input)方法。如果组件中的文本是有效的,当焦点转移时(如按下Tab或Shift-Tab),verify方法返回true;否则返回false,使得焦点仍停留在当前组件上。我们仍以数字为例:
package sdn;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class NumericVerifier{
public static void main(String args[]) {
Runnable runner = new Runnable() {
public void run() {
JFrame frame = new JFrame("Numeric Verifier");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel1 = new JPanel(new BorderLayout());
JLabel label1 = new JLabel("Numeric-only");
JTextField textField1 = new JTextField();
panel1.add(label1, BorderLayout.WEST);
panel1.add(textField1, BorderLayout.CENTER);
JPanel panel2 = new JPanel(new BorderLayout());
JLabel label2 = new JLabel("Anything");
JTextField textField2 = new JTextField();
panel2.add(label2, BorderLayout.WEST);
panel2.add(textField2, BorderLayout.CENTER);
JPanel panel3 = new JPanel(new BorderLayout());
JLabel label3 = new JLabel("Numeric-only");
JTextField textField3 = new JTextField();
panel3.add(label3, BorderLayout.WEST);
panel3.add(textField3, BorderLayout.CENTER);
InputVerifier verifier = new InputVerifier() {
public boolean verify(JComponent comp) {
boolean returnValue;
JTextField textField = (JTextField)comp;
try {
Integer.parseInt(textField.getText());
returnValue = true;
} catch (NumberFormatException e) {
Toolkit.getDefaultToolkit().beep();
returnValue = false;
}
return returnValue;
}
};
textField1.setInputVerifier(verifier);
textField3.setInputVerifier(verifier);
frame.add(panel1, BorderLayout.NORTH);
frame.add(panel2, BorderLayout.CENTER);
frame.add(panel3, BorderLayout.SOUTH);
frame.setSize(300, 95);
frame.setVisible(true);
}
};
EventQueue.invokeLater(runner);
}
}
这个例子的效果和上一个是不同的。自定义 Document的App中,用户将会发现任何非数字的字符都不会在JTextField中出现;而在使用InputVerifier的App中,用户在录入字符时不会发现任何异常,但是当他确认录入完成后,如果内容不符合有效性,焦点将不会转移!这两种情况都可能让一个没有经验的用户茫然,具体使用哪一种是一个见仁见智的问题。
在 J2SE 1.4中,又加入了一个新的类:DocumentFilter。你无需再实现一个新的Document,而是对现有的Document过滤一遍。它的结果与实现自定义的Document并无二样,仅仅是思路不同而已。
package snd;
import javax.swing.text.*;
import java.awt.Toolkit;
public class IntegerDocumentFilter extends DocumentFilter {
int currentValue = 0;
public IntegerDocumentFilter() {
}
public void insertString(DocumentFilter.FilterBypass fb,
int offset, String string, AttributeSet attr)
throws BadLocationException {
if (string == null) {
return;
} else {
replace(fb, offset, 0, string, attr);
}
}
public void remove(DocumentFilter.FilterBypass fb,
int offset, int length)
throws BadLocationException {
replace(fb, offset, length, "", null);
}
public void replace(DocumentFilter.FilterBypass fb,
int offset, int length, String text, AttributeSet attrs)
throws BadLocationException {
Document doc = fb.getDocument();
int currentLength = doc.getLength();
String currentContent = doc.getText(0, currentLength);
String before = currentContent.substring(0, offset);
String after = currentContent.substring(
length+offset, currentLength);
String newValue = before +
(text == null ? "" : text) + after;
currentValue = checkInput(newValue, offset);
fb.replace(offset, length, text, attrs);
}
private int checkInput(String proposedValue, int offset)
throws BadLocationException {
int newValue = 0;
if (proposedValue.length() > 0) {
try {
newValue = Integer.parseInt(proposedValue);
} catch (NumberFormatException e) {
throw new BadLocationException(
proposedValue, offset);
}
}
return newValue;
}
}
再将这个 Filter应用于Document:
package sdn;
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
public class NumericInputFilter {
public static void main(String args[]) {
Runnable runner = new Runnable() {
public void run() {
JFrame frame = new JFrame("Numeric Input Filter");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(2, 2));
frame.add(new JLabel("Number"));
JTextField textFieldOne = new JTextField();
Document doc= textFieldOne.getDocument();
DocumentFilter filterOne = new IntegerDocumentFilter();
((AbstractDocument)doc).setDocumentFilter(filterOne);
textFieldOne.setDocument(doc);
frame.add(textFieldOne);
frame.add(new JLabel("All"));
JTextField textFieldTwo = new JTextField();
frame.add(textFieldTwo);
frame.setSize(250, 90);
frame.setVisible(true);
}
};
EventQueue.invokeLater(runner);
}
}
DocumentFilter只能用于Swing中的与text有关的组件(而InputVerifier可用于任何组件)。除了这几种方法,在对于TextField而言,我们还有JFormattedTextField,很多时候用JFormattedTextField将是非常容易和简单的方式。
分享到:
相关推荐
对JTextField限制只能输入数字,且在0至999范围内
i = jTextField1.getText().length(); Highlighter hilite = jTextArea1.getHighlighter();//获取负责进行高亮显示的对象 //Highlighter:一个允许用户用带有颜色的区域标出背景的对象接口 for (f = 0; f (); f++...
JTextField添加“自动完成”,代码简单强大
JTextField_Example.java
java JTextField组件的使用 java JTextField组件的使用 java JTextField组件的使用
实现圆角矩形边框,hint文字,主要代码: ... JTextField textField = (JTextField) c; if ("".equals(textField.getText())) { g2d.setColor(Color.BLACK); g2d.drawString("请输入文字...", 10, 18); }
原创:java封装了的JTextField,可以达到google输入框的效果:在输入框中输入一些字符即可联想。
NULL 博文链接:https://alog2012.iteye.com/blog/1628396
Text_JTextField.class
扩展JTextField功能,使之能在输入一段字符后弹出下拉列表,在集合中匹配相似的信息,辅助完成整个输入,效果类似在订机票时输入目的地时辅助输入的形式.可在JTable中使用
在完成Swing的学习后,练习使用Swing包中JFrame、JButton、JLabel、JTextField、JMenu、JMenuItem等组件完成图形界面绘制。 前期能够独立思考并完成计算器的逻辑代码。 熟练使用JButton、JTextField、JLabel等...
JTextField是Java Swing库中的一个组件类,用于接收用户的文本输入。
文本框输入不合理数据时进行验证.rar文本框输入不合理数据时进行验证.rar
JTextField jurl=new JTextField(60); JEditorPane jEditorPanel=new JEditorPane(); JScrollPane scrollPane=new JScrollPane(jEditorPanel); // JWindow window=new JWindow(WebBrowser.this); // Toolkit ...
NULL 博文链接:https://zhangqkunkun.iteye.com/blog/815897
使JTextField与条形码扫描仪兼容的代码。 它可以用作常规的JTextField,但是当它检测到输入来自条形码扫描仪时,它将转换输入并触发事件。 Convertint输入表示将字符&é“((§è!çà)分别转换为1234567890。...
主要介绍了Java Swing JTextField文本框的代码示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
我想给您的文本增加一点...您可以禁用JTextField:JTextField oText = new JTextField(); oText.setEnable(false);它将不接受任何此类输入。如何使用TextFields [^] EDIT:有点棘手-函数setEnable(boolean)是...
主要介绍了Java Swing中的文本框(JTextField)与文本区(JTextArea)使用实例,Swing是一个用于开发Java应用程序用户界面的开发工具包,需要的朋友可以参考下
实验目的及要求 1) 掌握JFrame的基本用法 2) 掌握基本图形的绘制,...3)使用边缘布局管理器和流式布局管理器和几种基本的Swing组件包括:JLabel,JTextField,JPassword,JButton,JCheckBox等,来设计一个登陆界面;