Hi,
I am using DocumentFilter to control the input in a JtextField In accordance with model of a mask.
The mask can contain the following characters:
// # : for =---> NUMBER only
// ? : for =---> LETTER only
// A : for =---> LETTER end for NUMBER
// * : for =---> ANYTHING
I made a class that extends DocumentFilter and it look like this:
public class MydocumentFilter extends DocumentFilter {
public void insertString(...){
// do anything
} // insertString()
public void remove(...)
// do anything
} // remove()
@Override
public void replace(
DocumentFilter.FilterBypass fb,
int offset, // posizione del cursore
int length, // Length of text to delete (solo per sostituzioni...)
String text,// testo da inserire
AttributeSet attrs) throws BadLocationException {
// here are some controls that change the value of the text variable, and at last call the super class..:
super.replace(fb, offset, length, text.replaceAll(text, replace), attrs);
} // replace()
} // class MydocumentFilter
I have a problem when the user write wildcards (='*' OR '?').
Then I get the message:
Exception in thread "AWT-EventQueue-0" java.util.regex.PatternSyntaxException: Dangling meta character '*' near index 0.
I know that '*' and “?” are is a metachars and for that I added this code before calling super.replace(...);
if (text.compareTo("*") == 0){
replace = "\\*";
}
but I don't get the expected result. I get -\*- instead then -*-
here the code of the program that I use to make tests:
/**
* http://www.java2s.com/Tutorial/Java/0260__Swing-Event/CustomDocumentFilter.htm
*
* @author Owner
*/
//public class IntegerRangeDocumentFilter extends DocumentFilter {
public class NavBean_documentFilter extends DocumentFilter {
enum CharAcceptability_ENUM {
valid, invalid, overrite
};
String mask;
public NavBean_documentFilter(String mask_) { // constructor
mask = mask_;
} // constructor
@Override
public void insertString(
DocumentFilter.FilterBypass fb,
int offset,
String string,
AttributeSet attr) throws BadLocationException {
System.out.println("insert string" + string);
System.out.println(offset);
super.insertString(fb, offset, string, attr);
} // insertString()
@Override
public void remove(DocumentFilter.FilterBypass fb, int offset, int length)
throws BadLocationException {
System.out.println("remove");
super.remove(fb, offset, length);
} // remove()
public void replace(
DocumentFilter.FilterBypass fb,
int offset, // posizione del cursore
int length, // Length of text to delete (solo per sostituzioni...)
String text,// testo da inserire
AttributeSet attrs) throws BadLocationException {
boolean valid = true;
if (offset > mask.length()) {
return;
}
if (text.length() != 1) {
return;
}
CharAcceptability_ENUM charAcceptability_ENUM = checkTheInput(text, offset);
String replace = null;
switch (charAcceptability_ENUM) {
case invalid:
replace = "";
break;
case valid:
replace = text;
break;
case overrite:
char cc = mask.charAt(offset);
replace = String.valueOf(cc);
break;
}
// It is because * is used as a metacharacter to signify one or more
// occurences of previous character.
// So if i write M* then it will look for files MMMMMM..... !
// Here you are using * as the only character so the compiler
// is looking for the character to find multiple occurences of,
// so it throws the exception.:)
if (text.compareTo("*") == 0){
replace = "\\*";
}
text = replace;
super.replace(fb, offset, length, text.replaceAll(text, replace), attrs);
// super.replace(fb, offset, length, text, attrs);
} // replace()
private CharAcceptability_ENUM checkTheInput(String text, int cursorPosition) {
if (cursorPosition >= mask.length()) {
return CharAcceptability_ENUM.invalid;
}
char mappedCharInTheMask = mask.charAt(cursorPosition); // qui erro
char charToSet = text.charAt(0);
System.out.println("carattere da mettere = " + charToSet + " ; carattere della maschera = " + mappedCharInTheMask);
boolean placeHolderFree = mask.contains(String.valueOf(mappedCharInTheMask));
if (!placeHolderFree) {
return CharAcceptability_ENUM.invalid;
}
CharAcceptability_ENUM charAcceptability_ENUM =
CharAcceptability_ENUM.invalid;
//
char holdPlace = mask.charAt(cursorPosition);
switch (holdPlace) {
case '*': //
charAcceptability_ENUM = CharAcceptability_ENUM.valid;
break;
case '#': // only numbers
if ( Character.isDigit(charToSet)) {
charAcceptability_ENUM = CharAcceptability_ENUM.valid;
}
break;
case '?': //only letters
if (Character.isLetter(charToSet)){
charAcceptability_ENUM = CharAcceptability_ENUM.valid;
}
break;
case 'A': // letters and numbers
if (Character.isLetterOrDigit(charToSet)){
charAcceptability_ENUM = CharAcceptability_ENUM.valid;
}
break;
default:
charAcceptability_ENUM = CharAcceptability_ENUM.overrite;
}
System.out.println("valore di charAcceptability_ENUM = " + charAcceptability_ENUM.toString());
return charAcceptability_ENUM;
} // checkTheInput()
//
} // class UsingDocumentFilter
class RangeSample {
public static void main(String args[]) {
JFrame frame = new JFrame("Range Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// questo (in generale) e' quanto si deve fare per usare un filtro...
JTextField textFieldOne = new JTextField();
JLabel jLabMask = new JLabel();
JPanel panel = new JPanel();
String explanation1 = " --- use of wildCard: ---";
String explanation2 = " # : is for =---> only NUMBER ";
String explanation3 = " ? : is for =---> only LETTER ";
String explanation4 = " A : is for =---> LETTER end NUMBER";
String explanation5 = " * : is for =---> ANYTHING ";
JLabel jLabExplanat1 = new JLabel(explanation1);
JLabel jLabExplanat2 = new JLabel(explanation2);
JLabel jLabExplanat3 = new JLabel(explanation3);
JLabel jLabExplanat4 = new JLabel(explanation4);
JLabel jLabExplanat5 = new JLabel(explanation5);
panel.setLayout(new GridLayout(5, 1));
panel.add(jLabExplanat1);
panel.add(jLabExplanat2);
panel.add(jLabExplanat3);
panel.add(jLabExplanat4);
panel.add(jLabExplanat5);
//
jLabExplanat1.setForeground(Color.green);
jLabExplanat2.setForeground(Color.red);
jLabExplanat3.setForeground(Color.red);
jLabExplanat4.setForeground(Color.red);
jLabExplanat5.setForeground(Color.red);
jLabMask.setForeground(Color.blue);
//AAA-##:***
String mask = "##-A#A:#???? ***";
// String mask = "***";
Document textDocOne = textFieldOne.getDocument();
NavBean_documentFilter filterOne = new NavBean_documentFilter(mask);
((AbstractDocument) textDocOne).setDocumentFilter(filterOne);
//
//
String jLabelTxt = "mask to use : " + filterOne.mask + " ";
jLabMask.setText(jLabelTxt);
frame.setLayout(new GridLayout(3, 1));
frame.add(panel);
frame.add(jLabMask);
frame.add(textFieldOne);
//
frame.pack();
frame.setLocation(300, 150);
frame.setVisible(true);
} // main()
} // class RangeSample
any advice shall be appreciated
thank you
regards
Angelo Moreschini