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.Kontonummer; 031import org.jdtaus.core.container.ContainerFactory; 032import org.jdtaus.core.container.PropertyException; 033 034/** 035 * {@code JFormattedTextField} supporting the {@code Kontonummer} type. 036 * <p>This textfield uses the {@link Kontonummer} type for parsing and formatting. An empty string value is treated as 037 * {@code null}. Property {@code format} controls formatting and takes one of the format constants defined in class 038 * {@code Kontonummer}. 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 Kontonummer#parse(String)} method throws a {@code ParseException}.</p> 042 * 043 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a> 044 * @version $JDTAUS: KontonummerTextField.java 8864 2014-01-10 17:13:30Z schulte $ 045 */ 046public final class KontonummerTextField extends JFormattedTextField 047{ 048 049 /** Serial version UID for backwards compatibility with 1.1.x classes. */ 050 private static final long serialVersionUID = -959284086262750493L; 051 052 /** 053 * Format used to format Kontonummer 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 KontonummerTextField} instance. */ 065 public KontonummerTextField() 066 { 067 super(); 068 this.assertValidProperties(); 069 this.setColumns( Kontonummer.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 = Kontonummer.parse( text ); 085 } 086 087 return value; 088 } 089 090 public String valueToString( final Object value ) throws ParseException 091 { 092 String ret = null; 093 094 if ( value instanceof Kontonummer ) 095 { 096 final Kontonummer kto = (Kontonummer) value; 097 ret = kto.format( getFormat() ); 098 } 099 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}