2 Replies Latest reply: Oct 7, 2012 4:21 AM by mrsAngelo RSS

    PatternSyntaxException: Dangling meta character '*' near index 0

    mrsAngelo
      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
          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
            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