我有一个JTextField,我已经覆盖了Document,因此我可以阻止用户输入一些字符。它的工作方式是我的Document扩展在其构造函数中接收一个正则表达式,然后检查用户对正则表达式键入的任何内容:
public class ValidDocument extends PlainDocument
{
private String regex;
public ValidDocument(String regex)
{
this.regex = regex;
}
@Override
public void insertString(int offs, String str, AttributeSet a)
{
if(str == null) return;
try
{
if((this.getText(0, getLength()) + str).matches(regex))
super.insertString(offs, str, a);
}
catch(BadLocationException ble)
{
System.out.println("Came across a BadLocationException");
}
}
}
但是我遇到了一个问题,我想在其中只显示有效浮点数/双数的JTextField没有显示其初始值。我使用的代码如下:
float value = 25.0f;
JTextField textField = new JTextField("" + value);
textField.setDocument(new ValidDocument("^(\\-)?\\d*(\\.)?\\d*$"));
因此显示了JTextField,但没有初始值。我试图进入25.0进入该领域,它接受了我原先预期的那样。经过一些填充,我尝试添加:
textField.setText("" + value);
它显示了值。我突然意识到它可能接受我试图放入setText()的任何东西,所以我在其中添加了字母字符:
textField.setText("as" + value);
正如我所怀疑的那样,它包含了字母字符,即使正则表达式本应该阻止它。所以我的想法是在使用这个功能时绕过了Document。
任何人都可以解释为什么将ValidDocument应用于我的JTextField是删除我放置在文本字段的构造函数中的文本?我有其他JTextFields限制较少的正则表达式仍然显示我在构造函数中设置的值。为什么它会覆盖传递给构造函数的值,而不是传递给setText()的值?
答案 0 :(得分:1)
请勿使用PlainDocument
,请使用DocumentFilter
,这是它所要求的内容。您尝试使用的方法已超过10年,例如......
public class PatternFilter extends DocumentFilter {
// Useful for every kind of input validation !
// this is the insert pattern
// The pattern must contain all subpatterns so we can enter characters into a text component !
private Pattern pattern;
public PatternFilter(String pat) {
pattern = Pattern.compile(pat);
}
public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr)
throws BadLocationException {
String newStr = fb.getDocument().getText(0, fb.getDocument().getLength()) + string;
Matcher m = pattern.matcher(newStr);
if (m.matches()) {
super.insertString(fb, offset, string, attr);
} else {
}
}
public void replace(FilterBypass fb, int offset,
int length, String string, AttributeSet attr) throws
BadLocationException {
if (length > 0) fb.remove(offset, length);
insertString(fb, offset, string, attr);
}
}
请查看Implementing a Document Filter了解详情
如果您不需要实时过滤,则另一种选择是使用JFormattedTextField
或JSpinner
。有关详细信息,请参阅How to Use Formatted Text Fields和How to Use Spinners