001/*
002 *  jDTAUS Banking Utilities
003 *  Copyright (C) 2005 Christian Schulte
004 *  <cs@schulte.it>
005 *
006 *  This library is free software; you can redistribute it and/or
007 *  modify it under the terms of the GNU Lesser General Public
008 *  License as published by the Free Software Foundation; either
009 *  version 2.1 of the License, or any later version.
010 *
011 *  This library is distributed in the hope that it will be useful,
012 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
013 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014 *  Lesser General Public License for more details.
015 *
016 *  You should have received a copy of the GNU Lesser General Public
017 *  License along with this library; if not, write to the Free Software
018 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
019 *
020 */
021package org.jdtaus.banking.util.swing;
022
023import java.text.ParseException;
024import javax.swing.JFormattedTextField;
025import javax.swing.JFormattedTextField.AbstractFormatter;
026import javax.swing.text.AttributeSet;
027import javax.swing.text.BadLocationException;
028import javax.swing.text.DocumentFilter;
029import javax.swing.text.DocumentFilter.FilterBypass;
030import org.jdtaus.banking.Referenznummer11;
031import org.jdtaus.core.container.ContainerFactory;
032import org.jdtaus.core.container.PropertyException;
033
034/**
035 * {@code JFormattedTextField} supporting the {@code Referenznummer11} type.
036 * <p>This textfield uses the {@link Referenznummer11} type for parsing and formatting. An empty string value is treated
037 * as {@code null}. Property {@code format} controls formatting and takes one of the format constants defined in class
038 * {@code Referenznummer11}. By default the {@code ELECTRONIC_FORMAT} is used. The {@code validating} flag controls
039 * validation of values entered into the textfield. If {@code true} (default), a {@code DocumentFilter} is registered
040 * with the textfield disallowing invalid values, that is, values which are not {@code null} and not empty strings and
041 * for which the {@link Referenznummer11#parse(String)} method throws a {@code ParseException}.</p>
042 *
043 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
044 * @version $JDTAUS: Referenznummer11TextField.java 8864 2014-01-10 17:13:30Z schulte $
045 */
046public final class Referenznummer11TextField extends JFormattedTextField
047{
048
049    /** Serial version UID for backwards compatibility with 1.1.x classes. */
050    private static final long serialVersionUID = 47899058115334464L;
051
052    /**
053     * Format used when formatting Referenznummer11 instances.
054     * @serial
055     */
056    private Integer format;
057
058    /**
059     * Flag indicating if validation is performed.
060     * @serial
061     */
062    private Boolean validating;
063
064    /** Creates a new default {@code Referenznummer11TextField} instance. */
065    public Referenznummer11TextField()
066    {
067        super();
068        this.assertValidProperties();
069        this.setColumns( Referenznummer11.MAX_CHARACTERS );
070        this.setFormatterFactory( new AbstractFormatterFactory()
071        {
072
073            public AbstractFormatter getFormatter( final JFormattedTextField ftf )
074            {
075                return new AbstractFormatter()
076                {
077
078                    public Object stringToValue( final String text ) throws ParseException
079                    {
080                        Object value = null;
081
082                        if ( text != null && text.trim().length() > 0 )
083                        {
084                            value = Referenznummer11.parse( text );
085                        }
086
087                        return value;
088                    }
089
090                    public String valueToString( final Object value )
091                        throws ParseException
092                    {
093                        String ret = null;
094
095                        if ( value instanceof Referenznummer11 )
096                        {
097                            final Referenznummer11 ref = (Referenznummer11) value;
098                            ret = ref.format( getFormat() );
099                        }
100
101                        return ret;
102                    }
103
104                    protected DocumentFilter getDocumentFilter()
105                    {
106                        return new DocumentFilter()
107                        {
108
109                            public void insertString( final FilterBypass fb, final int o, String s,
110                                                      final AttributeSet a ) throws BadLocationException
111                            {
112                                if ( isValidating() )
113                                {
114                                    final StringBuffer b = new StringBuffer( fb.getDocument().getLength() + s.length() );
115                                    b.append( fb.getDocument().getText( 0, fb.getDocument().getLength() ) );
116                                    b.insert( o, s );
117
118                                    try
119                                    {
120                                        Referenznummer11.parse( b.toString() );
121                                    }
122                                    catch ( ParseException e )
123                                    {
124                                        invalidEdit();
125                                        return;
126                                    }
127                                }
128
129                                super.insertString( fb, o, s, a );
130                            }
131
132                            public void replace( final FilterBypass fb, final int o, final int l, String s,
133                                                 final AttributeSet a ) throws BadLocationException
134                            {
135                                if ( isValidating() )
136                                {
137                                    final StringBuffer b = new StringBuffer(
138                                        fb.getDocument().getText( 0, fb.getDocument().getLength() ) );
139
140                                    b.delete( o, o + l );
141
142                                    if ( s != null )
143                                    {
144                                        b.insert( o, s );
145                                    }
146
147                                    try
148                                    {
149                                        Referenznummer11.parse( b.toString() );
150                                    }
151                                    catch ( ParseException e )
152                                    {
153                                        invalidEdit();
154                                        return;
155                                    }
156                                }
157
158                                super.replace( fb, o, l, s, a );
159                            }
160
161                        };
162                    }
163
164                };
165            }
166
167        } );
168    }
169
170    /**
171     * Gets the last valid {@code Referenznummer11}.
172     *
173     * @return the last valid {@code Referenznummer11} or {@code null}.
174     */
175    public Referenznummer11 getReferenznummer11()
176    {
177        return (Referenznummer11) this.getValue();
178    }
179
180    /**
181     * Gets the constant of the format used when formatting Referenznummer11 instances.
182     *
183     * @return the constant of the format used when formatting Referenznummer11 instances.
184     *
185     * @see Referenznummer11#ELECTRONIC_FORMAT
186     * @see Referenznummer11#LETTER_FORMAT
187     */
188    public int getFormat()
189    {
190        if ( this.format == null )
191        {
192            this.format = this.getDefaultFormat();
193        }
194
195        return this.format.intValue();
196    }
197
198    /**
199     * Sets the constant of the format to use when formatting Referenznummer11 instances.
200     *
201     * @param value the constant of the format to use when formatting Referenznummer11 instances.
202     *
203     * @throws IllegalArgumentException if {@code format} is neither {@code ELECTRONIC_FORMAT} nor
204     * {@code LETTER_FORMAT}.
205     *
206     * @see Referenznummer11#ELECTRONIC_FORMAT
207     * @see Referenznummer11#LETTER_FORMAT
208     */
209    public void setFormat( final int value )
210    {
211        if ( value != Referenznummer11.ELECTRONIC_FORMAT && value != Referenznummer11.LETTER_FORMAT )
212        {
213            throw new IllegalArgumentException( Integer.toString( value ) );
214        }
215
216        this.format = new Integer( value );
217    }
218
219    /**
220     * Gets the flag indicating if validation is performed.
221     *
222     * @return {@code true} if the field's value is validated; {@code false} if no validation of the field's value is
223     * performed.
224     */
225    public boolean isValidating()
226    {
227        if ( this.validating == null )
228        {
229            this.validating = this.isDefaultValidating();
230        }
231
232        return this.validating.booleanValue();
233    }
234
235    /**
236     * Sets the flag indicating if validation should be performed.
237     *
238     * @param value {@code true} to validate the field's value; {@code false} to not validate the field's value.
239     */
240    public void setValidating( boolean value )
241    {
242        this.validating = Boolean.valueOf( value );
243    }
244
245    /**
246     * Checks configured properties.
247     *
248     * @throws PropertyException for invalid property values.
249     */
250    private void assertValidProperties()
251    {
252        if ( this.getFormat() != Referenznummer11.ELECTRONIC_FORMAT
253             && this.getFormat() != Referenznummer11.LETTER_FORMAT )
254        {
255            throw new PropertyException( "format", Integer.toString( this.getFormat() ) );
256        }
257    }
258
259    //--Properties--------------------------------------------------------------
260
261// <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:jdtausProperties
262    // This section is managed by jdtaus-container-mojo.
263
264    /**
265     * Gets the value of property <code>defaultValidating</code>.
266     *
267     * @return Default value of the flag indicating if validation should be performed.
268     */
269    private java.lang.Boolean isDefaultValidating()
270    {
271        return (java.lang.Boolean) ContainerFactory.getContainer().
272            getProperty( this, "defaultValidating" );
273
274    }
275
276    /**
277     * Gets the value of property <code>defaultFormat</code>.
278     *
279     * @return Default value of the format to use when formatting Referenznummer11 instances (6001 = electronic format, 6002 letter format).
280     */
281    private java.lang.Integer getDefaultFormat()
282    {
283        return (java.lang.Integer) ContainerFactory.getContainer().
284            getProperty( this, "defaultFormat" );
285
286    }
287
288// </editor-fold>//GEN-END:jdtausProperties
289
290    //--------------------------------------------------------------Properties--
291}