java - make custom JTextField (JCurrencyField) -


i making jcurrencyfield use in program, finished creating i've faced issue.

jcurrencyfield normal jtextfield cannot accept character not number or decimal point . , made specifications jcurrencyfield:

  • the user cannot insert more 1 decimal point ..
  • the user cannot insert more 2 digits after decimal point.

the issue i've faced not being able insert digits before decimal point if there 2 digits after decimal point.

here code:

import javax.swing.*; import javax.swing.text.*; public class jcurrencyfield extends jtextfield {     public jcurrencyfield()     {         ((abstractdocument)getdocument()).setdocumentfilter(new numberonlyfilter());     }      private class numberonlyfilter extends documentfilter     {         public void insertstring(documentfilter.filterbypass fb, int offset,            string text, attributeset attr) throws badlocationexception         {             if(!containsonlynumbers(text)) return;             fb.insertstring(offset, text, attr);            }              public void replace(documentfilter.filterbypass fb, int offset, int length,            string text, attributeset attr) throws badlocationexception         {             if(!containsonlynumbers(text)) return;             fb.replace(offset, length, text, attr);         }          /**         * method checks if string contains numbers         */         public boolean containsonlynumbers(string str)         {              //it can't contain numbers if it's null or empty...             if (str == null || str.length() == 0) return false;               int counter = 0;             for(int = 0; < gettext().length(); i++)             {                 if(counter > 1) return false;                 if(gettext().charat(i) == '.')                 {                     counter++;                 }             }              int fp_counter = 0;             int fp_index = -1;             for(int = 0; < str.length(); i++)             {                 if(counter >= 1) break;                 if(str.charat(i) == '.')                 {                     fp_counter++;                     fp_index = i;                 }             }              if(fp_counter > 1) return false;              if(str.length() > fp_index + 3) return false;              if(counter >= 1)             {                 for(int = 0; < gettext().length(); i++)                 {                     if(gettext().charat(i) == '.') counter++;                 }             }              (int j = 0; j < str.length(); j++)             {                 if(counter >= 1 && (str.charat(j) == '.')) return false;             }              int index = 0;             boolean fp_flag = false;             int sp_count = 0;             for(int k = 0; k < gettext().length(); k++)             {                 if(gettext().charat(k) == '.')                 {                     index = k;                     fp_flag = true;                 }                 if(fp_flag) sp_count++;                 if(sp_count > 2) return false;             }              //if(fp_flag && str.length() > 2) return false;             if(fp_flag && index + 1 < gettext().length() && str.length() > 1) return false;             //if(index + 2 < gettext().length() && fp_flag) return false;               (int l = 0; l < str.length(); l++)             {                  //if find non-digit character return false.                 if(str.charat(l) == '.') continue;                 if(!character.isdigit(str.charat(l)))                 return false;             }              return true;         }     } } 

test program:

import java.awt.*; import java.util.*; import javax.swing.*; import javax.swing.border.*; public class test extends jframe  {     private jcurrencyfield txt = new jcurrencyfield();     public test()     {         super("test...");         setdefaultcloseoperation(exit_on_close);         try{ uimanager.setlookandfeel(uimanager.getsystemlookandfeelclassname());}         catch(exception e){ system.out.println("unable load windows , feel");}         setpreferredsize(new dimension(300, 100));         ((jpanel) getcontentpane()).setborder(new emptyborder(13, 13, 13, 13) );         setlayout(new flowlayout());         txt.setpreferredsize(new dimension(100,30));         add(txt);         pack();         setlocationrelativeto(null);         setvisible(true);         setresizable(false);     }     public static void main(string[] args)     {         new test();     } } 

could please me solve issue?

you're testing wrong string in documentfilter.

you shouldn't testing text string rather string built text , document obtained filterbypass parameter since string want see if fulfills criteria. instance, not this:

    public void insertstring(documentfilter.filterbypass fb, int offset,        string text, attributeset attr) throws badlocationexception     {         if(!containsonlynumbers(text)) return;         fb.insertstring(offset, text, attr);        }          public void replace(documentfilter.filterbypass fb, int offset, int length,        string text, attributeset attr) throws badlocationexception     {         if(!containsonlynumbers(text)) return;         fb.replace(offset, length, text, attr);     } 

but rather this:

   private class numberonlyfilter extends documentfilter {       public void insertstring(documentfilter.filterbypass fb, int offset,                string text, attributeset attr) throws badlocationexception {          stringbuilder sb = new stringbuilder();          sb.append(fb.getdocument().gettext(0, fb.getdocument().getlength()));          sb.insert(offset, text);          if (!containsonlynumbers(sb.tostring()))             return;          fb.insertstring(offset, text, attr);       }        public void replace(documentfilter.filterbypass fb, int offset,                int length, string text, attributeset attr)                throws badlocationexception {          stringbuilder sb = new stringbuilder();          sb.append(fb.getdocument().gettext(0, fb.getdocument().getlength()));          sb.replace(offset, offset + length, text);          if (!containsonlynumbers(sb.tostring()))             return;          fb.replace(offset, length, text, attr);       } 

you need make changes containsonlynumbers method account these changes.

edit 1
, can done using toto's regex:

  private boolean containsonlynumbers(string text) {      pattern pattern = pattern.compile("\\d*(\\.\\d{0,2})?");      matcher matcher = pattern.matcher(text);      boolean ismatch = matcher.matches();      return ismatch;   } 

Comments

Popular posts from this blog

c# - SharpSVN - How to get the previous revision? -

c++ - Is it possible to compile a VST on linux? -

url - Querystring manipulation of email Address in PHP -