应用了正则表达式的JTextField在文档应用之后才会接受值

时间:2015-03-01 06:31:43

标签: java regex swing numbers jtextfield

我有一个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()的值?

1 个答案:

答案 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);
    }
}

来自此DocumentFilter Examples

请查看Implementing a Document Filter了解详情

如果您不需要实时过滤,则另一种选择是使用JFormattedTextFieldJSpinner。有关详细信息,请参阅How to Use Formatted Text FieldsHow to Use Spinners