【问题标题】:jtextfield documentFilter once defined, value not loading in the jtextfieldjtextfield documentFilter 一旦定义,值不会加载到 jtextfield
【发布时间】:2013-09-07 17:12:29
【问题描述】:

我有一个名为 tPvv 的 Jtextfield,写了一个 DocumentFilter 只接受数字,最大长度为 3。我有一个按钮编辑,当我单击该按钮时,整个行加载到 textfield 中以便从 jtable 进行编辑(Jtextfield 中的值tPvv 保持不变)。没有 documentFilter 定义的 Jtextfield 运行良好(根据行选择将值从 jtable 加载到文本字段)。此外,当我评论 DocumentFilter 时,它运行良好,但我无法提供验证(仅接受数字和 3 的长度)。

我需要检查 tPvv 的验证,并通过单击编辑按钮根据不同的行选择从 jtable 加载值。

`class NumericAndLengthFilter extends DocumentFilter {

        /**
         * Number of characters allowed.
         */
        private int length = 0;

        /**
         * Restricts the number of charcacters can be entered by given length.
         * @param length Number of characters allowed.
         */
        public NumericAndLengthFilter(int length) {
            this.length = length;
        }

        @Override
        public void insertString(FilterBypass fb, int offset, String string,
                AttributeSet attr) throws
                BadLocationException {
            if (isNumeric(string)) {
                if (this.length > 0 && fb.getDocument().getLength() + string.
                        length()
                        > this.length) {
                    return;
                }
                super.insertString(fb, offset, string, attr);
            }
        }

        @Override
        public void replace(FilterBypass fb, int offset, int length, String text,
                AttributeSet attrs) throws
                BadLocationException {
            if (isNumeric(text)) {
                if (this.length > 0 && fb.getDocument().getLength() + text.
                        length()
                        > this.length) {
                    return;
                }
                super.insertString(fb, offset, text, attrs);
            }
        }

        /**
         * This method tests whether given text can be represented as number.
         * This method can be enhanced further for specific needs.
         * @param text Input text.
         * @return {@code true} if given string can be converted to number; otherwise returns {@code false}.
         */
        private boolean isNumeric(String text) {
            if (text == null || text.trim().equals("")) {
                return false;
            }
            for (int iCount = 0; iCount < text.length(); iCount++) {
                if (!Character.isDigit(text.charAt(iCount))) {
                    return false;
                }
            }
            return true;
        }

}
//((AbstractDocument) tPvv.getDocument()).setDocumentFilter(new NumericAndLengthFilter(3));

`我在代码中为验证目的调用定义的最后注释行。请解决这个问题。

【问题讨论】:

  • 对于只接受数字的文本字段(即使长度有限),您也可以查看this question

标签: java swing documentlistener documentfilter


【解决方案1】:

您基本上忽略了传递给您的参数及其含义...

  • offset 是文档中将插入新的text 的偏移量...
  • length 是要删除的字符数

现在,如果我们在if 语句中使用length,我们开始看到不同之处。基本上,当您调用setText 时,length 将等于文本字段中的字符数(因为所有文本都将被替换)...

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

        System.out.println(offset + "; " + length + "; " + text);

        if (this.length > 0 && 
            fb.getDocument().getLength() + text.length() - length > this.length) {
            return;
        }
        super.replace(fb, offset, length, text, attrs);
    }
}

您还在replace 方法中调用super.insertString(fb, offset, text, attrs);,这也无济于事...

来自 cmets 的更新

setText(null) 面临的问题与过滤器中的 isNumeric 为 null 和空 ("") 值返回 false 的事实有关,但这些实际上在某些情况下是有效的上下文...

现在,您可以更改isNumeric 方法,但这可能会对过滤器的其他方法产生不利影响,相反,我们应该在replace 中添加一个附加条件来捕获这种情况并适当地处理它。 .

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

        System.out.println(offset + "; " + length + "; " + text);

        if (this.length > 0 && 
            fb.getDocument().getLength() + text.length() - length > this.length) {
            return;
        }
        super.replace(fb, offset, length, text, attrs);
    } else if (text == null || text.equals("")) {
        super.replace(fb, offset, length, text, attrs);
    }
}

【讨论】:

  • 上述代码解决了上述问题,但出现了新问题,当我单击添加按钮时,所有文本字段都变为空或空白(我调用 Textfield.setText(null) 方法)但 tPvv(为该 JTextField 创建的 Docfilter) 文本字段字段未删除。
  • "我调用了 Textfield.setText(null)",但是在您的 isNumeric 中,您返回 false 的值等于 null 并且为空。我会考虑返回true,但您需要在其他方法中为nullStrings 添加额外的检查。或者,将else if 语句添加到您的replace 方法以包括null String 的可能性并调用super.replace(...)
猜你喜欢
  • 2011-12-20
  • 1970-01-01
  • 1970-01-01
  • 2013-02-23
  • 1970-01-01
  • 1970-01-01
  • 2016-11-27
  • 2016-07-09
  • 2022-01-21
相关资源
最近更新 更多