This discussion is archived
2 Replies Latest reply: Oct 7, 2012 2:21 AM by mrsAngelo RSS

PatternSyntaxException: Dangling meta character '*' near index 0

mrsAngelo Newbie
Currently Being Moderated
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
  • 1. Re: PatternSyntaxException: Dangling meta character '*' near index 0
    Jörg Explorer
    Currently Being Moderated
    All that many lines for a regex question (where the error message already pointed to), which has nothing to do with Swing. An SSCCE looks different.
    if (text.compareTo("*") == 0){
    replace = "\\*";
    }
    text = replace;
    super.replace(fb, offset, length, text.replaceAll(text, replace), attrs);
    You must keep the text, the regex and the replacement string apart:
    String text= "A", regEx= "A", rep= "B";
    //String text= "*", regEx="\\*", rep= "*";
    text= text.replaceAll(regEx, rep);
    System.out.println(text);
    And why don't you use a JFormattedTextField with a MaskFormatter which does all the job for you.
  • 2. Re: PatternSyntaxException: Dangling meta character '*' near index 0
    mrsAngelo Newbie
    Currently Being Moderated
    Hi Jorg,

    Thank you for answering me
    Your code works.

    I use a filter (instead then a JFormattedTextField with a MaskFormatter) because
    in this way I can have a direct and better control of the elaboration...

    Regards

    Angelo