001    /* 
002     * Copyright (c) Holger Pfaff - http://pfaff.ws
003     *
004     * This software maybe used for any purpose provided the
005     * above copyright notice is retained. It is supplied as is.
006     * No warranty expressed or implied - Use at your own risk.
007     */
008    
009    import java.awt.TextComponent;
010    import java.awt.event.TextEvent;
011    import java.awt.event.TextListener;
012    import java.util.StringTokenizer;
013    
014    /**
015      * (#)TextFilter.java
016      * @author   Holger Pfaff
017      * @version  3.2 19-Mar-2004<br><br> 
018      *
019      * Textfilter to be used with TextComponents
020      */
021    
022    public class TextFilter implements TextListener {
023    
024      /**
025       * allowed chars (empty str allows any)
026       */
027      private String alw = "";
028    
029      /**
030       * denied char (empty str allows any)
031       */
032      private String dny = "";
033    
034      /**
035       * max chars (0 for unlimited)
036       */
037      private int    max = 0;
038    
039      /**
040       * Construct a textfilter
041       *
042       * @param   al   chars to allow
043       * @param   dy   chars to deny
044       * @param   mx   max. length
045       */
046      public TextFilter(String al, String dy, int mx) {
047        max = mx;
048        alw = al;
049        dny = dy;
050      }
051      
052      /**
053       * removes all chars in chr from txt
054       *
055       * @param   txt   text to remove chars from
056       * @param   chr   set of chars to remove
057       */
058      private String rem(String txt, String chr) {
059        return Util.enum2String(new StringTokenizer(txt, chr), "");
060      }
061      
062      /**
063       * implement textlistener
064       *
065       * @param   e   TextEvent
066       */
067      public void textValueChanged(TextEvent e) {
068        TextComponent cmp = (TextComponent) e.getSource();
069        String        txt = cmp.getText();
070        int           pos = cmp.getCaretPosition();
071        
072        // leave only allowed chars
073        if(alw.length() > 0) {
074          txt = rem(txt, rem(txt, alw));
075        }
076        
077        // remove denied chars
078        if(dny.length() > 0) {
079          txt = rem(txt, dny);
080        }
081        
082        int dif = txt.length() - max;
083    
084        // text too long? Try to be clever and remove char
085        // at current caret (cursor)  pos as this should be the last
086        // one entered
087        if(max > 0 && dif > 0) {
088          if(dif <= pos && pos <= txt.length()) {
089            txt = txt.substring(0, pos - dif) + txt.substring(pos);
090          } else {
091            txt = txt.substring(0, max);
092          }
093        }
094        
095        // text changed ?
096        // set it in component and try to leave caret (cursor) where it was
097        if(cmp.getText().equals(txt) == false) {
098          pos = pos + txt.length() - cmp.getText().length();
099          cmp.setText(txt);
100          cmp.setCaretPosition(pos < 0 ? 0 : pos);
101        }
102      }
103    }