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 org.jdtaus.banking.AlphaNumericText27; 030import org.jdtaus.core.container.ContainerFactory; 031 032/** 033 * {@code JFormattedTextField} supporting the {@code AlphaNumericText27} type. 034 * <p>This textfield uses the {@link AlphaNumericText27} type for parsing and formatting. An empty string value is 035 * treated as {@code null}. The {@code normalizing} flag controls parsing. If {@code true} (default) the field's value 036 * is normalized using the {@link AlphaNumericText27#normalize(String)} method prior to parsing. The {@code validating} 037 * flag controls validation of values entered into the textfield. If {@code true} (default), a {@code DocumentFilter} is 038 * registered with the textfield disallowing invalid values, that is, values which are not {@code null} and not empty 039 * strings and for which the {@link AlphaNumericText27#parse(String)} method throws a {@code ParseException}.</p> 040 * 041 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a> 042 * @version $JDTAUS: AlphaNumericText27TextField.java 8661 2012-09-27 11:29:58Z schulte $ 043 */ 044public final class AlphaNumericText27TextField extends JFormattedTextField 045{ 046 047 /** Serial version UID for backwards compatibility with 1.1.x classes. */ 048 private static final long serialVersionUID = -8152767220100367519L; 049 050 /** 051 * Flag indicating if a normalizing parser is used. 052 * @serial 053 */ 054 private Boolean normalizing; 055 056 /** 057 * Flag indicating if validation is performed. 058 * @serial 059 */ 060 private Boolean validating; 061 062 /** Creates a new default {@code AlphaNumericText27TextField} instance. */ 063 public AlphaNumericText27TextField() 064 { 065 super(); 066 this.setColumns( AlphaNumericText27.MAX_LENGTH ); 067 this.setFormatterFactory( new AbstractFormatterFactory() 068 { 069 070 public AbstractFormatter getFormatter( final JFormattedTextField ftf ) 071 { 072 return new AbstractFormatter() 073 { 074 075 public Object stringToValue( final String text ) throws ParseException 076 { 077 Object value = null; 078 079 if ( text != null && text.trim().length() > 0 ) 080 { 081 value = AlphaNumericText27.parse( 082 isNormalizing() ? AlphaNumericText27.normalize( text ) : text ); 083 084 } 085 086 return value; 087 } 088 089 public String valueToString( final Object value ) throws ParseException 090 { 091 String ret = null; 092 093 if ( value instanceof AlphaNumericText27 ) 094 { 095 final AlphaNumericText27 txt = (AlphaNumericText27) value; 096 ret = txt.isEmpty() ? null : txt.format().trim(); 097 } 098 099 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 = 158 new StringBuffer( fb.getDocument().getLength() + s.length() ); 159 160 b.append( fb.getDocument().getText( 0, fb.getDocument().getLength() ) ); 161 b.replace( o, o + s.length(), s ); 162 163 try 164 { 165 AlphaNumericText27.parse( b.toString() ); 166 } 167 catch ( ParseException e ) 168 { 169 invalidEdit(); 170 return; 171 } 172 } 173 174 super.replace( fb, o, l, s, a ); 175 } 176 177 }; 178 } 179 180 }; 181 } 182 183 } ); 184 } 185 186 /** 187 * Gets the last valid {@code AlphaNumericText27}. 188 * 189 * @return the last valid {@code AlphaNumericText27} or {@code null}. 190 */ 191 public AlphaNumericText27 getAlphaNumericText27() 192 { 193 return (AlphaNumericText27) this.getValue(); 194 } 195 196 /** 197 * Gets the flag indicating if a normalizing parser is used. 198 * 199 * @return {@code true} if a normalizing parser is used; {@code false} if a strict parser is used 200 * (defaults to {@code true}). 201 */ 202 public boolean isNormalizing() 203 { 204 if ( this.normalizing == null ) 205 { 206 this.normalizing = this.isDefaultNormalizing(); 207 } 208 209 return this.normalizing.booleanValue(); 210 } 211 212 /** 213 * Sets the flag indicating if a normalizing parser should be used. 214 * 215 * @param value {@code true} to use a normalizing parser; {@code false} to use a strict parser 216 * (defaults to {@code true}). 217 */ 218 public void setNormalizing( final boolean value ) 219 { 220 this.normalizing = Boolean.valueOf( value ); 221 } 222 223 /** 224 * Gets the flag indicating if validation is performed. 225 * 226 * @return {@code true} if the field's value is validated; {@code false} if no validation of the field's value is 227 * performed. 228 */ 229 public boolean isValidating() 230 { 231 if ( this.validating == null ) 232 { 233 this.validating = this.isDefaultValidating(); 234 } 235 236 return this.validating.booleanValue(); 237 } 238 239 /** 240 * Sets the flag indicating if validation should be performed. 241 * 242 * @param value {@code true} to validate the field's value; {@code false} to not validate the field's value. 243 */ 244 public void setValidating( boolean value ) 245 { 246 this.validating = Boolean.valueOf( value ); 247 } 248 249 //--Properties-------------------------------------------------------------- 250 251// <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:jdtausProperties 252 // This section is managed by jdtaus-container-mojo. 253 254 /** 255 * Gets the value of property <code>defaultValidating</code>. 256 * 257 * @return Default value of the flag indicating if validation should be performed. 258 */ 259 private java.lang.Boolean isDefaultValidating() 260 { 261 return (java.lang.Boolean) ContainerFactory.getContainer(). 262 getProperty( this, "defaultValidating" ); 263 264 } 265 266 /** 267 * Gets the value of property <code>defaultNormalizing</code>. 268 * 269 * @return Default value of the flag indicating if a normalizing parser should be used. 270 */ 271 private java.lang.Boolean isDefaultNormalizing() 272 { 273 return (java.lang.Boolean) ContainerFactory.getContainer(). 274 getProperty( this, "defaultNormalizing" ); 275 276 } 277 278// </editor-fold>//GEN-END:jdtausProperties 279 280 //--------------------------------------------------------------Properties-- 281}