I have a Jtextfield named tPvv, wrote a DocumentFilter for accept only numbers, maximum length of 3.And I have a button edit, when I click that button the entire row loaded in textfield's for editing from the jtable(value in Jtextfield tPvv remains constant). The Jtextfield which are defined without documentFilter works well(loads values from jtable to the textfields based on row selection). Also when I comment the DocumentFilter it works well, but I cannot provide the validation (accept number only and the length of 3).
I need to check the validation for the tPvv and also load the values from the jtable based on different row selection by clicking the edit button.
`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));
`last commented line i defined in my code for the validation purpose call. Please solve this problem.
You're basically ignoring the parameters that are passed to you and what they mean...
offset
is the offset within the document where the new text
will be inserted...length
is the number of characters to be deletedNow, if we use the length
within the if
statement, we start to see a difference. Basically, when you call setText
, the length
will be equal to the number of characters in the text field (as all the text is to be replaced)...
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);
}
}
You're also calling super.insertString(fb, offset, text, attrs);
in the replace
method, which isn't helpful either...
Update from comments
The problem you're facing with setText(null)
is to do with the fact that isNumeric
in your filter is returning false
for null
and empty ("") values, but these are actually valid in some contexts...
Now, you could alter the isNumeric
method, but that might adversely affect the other methods of the filter, instead, we should be place an additional condition in replace
to catch this case and deal with it appropriately...
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);
}
}