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 8661 2012-09-27 11:29:58Z 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( fb.getDocument().getLength() + s.length() ); 137 b.append( fb.getDocument().getText( 0, fb.getDocument().getLength() ) ); 138 b.replace( o, o + s.length(), s ); 139 140 try 141 { 142 Kontonummer.parse( b.toString() ); 143 } 144 catch ( ParseException e ) 145 { 146 invalidEdit(); 147 return; 148 } 149 } 150 151 super.replace( fb, o, l, s, a ); 152 } 153 154 }; 155 } 156 157 }; 158 } 159 160 } ); 161 } 162 163 /** 164 * Gets the last valid {@code Kontonummer}. 165 * 166 * @return the last valid {@code Kontonummer} or {@code null}. 167 */ 168 public Kontonummer getKontonummer() 169 { 170 return (Kontonummer) this.getValue(); 171 } 172 173 /** 174 * Gets the constant of the format used when formatting Kontonummer instances. 175 * 176 * @return the constant of the format used when formatting Kontonummer instances. 177 * 178 * @see Kontonummer#ELECTRONIC_FORMAT 179 * @see Kontonummer#LETTER_FORMAT 180 */ 181 public int getFormat() 182 { 183 if ( this.format == null ) 184 { 185 this.format = this.getDefaultFormat(); 186 } 187 188 return this.format.intValue(); 189 } 190 191 /** 192 * Sets the constant of the format to use when formatting Kontonummer instances. 193 * 194 * @param value the constant of the format to use when formatting Kontonummer instances. 195 * 196 * @throws IllegalArgumentException if {@code format} is neither {@code ELECTRONIC_FORMAT} nor 197 * {@code LETTER_FORMAT}. 198 * 199 * @see Kontonummer#ELECTRONIC_FORMAT 200 * @see Kontonummer#LETTER_FORMAT 201 */ 202 public void setFormat( final int value ) 203 { 204 if ( value != Kontonummer.ELECTRONIC_FORMAT && value != Kontonummer.LETTER_FORMAT ) 205 { 206 throw new IllegalArgumentException( Integer.toString( value ) ); 207 } 208 209 this.format = new Integer( value ); 210 } 211 212 /** 213 * Gets the flag indicating if validation is performed. 214 * 215 * @return {@code true} if the field's value is validated; {@code false} if no validation of the field's value is 216 * performed. 217 */ 218 public boolean isValidating() 219 { 220 if ( this.validating == null ) 221 { 222 this.validating = this.isDefaultValidating(); 223 } 224 225 return this.validating.booleanValue(); 226 } 227 228 /** 229 * Sets the flag indicating if validation should be performed. 230 * 231 * @param value {@code true} to validate the field's value; {@code false} to not validate the field's value. 232 */ 233 public void setValidating( boolean value ) 234 { 235 this.validating = Boolean.valueOf( value ); 236 } 237 238 /** 239 * Checks configured properties. 240 * 241 * @throws PropertyException for invalid property values. 242 */ 243 private void assertValidProperties() 244 { 245 if ( this.getFormat() != Kontonummer.ELECTRONIC_FORMAT && this.getFormat() != Kontonummer.LETTER_FORMAT ) 246 { 247 throw new PropertyException( "format", Integer.toString( this.getFormat() ) ); 248 } 249 } 250 251 //--Properties-------------------------------------------------------------- 252 253// <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:jdtausProperties 254 // This section is managed by jdtaus-container-mojo. 255 256 /** 257 * Gets the value of property <code>defaultValidating</code>. 258 * 259 * @return Default value of the flag indicating if validation should be performed. 260 */ 261 private java.lang.Boolean isDefaultValidating() 262 { 263 return (java.lang.Boolean) ContainerFactory.getContainer(). 264 getProperty( this, "defaultValidating" ); 265 266 } 267 268 /** 269 * Gets the value of property <code>defaultFormat</code>. 270 * 271 * @return Default value of the format to use when formatting Kontonummer instances (4001 = electronic format, 4002 letter format). 272 */ 273 private java.lang.Integer getDefaultFormat() 274 { 275 return (java.lang.Integer) ContainerFactory.getContainer(). 276 getProperty( this, "defaultFormat" ); 277 278 } 279 280// </editor-fold>//GEN-END:jdtausProperties 281 282 //--------------------------------------------------------------Properties-- 283}