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 }