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 org.jdtaus.banking.AlphaNumericText27;
30 import org.jdtaus.core.container.ContainerFactory;
31
32 /**
33 * {@code JFormattedTextField} supporting the {@code AlphaNumericText27} type.
34 * <p>This textfield uses the {@link AlphaNumericText27} type for parsing and formatting. An empty string value is
35 * treated as {@code null}. The {@code normalizing} flag controls parsing. If {@code true} (default) the field's value
36 * is normalized using the {@link AlphaNumericText27#normalize(String)} method prior to parsing. The {@code validating}
37 * flag controls validation of values entered into the textfield. If {@code true} (default), a {@code DocumentFilter} is
38 * registered with the textfield disallowing invalid values, that is, values which are not {@code null} and not empty
39 * strings and for which the {@link AlphaNumericText27#parse(String)} method throws a {@code ParseException}.</p>
40 *
41 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
42 * @version $JDTAUS: AlphaNumericText27TextField.java 8864 2014-01-10 17:13:30Z schulte $
43 */
44 public final class AlphaNumericText27TextField extends JFormattedTextField
45 {
46
47 /** Serial version UID for backwards compatibility with 1.1.x classes. */
48 private static final long serialVersionUID = -8152767220100367519L;
49
50 /**
51 * Flag indicating if a normalizing parser is used.
52 * @serial
53 */
54 private Boolean normalizing;
55
56 /**
57 * Flag indicating if validation is performed.
58 * @serial
59 */
60 private Boolean validating;
61
62 /** Creates a new default {@code AlphaNumericText27TextField} instance. */
63 public AlphaNumericText27TextField()
64 {
65 super();
66 this.setColumns( AlphaNumericText27.MAX_LENGTH );
67 this.setFormatterFactory( new AbstractFormatterFactory()
68 {
69
70 public AbstractFormatter getFormatter( final JFormattedTextField ftf )
71 {
72 return new AbstractFormatter()
73 {
74
75 public Object stringToValue( final String text ) throws ParseException
76 {
77 Object value = null;
78
79 if ( text != null && text.trim().length() > 0 )
80 {
81 value = AlphaNumericText27.parse(
82 isNormalizing() ? AlphaNumericText27.normalize( text ) : text );
83
84 }
85
86 return value;
87 }
88
89 public String valueToString( final Object value ) throws ParseException
90 {
91 String ret = null;
92
93 if ( value instanceof AlphaNumericText27 )
94 {
95 final AlphaNumericText27 txt = (AlphaNumericText27) value;
96 ret = txt.isEmpty() ? null : txt.format().trim();
97 }
98
99 return ret;
100 }
101
102 protected DocumentFilter getDocumentFilter()
103 {
104 return new DocumentFilter()
105 {
106
107 public void insertString( final FilterBypass fb, final int o, String s,
108 final AttributeSet a ) throws BadLocationException
109 {
110 if ( isValidating() )
111 {
112 if ( isNormalizing() )
113 {
114 final char[] chars = s.toCharArray();
115 for ( int i = chars.length - 1; i >= 0; i-- )
116 {
117 chars[i] = Character.toUpperCase( chars[i] );
118 }
119 s = String.valueOf( chars );
120 }
121
122 final StringBuffer b =
123 new StringBuffer( fb.getDocument().getLength() + s.length() );
124
125 b.append( fb.getDocument().getText( 0, fb.getDocument().getLength() ) );
126 b.insert( o, s );
127
128 try
129 {
130 AlphaNumericText27.parse( b.toString() );
131 }
132 catch ( ParseException e )
133 {
134 invalidEdit();
135 return;
136 }
137 }
138
139 super.insertString( fb, o, s, a );
140 }
141
142 public void replace( final FilterBypass fb, final int o, final int l, String s,
143 final AttributeSet a ) throws BadLocationException
144 {
145 if ( isValidating() )
146 {
147 if ( isNormalizing() )
148 {
149 final char[] chars = s.toCharArray();
150 for ( int i = chars.length - 1; i >= 0; i-- )
151 {
152 chars[i] = Character.toUpperCase( chars[i] );
153 }
154 s = String.valueOf( chars );
155 }
156
157 final StringBuffer b = new StringBuffer(
158 fb.getDocument().getText( 0, fb.getDocument().getLength() ) );
159
160 b.delete( o, o + l );
161
162 if ( s != null )
163 {
164 b.insert( o, s );
165 }
166
167 try
168 {
169 AlphaNumericText27.parse( b.toString() );
170 }
171 catch ( ParseException e )
172 {
173 invalidEdit();
174 return;
175 }
176 }
177
178 super.replace( fb, o, l, s, a );
179 }
180
181 };
182 }
183
184 };
185 }
186
187 } );
188 }
189
190 /**
191 * Gets the last valid {@code AlphaNumericText27}.
192 *
193 * @return the last valid {@code AlphaNumericText27} or {@code null}.
194 */
195 public AlphaNumericText27 getAlphaNumericText27()
196 {
197 return (AlphaNumericText27) this.getValue();
198 }
199
200 /**
201 * Gets the flag indicating if a normalizing parser is used.
202 *
203 * @return {@code true} if a normalizing parser is used; {@code false} if a strict parser is used
204 * (defaults to {@code true}).
205 */
206 public boolean isNormalizing()
207 {
208 if ( this.normalizing == null )
209 {
210 this.normalizing = this.isDefaultNormalizing();
211 }
212
213 return this.normalizing.booleanValue();
214 }
215
216 /**
217 * Sets the flag indicating if a normalizing parser should be used.
218 *
219 * @param value {@code true} to use a normalizing parser; {@code false} to use a strict parser
220 * (defaults to {@code true}).
221 */
222 public void setNormalizing( final boolean value )
223 {
224 this.normalizing = Boolean.valueOf( value );
225 }
226
227 /**
228 * Gets the flag indicating if validation is performed.
229 *
230 * @return {@code true} if the field's value is validated; {@code false} if no validation of the field's value is
231 * performed.
232 */
233 public boolean isValidating()
234 {
235 if ( this.validating == null )
236 {
237 this.validating = this.isDefaultValidating();
238 }
239
240 return this.validating.booleanValue();
241 }
242
243 /**
244 * Sets the flag indicating if validation should be performed.
245 *
246 * @param value {@code true} to validate the field's value; {@code false} to not validate the field's value.
247 */
248 public void setValidating( boolean value )
249 {
250 this.validating = Boolean.valueOf( value );
251 }
252
253 //--Properties--------------------------------------------------------------
254
255 // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:jdtausProperties
256 // This section is managed by jdtaus-container-mojo.
257
258 /**
259 * Gets the value of property <code>defaultValidating</code>.
260 *
261 * @return Default value of the flag indicating if validation should be performed.
262 */
263 private java.lang.Boolean isDefaultValidating()
264 {
265 return (java.lang.Boolean) ContainerFactory.getContainer().
266 getProperty( this, "defaultValidating" );
267
268 }
269
270 /**
271 * Gets the value of property <code>defaultNormalizing</code>.
272 *
273 * @return Default value of the flag indicating if a normalizing parser should be used.
274 */
275 private java.lang.Boolean isDefaultNormalizing()
276 {
277 return (java.lang.Boolean) ContainerFactory.getContainer().
278 getProperty( this, "defaultNormalizing" );
279
280 }
281
282 // </editor-fold>//GEN-END:jdtausProperties
283
284 //--------------------------------------------------------------Properties--
285 }