JTextField,使用文档过滤器过滤整数和句点

Joa*_*tos 5 java swing jtextfield documentfilter

编辑 - 在帖子的最后添加了我们能够实现的答案

这是我在SO的第一篇文章,所以我希望我可以问一切正确!

尽管发布了类似的问题,我搜索并没有找到我的问题的答案,所以我希望这不是转贴.

这就是ai得到的,一个JTextField用于接收用户输入的小应用程序,除此之外我还有一个DocumentFilter用户只能输入整数和句点以便接收代表重量的值.

我的问题是,我的DocumentFilter我无法过滤"复制粘贴"文本,我无法过滤选定的文本删除.

这是Filter的代码

import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;

/**
* The Class IntAndDotFilter.
*/
public class IntAndDotFilter extends DocumentFilter {

/** The period counter. */
private int periodCounter = 0;

/** The number counter. */
private int numberCounter = 0;

private boolean canRemove = true;

public void setCanRemove(boolean canRemove) {
    this.canRemove = canRemove;
}

@Override
public void replace(FilterBypass fb, int offset, int length, String text,
        AttributeSet attrs) throws BadLocationException {

    if (periodCounter == 0) { // If there is no . on the text
        if (text.matches("\\.")) { // Checks if the input is a dot
            super.replace(fb, offset, length,
                    text.replaceAll("[^0-9.]", ""), attrs);
            periodCounter++; // If it is, inserts it and saves that info
        } else {
            super.replace(fb, offset, length,
                    text.replaceAll("[^0-9]", ""), attrs);
            // If not, checks if the input is a digit
            // and inserts if it is
        }
    } else { // If there is already a .
        if (text.matches("\\.")) { // Checks if the input is another .
            super.replace(fb, offset, length,
                    text.replaceAll("[^0-9]", ""), attrs);
            // If it is, filters so that cannot be more than one .
        } else {
            if (text.matches("[0-9]")) { // Checks if it's a digit
                if (numberCounter != 2) {
                    super.replace(fb, offset, length,
                            text.replaceAll("[^0-9]", ""), attrs);
                    numberCounter++;
                    // If yes, and if that is only the second one (0.00)
                    // inserts and
                    // saves the info that there are digits after the 1st .
                    // for removal purposes
                } else {
                    super.replace(fb, offset, length,
                            text.replaceAll(".", ""), attrs);
                    // if it is the third+ digit after . , doesn't allow the
                    // input
                }
            } else {
                super.replace(fb, offset, length, text.replaceAll(".", ""),
                        attrs);
                // Not being a digit, doesn't allow the
                // insertion of the given input
            }
        }
    }
}

@Override
public void remove(FilterBypass fb, int offset, int length)
        throws BadLocationException {

    if (canRemove) {
        if (periodCounter == 1) { // If there is a . in the text
            if (numberCounter != 0) { // and If there are digits after the .
                numberCounter--; // It means you'r removing a digit, so it
                                    // saves
                                    // that info
                super.remove(fb, offset, length); // And removes it
            } else { // If there are no digits it means you'r removing a .
                periodCounter--; // It saves that info allowing a new . to
                                    // be
                                    // inserted
                super.remove(fb, offset, length); // and removes it
            }
        } else { // If there is no . in the text there are no problems
            super.remove(fb, offset, length); // so it just removes whatever
                                                // there is (digit)
        }
    } else {

    }
}
}
Run Code Online (Sandbox Code Playgroud)

insertString方法做了同样的替换方法,所以我把它留了出来,但在应用程序中它实现了.

在此先感谢您的时间!

编辑 - 此外它现在有一个过滤器来限制高度输入

