应用了正则表达式的JTextField在应用文档之后才接受值 [英] JTextField with regex applied won't accept value until AFTER the Document is applied

查看:96
本文介绍了应用了正则表达式的JTextField在应用文档之后才接受值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个JTextField,我已经为其重写了Document,以便可以防止用户输入某些字符.这种工作方式是我的Document扩展在其构造函数中接收一个Regex,然后根据Regex检查用户键入的任何内容:

I have a JTextField that I have overridden the Document for, so that I can prevent the user from entering some characters. The way this works is my extension of Document receives a Regex in its constructor, then checks anything the user types against the Regex:

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没有显示其初始值.我正在使用的代码如下:

I had an issue however, where a JTextField that I wanted to display only valid float/double numbers in wasn't displaying its initial value. The code I was using is below:

float value = 25.0f;
JTextField textField = new JTextField("" + value);
textField.setDocument(new ValidDocument("^(\\-)?\\d*(\\.)?\\d*$"));

因此显示了JTextField,但是没有初始值.我尝试在该字段中输入25.0,它接受了我最初期望的值.经过一番充实之后,我尝试添加:

So the JTextField displayed, but there was no initial value. I tried to enter 25.0 into the field and it accepted it I had originally expected it would. After a bit of stuffing around, I tried adding:

textField.setText("" + value);

它显示了值.在我看来,它可以接受我尝试放入setText()中的任何内容,因此我向其中添加了字母字符:

And it displayed the value. It occurred to me that it might accept anything I tried to put in setText(), so I added alphabetic characters to it:

textField.setText("as" + value);

正如我所怀疑的那样,尽管正则表达式本来可以防止这种情况,但其中包含字母字符.因此,我的想法是使用此功能时会绕过文档.

As I suspected, it included the alphabetic characters, even though the Regex should have prevented that. So my thoughts are that the Document is bypassed when using this function.

谁能阐明为什么将ValidDocument应用于我的JTextField会删除放置在文本字段构造函数中的文本?我还有其他JTextField,它们的Regex限制较少,但仍显示我在构造函数中设置的值.为什么要覆盖传递给构造函数的值,而不是传递给setText()的值呢?

Can anyone shed some light on why applying the ValidDocument to my JTextField is removing the text I placed in the constructor of the text field? I have other JTextFields with less restrictive Regex's that still display the value I set in the constructor. And why would it be overriding the value passed into the constructor, but not the one passed into setText()?

推荐答案

不要使用PlainDocument,请使用DocumentFilter,这就是它的用途.您尝试使用的方法已过期10多年了,例如...

Don't use PlainDocument, use a DocumentFilter, it's what it is deisnged for. The method you're attempting to use has been out of date for more than 10 years, for example...

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示例

看看实现文档过滤器了解更多详情

如果不需要实时过滤,另一种选择是使用JFormattedTextFieldJSpinner.请参见如何使用带格式的文本字段

If you don't need real time filtering, another option would be to use a JFormattedTextField or JSpinner. See How to Use Formatted Text Fields and How to Use Spinners for more details

这篇关于应用了正则表达式的JTextField在应用文档之后才接受值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