View Javadoc
1   /*
2    *  jDTAUS Banking Utilities
3    *  Copyright (C) 2005 Christian Schulte
4    *  <cs@schulte.it>
5    *
6    *  This library is free software; you can redistribute it and/or
7    *  modify it under the terms of the GNU Lesser General Public
8    *  License as published by the Free Software Foundation; either
9    *  version 2.1 of the License, or any later version.
10   *
11   *  This library is distributed in the hope that it will be useful,
12   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   *  Lesser General Public License for more details.
15   *
16   *  You should have received a copy of the GNU Lesser General Public
17   *  License along with this library; if not, write to the Free Software
18   *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19   *
20   */
21  package org.jdtaus.banking.util.swing;
22  
23  import java.text.ParseException;
24  import javax.swing.JFormattedTextField;
25  import javax.swing.JFormattedTextField.AbstractFormatter;
26  import javax.swing.text.AttributeSet;
27  import javax.swing.text.BadLocationException;
28  import javax.swing.text.DocumentFilter;
29  import javax.swing.text.DocumentFilter.FilterBypass;
30  import org.jdtaus.banking.Kontonummer;
31  import org.jdtaus.core.container.ContainerFactory;
32  import org.jdtaus.core.container.PropertyException;
33  
34  /**
35   * {@code JFormattedTextField} supporting the {@code Kontonummer} type.
36   * <p>This textfield uses the {@link Kontonummer} type for parsing and formatting. An empty string value is treated as
37   * {@code null}. Property {@code format} controls formatting and takes one of the format constants defined in class
38   * {@code Kontonummer}. By default the {@code ELECTRONIC_FORMAT} is used. The {@code validating} flag controls
39   * validation of values entered into the textfield. If {@code true} (default), a {@code DocumentFilter} is registered
40   * with the textfield disallowing invalid values, that is, values which are not {@code null} and not empty strings and
41   * for which the {@link Kontonummer#parse(String)} method throws a {@code ParseException}.</p>
42   *
43   * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
44   * @version $JDTAUS: KontonummerTextField.java 8864 2014-01-10 17:13:30Z schulte $
45   */
46  public final class KontonummerTextField extends JFormattedTextField
47  {
48  
49      /** Serial version UID for backwards compatibility with 1.1.x classes. */
50      private static final long serialVersionUID = -959284086262750493L;
51  
52      /**
53       * Format used to format Kontonummer instances.
54       * @serial
55       */
56      private Integer format;
57  
58      /**
59       * Flag indicating if validation is performed.
60       * @serial
61       */
62      private Boolean validating;
63  
64      /** Creates a new default {@code KontonummerTextField} instance. */
65      public KontonummerTextField()
66      {
67          super();
68          this.assertValidProperties();
69          this.setColumns( Kontonummer.MAX_CHARACTERS );
70          this.setFormatterFactory( new AbstractFormatterFactory()
71          {
72  
73              public AbstractFormatter getFormatter( final JFormattedTextField ftf )
74              {
75                  return new AbstractFormatter()
76                  {
77  
78                      public Object stringToValue( final String text ) throws ParseException
79                      {
80                          Object value = null;
81  
82                          if ( text != null && text.trim().length() > 0 )
83                          {
84                              value = Kontonummer.parse( text );
85                          }
86  
87                          return value;
88                      }
89  
90                      public String valueToString( final Object value ) throws ParseException
91                      {
92                          String ret = null;
93  
94                          if ( value instanceof Kontonummer )
95                          {
96                              final Kontonummer kto = (Kontonummer) value;
97                              ret = kto.format( getFormat() );
98                          }
99  
100                         return ret;
101                     }
102 
103                     protected DocumentFilter getDocumentFilter()
104                     {
105                         return new DocumentFilter()
106                         {
107 
108                             public void insertString( final FilterBypass fb, final int o, String s,
109                                                       final AttributeSet a ) throws BadLocationException
110                             {
111                                 if ( isValidating() )
112                                 {
113                                     final StringBuffer b = new StringBuffer( fb.getDocument().getLength() + s.length() );
114                                     b.append( fb.getDocument().getText( 0, fb.getDocument().getLength() ) );
115                                     b.insert( o, s );
116 
117                                     try
118                                     {
119                                         Kontonummer.parse( b.toString() );
120                                     }
121                                     catch ( ParseException e )
122                                     {
123                                         invalidEdit();
124                                         return;
125                                     }
126                                 }
127 
128                                 super.insertString( fb, o, s, a );
129                             }
130 
131                             public void replace( final FilterBypass fb, final int o, final int l, String s,
132                                                  final AttributeSet a ) throws BadLocationException
133                             {
134                                 if ( isValidating() )
135                                 {
136                                     final StringBuffer b = new StringBuffer(
137                                         fb.getDocument().getText( 0, fb.getDocument().getLength() ) );
138 
139                                     b.delete( o, o + l );
140 
141                                     if ( s != null )
142                                     {
143                                         b.insert( o, s );
144                                     }
145 
146                                     try
147                                     {
148                                         Kontonummer.parse( b.toString() );
149                                     }
150                                     catch ( ParseException e )
151                                     {
152                                         invalidEdit();
153                                         return;
154                                     }
155                                 }
156 
157                                 super.replace( fb, o, l, s, a );
158                             }
159 
160                         };
161                     }
162 
163                 };
164             }
165 
166         } );
167     }
168 
169     /**
170      * Gets the last valid {@code Kontonummer}.
171      *
172      * @return the last valid {@code Kontonummer} or {@code null}.
173      */
174     public Kontonummer getKontonummer()
175     {
176         return (Kontonummer) this.getValue();
177     }
178 
179     /**
180      * Gets the constant of the format used when formatting Kontonummer instances.
181      *
182      * @return the constant of the format used when formatting Kontonummer instances.
183      *
184      * @see Kontonummer#ELECTRONIC_FORMAT
185      * @see Kontonummer#LETTER_FORMAT
186      */
187     public int getFormat()
188     {
189         if ( this.format == null )
190         {
191             this.format = this.getDefaultFormat();
192         }
193 
194         return this.format.intValue();
195     }
196 
197     /**
198      * Sets the constant of the format to use when formatting Kontonummer instances.
199      *
200      * @param value the constant of the format to use when formatting Kontonummer instances.
201      *
202      * @throws IllegalArgumentException if {@code format} is neither {@code ELECTRONIC_FORMAT} nor
203      * {@code LETTER_FORMAT}.
204      *
205      * @see Kontonummer#ELECTRONIC_FORMAT
206      * @see Kontonummer#LETTER_FORMAT
207      */
208     public void setFormat( final int value )
209     {
210         if ( value != Kontonummer.ELECTRONIC_FORMAT && value != Kontonummer.LETTER_FORMAT )
211         {
212             throw new IllegalArgumentException( Integer.toString( value ) );
213         }
214 
215         this.format = new Integer( value );
216     }
217 
218     /**
219      * Gets the flag indicating if validation is performed.
220      *
221      * @return {@code true} if the field's value is validated; {@code false} if no validation of the field's value is
222      * performed.
223      */
224     public boolean isValidating()
225     {
226         if ( this.validating == null )
227         {
228             this.validating = this.isDefaultValidating();
229         }
230 
231         return this.validating.booleanValue();
232     }
233 
234     /**
235      * Sets the flag indicating if validation should be performed.
236      *
237      * @param value {@code true} to validate the field's value; {@code false} to not validate the field's value.
238      */
239     public void setValidating( boolean value )
240     {
241         this.validating = Boolean.valueOf( value );
242     }
243 
244     /**
245      * Checks configured properties.
246      *
247      * @throws PropertyException for invalid property values.
248      */
249     private void assertValidProperties()
250     {
251         if ( this.getFormat() != Kontonummer.ELECTRONIC_FORMAT && this.getFormat() != Kontonummer.LETTER_FORMAT )
252         {
253             throw new PropertyException( "format", Integer.toString( this.getFormat() ) );
254         }
255     }
256 
257     //--Properties--------------------------------------------------------------
258 
259 // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:jdtausProperties
260     // This section is managed by jdtaus-container-mojo.
261 
262     /**
263      * Gets the value of property <code>defaultValidating</code>.
264      *
265      * @return Default value of the flag indicating if validation should be performed.
266      */
267     private java.lang.Boolean isDefaultValidating()
268     {
269         return (java.lang.Boolean) ContainerFactory.getContainer().
270             getProperty( this, "defaultValidating" );
271 
272     }
273 
274     /**
275      * Gets the value of property <code>defaultFormat</code>.
276      *
277      * @return Default value of the format to use when formatting Kontonummer instances (4001 = electronic format, 4002 letter format).
278      */
279     private java.lang.Integer getDefaultFormat()
280     {
281         return (java.lang.Integer) ContainerFactory.getContainer().
282             getProperty( this, "defaultFormat" );
283 
284     }
285 
286 // </editor-fold>//GEN-END:jdtausProperties
287 
288     //--------------------------------------------------------------Properties--
289 }