public class IntAndDotFilter extends DocumentFilter {

/** The Constant _maxCharacters. */
private static final int _maxCharacters = 10;

/** The _is weight. */
private Boolean _isWeight = null;


public IntAndDotFilter(Boolean isWeight) {
    super();
    _isWeight = isWeight;
}

public void replace(FilterBypass fb, int offset, int length, String string,
        AttributeSet attr) throws BadLocationException {

    String text = fb.getDocument().getText(0, fb.getDocument().getLength());
    text += string;

    if (_isWeight) {
        if ((fb.getDocument().getLength() + string.length() - length) <= _maxCharacters
                && text.matches("^[1]?[0-9]{1,2}([.][0-9]{0,2})?$")) {
            super.replace(fb, offset, length, string, attr);
        } else {
            Toolkit.getDefaultToolkit().beep();
        }
    } else {
        if ((fb.getDocument().getLength() + string.length() - length) <= _maxCharacters
                && text.matches("^([1]([.][0-9]{0,2})?)|([2]([.][0-5]?)?)$")) {
            super.replace(fb, offset, length, string, attr);
        } else {
            Toolkit.getDefaultToolkit().beep();
        }
    }
}

@Override
public void remove(FilterBypass fb, int offset, int length)
        throws BadLocationException {

    String text = fb.getDocument().getText(0, fb.getDocument().getLength());

    if (_isWeight) {
        if (text.matches("^[1]?[0-9]{1,2}([.][0-9]{0,2})?$")) {
            super.remove(fb, offset, length);
        } else {
            Toolkit.getDefaultToolkit().beep();
        }
    } else {
        if (text.matches("^([1]([.][0-9]{0,2})?)|([2]([.][0-5]?)?)$")) {
            super.remove(fb, offset, length);
        } else {
            Toolkit.getDefaultToolkit().beep();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Pau*_*tha 10

你使过滤变得比以前更加复杂.对于插入(如果代码相同,则替换),您可能因为\\.检查而无法输入.您只能粘贴句点,因为这是您要检查的内容.至于删除,以下建议将适用.

为简化起见,您应该只获取文档的整个文本,然后使用正则表达式检查整个文档字符串是否与正则表达式匹配.它比你想做的要简单得多.您可以在此处获得有关过滤过程的详细说明.

这是一个例子,只使用insertString和replace.对于删除,它没有什么不同,只需获取文本,并检查它是否与正则表达式匹配.我从上面的链接中的答案中获取了部分示例.场景是OP想要最大字符,只允许一个小数位.这就是正则表达式匹配的东西.但是当你输入或插入时也可以匹配任何东西00 00. 00.0

import java.awt.GridBagLayout;
import java.awt.Toolkit;

import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;

public class FilterDemo {

    public FilterDemo() {
        JFrame frame = new JFrame();
        frame.setLayout(new GridBagLayout());
        frame.setSize(300, 300);
        frame.add(createFilteredField());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationByPlatform(true);
        frame.setVisible(true);

    }

    public JTextField createFilteredField() {
        JTextField field = new JTextField();
        AbstractDocument document = (AbstractDocument) field.getDocument();
        final int maxCharacters = 10;
        document.setDocumentFilter(new DocumentFilter() {
            public void replace(FilterBypass fb, int offs, int length,
                    String str, AttributeSet a) throws BadLocationException {

                String text = fb.getDocument().getText(0,
                        fb.getDocument().getLength());
                text += str;
                if ((fb.getDocument().getLength() + str.length() - length) <= maxCharacters
                        && text.matches("^[0-9]+[.]?[0-9]{0,1}$")) {
                    super.replace(fb, offs, length, str, a);
                } else {
                    Toolkit.getDefaultToolkit().beep();
                }
            }

            public void insertString(FilterBypass fb, int offs, String str,
                    AttributeSet a) throws BadLocationException {

                String text = fb.getDocument().getText(0,
                        fb.getDocument().getLength());
                text += str;
                if ((fb.getDocument().getLength() + str.length()) <= maxCharacters
                        && text.matches("^[0-9]+[.]?[0-9]{0,1}$")) {
                    super.insertString(fb, offs, str, a);
                } else {
                    Toolkit.getDefaultToolkit().beep();
                }
            }
        });
        return field;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new FilterDemo();
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)