Source Code Cross Referenced for RuleInputField.java in  » Installer » IzPack » com » izforge » izpack » panels » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Installer » IzPack » com.izforge.izpack.panels 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * IzPack - Copyright 2001-2008 Julien Ponge, All Rights Reserved.
003:         * 
004:         * http://izpack.org/
005:         * http://izpack.codehaus.org/
006:         * 
007:         * Copyright 2002 Elmar Grom
008:         * 
009:         * Licensed under the Apache License, Version 2.0 (the "License");
010:         * you may not use this file except in compliance with the License.
011:         * You may obtain a copy of the License at
012:         * 
013:         *     http://www.apache.org/licenses/LICENSE-2.0
014:         *     
015:         * Unless required by applicable law or agreed to in writing, software
016:         * distributed under the License is distributed on an "AS IS" BASIS,
017:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018:         * See the License for the specific language governing permissions and
019:         * limitations under the License.
020:         */
021:
022:        package com.izforge.izpack.panels;
023:
024:        import java.awt.Toolkit;
025:        import java.awt.event.FocusEvent;
026:        import java.awt.event.FocusListener;
027:        import java.awt.event.KeyEvent;
028:        import java.awt.event.KeyListener;
029:        import java.util.Map;
030:        import java.util.StringTokenizer;
031:        import java.util.Vector;
032:        import java.io.Serializable;
033:
034:        import javax.swing.JComponent;
035:        import javax.swing.JLabel;
036:        import javax.swing.JTextField;
037:        import javax.swing.event.CaretEvent;
038:        import javax.swing.event.CaretListener;
039:
040:        import org.apache.regexp.RE;
041:
042:        import com.izforge.izpack.installer.InstallData;
043:        import com.izforge.izpack.util.Debug;
044:        import com.izforge.izpack.util.VariableSubstitutor;
045:
046:        /*---------------------------------------------------------------------------*/
047:        /**
048:         * This class assists the user in entering serial numbers. <BR>
049:         * <BR>
050:         * Serial numbers, license number, CD keys and the like are often lenghty alpha-numerical numbers.
051:         * In many cases they are devided into multiple parts by dash or point separators. Entering these in
052:         * a single text field can be a frustrating experience for the user. This class provides a way of
053:         * presenting the user with an assembly of input fields that are arranged in the same way as the
054:         * key, with the separators already in place. Immideate testing for format compliance if performed
055:         * ans soon as each field is completed. In addition, the cursor is automatically advanced to make
056:         * entering numbers as painless as possible. <br>
057:         * <br>
058:         * <b>Formatting:</b>
059:         * 
060:         * <ul>
061:         * <li><code>N:X:Y </code>- numeric field, accepts digits only
062:         * <li><code>H:X:Y </code>- hex field, accepts only hexadecimal digits
063:         * <li><code>A:X:Y </code>- alpha field, accepts only letters, no digits
064:         * <li><code>AN:X:Y</code>- alpha-numeric field, accepts digits and letters
065:         * </ul>
066:         * <b>Example:</b> <br>
067:         * <br>
068:         * <code>"N:4:4 - H:6:6 - AN:3:3 x A:5:5"</code><br>
069:         * <br>
070:         * This formatting string will produce a serial number field consisting of four separate input
071:         * fields. The fisrt input field will accept four numeric digits, the second six hexa-decimal
072:         * digits, the third three alpha-numeric digits and the fourth five letters. The first three input
073:         * fields will be separated by '-' and the third and fourth by 'x'. The following snapshot was
074:         * obtained with this setting: <br>
075:         * <br>
076:         * <img src="doc-files/RuleInputField-1.gif"/>
077:         * 
078:         * @version 0.0.1 / 10/19/02
079:         * @author Elmar Grom
080:         */
081:        /*---------------------------------------------------------------------------*/
082:        public class RuleInputField extends JComponent implements  KeyListener,
083:                FocusListener, CaretListener, ProcessingClient {
084:
085:            /**
086:             * 
087:             */
088:            private static final long serialVersionUID = 3832616275124958257L;
089:
090:            /**
091:             * Used to specify the retsult format. This constant specifies to return the contents of all
092:             * fields concatenated into one long string, with separation between each component.
093:             */
094:            public static final int PLAIN_STRING = 1;
095:
096:            /**
097:             * Used to specify the retsult format. This constant specifies to return the contents of all
098:             * fields together with all separators as specified in the field format concatenated into one
099:             * long string. In this case the resulting string looks just like the user saw it during data
100:             * entry
101:             */
102:            public static final int DISPLAY_FORMAT = 2;
103:
104:            /**
105:             * Used to specify the retsult format. This constant specifies to return the contents of all
106:             * fields concatenated into one long string, with a special separator string inserted in between
107:             * the individual components.
108:             */
109:            public static final int SPECIAL_SEPARATOR = 3;
110:
111:            /**
112:             * Used to specify the retsult format. This constant specifies to return the contents of all
113:             * fields in a somehow modified way. How the content is modified depends on the operation
114:             * performed by a encryption service class. The class must be provided at object instatiation.
115:             */
116:            public static final int ENCRYPTED = 4;
117:
118:            /** Used internally to identify the default setting for the return format. */
119:            private static int DEFAULT = DISPLAY_FORMAT;
120:
121:            private Vector<Serializable> items = new Vector<Serializable>();
122:
123:            /**
124:             * This <code>Vector</code> holds a reference to each input field, in the order in which they
125:             * appear on the screen.
126:             */
127:            private Vector inputFields = new Vector();
128:
129:            private boolean hasParams = false;
130:
131:            private Map<String, String> validatorParams;
132:
133:            private RuleTextField activeField;
134:
135:            private boolean backstep = false;
136:
137:            private Toolkit toolkit;
138:
139:            private String separator;
140:
141:            private int resultFormat = DEFAULT;
142:
143:            private InstallData idata = null;
144:
145:            /**
146:             * Holds an instance of the <code>Validator</code> if one was specified and available
147:             */
148:            private Validator validationService;
149:
150:            /**
151:             * Holds an instance of the <code>Processor</code> if one was specified and available
152:             */
153:            private Processor encryptionService;
154:
155:            /*--------------------------------------------------------------------------*/
156:            // javadoc inherited
157:            public boolean hasParams() {
158:                return hasParams;
159:            }
160:
161:            /*--------------------------------------------------------------------------*/
162:            /**
163:             * Constructs a rule input field.
164:             * 
165:             * @param format a string that specifies the formatting and to a limited degree the behavior of
166:             * this field.
167:             * @param preset a string that specifies preset values for specific sub-fields.
168:             * @param separator a string to be used for separating the contents of individual fields in the
169:             * string returned by <code>getText()</code>
170:             * @param validator A string that specifies a class to perform validation services. The string
171:             * must completely identify the class, so that it can be instantiated. The class must implement
172:             * the <code>RuleValidator</code> interface. If an attempt to instantiate this class fails, no
173:             * validation will be performed.
174:             * @param validatorParams A <code>java.util.Map</code> containing name/ value pairs, which
175:             * will be forwarded to the validator.
176:             * @param processor A string that specifies a class to perform processing services. The string
177:             * must completely identify the class, so that it can be instantiated. The class must implement
178:             * the <code>Processor</code> interface. If an attempt to instantiate this class fails, no
179:             * processing will be performed. Instead, the text is returned in the default formatting.
180:             * @param resultFormat specifies in which format the resulting text should be returned, wehn
181:             * <code>getText()</code> is called. The following values are legal:<br>
182:             * <ul>
183:             * <li>PLAIN_STRING
184:             * <li>DISPLAY_FORMAT
185:             * <li>SPECIAL_SEPARATOR
186:             * <li>ENCRYPTED
187:             * </ul>
188:             * @param toolkit needed to gain access to <code>beep()</code>
189:             */
190:            /*--------------------------------------------------------------------------*/
191:            public RuleInputField(String format, String preset,
192:                    String separator, String validator,
193:                    Map<String, String> validatorParams, String processor,
194:                    int resultFormat, Toolkit toolkit, InstallData idata) {
195:                this (format, preset, separator, validator, processor,
196:                        resultFormat, toolkit, idata);
197:                this .validatorParams = validatorParams;
198:                this .hasParams = true;
199:            }
200:
201:            /*--------------------------------------------------------------------------*/
202:            /**
203:             * Constructs a rule input field.
204:             * 
205:             * @param format a string that specifies the formatting and to a limited degree the behavior of
206:             * this field.
207:             * @param preset a string that specifies preset values for specific sub-fields.
208:             * @param separator a string to be used for separating the contents of individual fields in the
209:             * string returned by <code>getText()</code>
210:             * @param validator A string that specifies a class to perform validation services. The string
211:             * must completely identify the class, so that it can be instantiated. The class must implement
212:             * the <code>RuleValidator</code> interface. If an attempt to instantiate this class fails, no
213:             * validation will be performed.
214:             * @param processor A string that specifies a class to perform processing services. The string
215:             * must completely identify the class, so that it can be instantiated. The class must implement
216:             * the <code>Processor</code> interface. If an attempt to instantiate this class fails, no
217:             * processing will be performed. Instead, the text is returned in the default formatting.
218:             * @param resultFormat specifies in which format the resulting text should be returned, wehn
219:             * <code>getText()</code> is called. The following values are legal:<br>
220:             * <ul>
221:             * <li>PLAIN_STRING
222:             * <li>DISPLAY_FORMAT
223:             * <li>SPECIAL_SEPARATOR
224:             * <li>ENCRYPTED
225:             * </ul>
226:             * @param toolkit needed to gain access to <code>beep()</code>
227:             */
228:            /*--------------------------------------------------------------------------*/
229:            public RuleInputField(String format, String preset,
230:                    String separator, String validator, String processor,
231:                    int resultFormat, Toolkit toolkit, InstallData idata) {
232:                this .toolkit = toolkit;
233:                this .separator = separator;
234:                this .resultFormat = resultFormat;
235:                this .idata = idata;
236:
237:                com.izforge.izpack.gui.FlowLayout layout = new com.izforge.izpack.gui.FlowLayout();
238:                layout.setAlignment(com.izforge.izpack.gui.FlowLayout.LEFT);
239:                setLayout(layout);
240:
241:                // ----------------------------------------------------
242:                // attempt to create an instance of the Validator
243:                // ----------------------------------------------------
244:                try {
245:                    if (validator != null) {
246:                        validationService = (Validator) Class
247:                                .forName(validator).newInstance();
248:                    }
249:                } catch (Throwable exception) {
250:                    validationService = null;
251:                    Debug.trace(exception);
252:                }
253:
254:                // ----------------------------------------------------
255:                // attempt to create an instance of the Processor
256:                // ----------------------------------------------------
257:                try {
258:                    if (processor != null) {
259:                        encryptionService = (Processor) Class
260:                                .forName(processor).newInstance();
261:                    }
262:                } catch (Throwable exception) {
263:                    encryptionService = null;
264:                    Debug.trace(exception);
265:                }
266:
267:                // ----------------------------------------------------
268:                // create the fields and field separators
269:                // ----------------------------------------------------
270:                createItems(format);
271:
272:                if ((preset != null) && (preset.length() > 0)) {
273:                    setFields(preset);
274:                }
275:
276:                // ----------------------------------------------------
277:                // set the focus to the first field
278:                // ----------------------------------------------------
279:                activeField = (RuleTextField) inputFields.elementAt(0);
280:                activeField.grabFocus();
281:            }
282:
283:            /*--------------------------------------------------------------------------*/
284:            /**
285:             * Returns the number of sub-fields composing this <code>RuleInputField</code>.
286:             * 
287:             * @return the number of sub-fields
288:             */
289:            /*--------------------------------------------------------------------------*/
290:            public int getNumFields() {
291:                return (inputFields.size());
292:            }
293:
294:            /*--------------------------------------------------------------------------*/
295:            /**
296:             * Returns the contents of the field indicated by <code>index</code>.
297:             * 
298:             * @param index the index of the sub-field from which the contents is requested.
299:             * 
300:             * @return the contents of the indicated sub-field.
301:             * 
302:             * @exception IndexOutOfBoundsException if the index is out of bounds.
303:             */
304:            /*--------------------------------------------------------------------------*/
305:            public String getFieldContents(int index)
306:                    throws IndexOutOfBoundsException {
307:                if ((index < 0) || (index > (inputFields.size() - 1))) {
308:                    throw (new IndexOutOfBoundsException());
309:                }
310:
311:                return (((JTextField) inputFields.elementAt(index)).getText());
312:            }
313:
314:            /*--------------------------------------------------------------------------*/
315:            // javadoc inherited
316:            public Map<String, String> getValidatorParams() {
317:                return validatorParams;
318:            }
319:
320:            /*---------------------------------------------------------------------------*/
321:            /**
322:             * Returns the field contents, assembled acording to the encryption and separator rules.
323:             * 
324:             * @return the field contents
325:             */
326:            /*--------------------------------------------------------------------------*/
327:            public String getText() {
328:                Object item;
329:                StringBuffer buffer = new StringBuffer();
330:                int size = inputFields.size();
331:
332:                // ----------------------------------------------------
333:                // have the encryption service class perfrom the task
334:                // of assembling an output string. If we have no instance
335:                // of this class available set the formatting
336:                // instruction to the default setting.
337:                // ----------------------------------------------------
338:                if (resultFormat == ENCRYPTED) {
339:                    if (encryptionService != null) {
340:                        buffer.append(encryptionService.process(this ));
341:                    } else {
342:                        resultFormat = DEFAULT;
343:                    }
344:                }
345:
346:                // ----------------------------------------------------
347:                // concatentate the field contents, with no separators
348:                // in between.
349:                // ----------------------------------------------------
350:                else if (resultFormat == PLAIN_STRING) {
351:                    for (int i = 0; i < inputFields.size(); i++) {
352:                        buffer.append(((JTextField) inputFields.elementAt(i))
353:                                .getText());
354:                    }
355:                }
356:
357:                // ----------------------------------------------------
358:                // concatenate the field contents and setarators, as
359:                // specified for the display of the field.
360:                // ----------------------------------------------------
361:                else if (resultFormat == DISPLAY_FORMAT) {
362:                    for (int i = 0; i < items.size(); i++) {
363:                        item = items.elementAt(i);
364:                        if (item instanceof  JTextField) {
365:                            buffer.append(((JTextField) item).getText());
366:                        } else {
367:                            buffer.append((String) item);
368:                        }
369:                    }
370:                }
371:
372:                // ----------------------------------------------------
373:                // concatenate the field contents and insert the
374:                // separator string in between.
375:                // ----------------------------------------------------
376:                else if (resultFormat == SPECIAL_SEPARATOR) {
377:                    for (int i = 0; i < size; i++) {
378:                        buffer.append(((JTextField) inputFields.elementAt(i))
379:                                .getText());
380:
381:                        if (i < (size - 1)) {
382:                            buffer.append(separator);
383:                        }
384:                    }
385:                }
386:
387:                return (buffer.toString());
388:            }
389:
390:            /*--------------------------------------------------------------------------*/
391:            /**
392:             * Creates the items that make up this field. Both separators and input fields are considered
393:             * items. The items created are stored in <code>items</code>. In addition, all fields are
394:             * stored in <code>inputFields</code>.
395:             * 
396:             * @param format a string that specifies the layout of the input fields and separators.
397:             */
398:            /*--------------------------------------------------------------------------*/
399:            /*
400:             * $ @design
401:             * 
402:             * I used a simple StringTokenizer to break the format string into individual tokens. The
403:             * approach in building up the field is to consider each token a potential definition for an
404:             * input field. Therefore I attempt to create an instance of FieldSpec from each token.
405:             * FieldSpec analyzes the token and if it does not represent a valid specification for an input
406:             * field throws an exception. If I catch an exception, I know the token does not represent a
407:             * valid field specification. In this case I treat the token as a separator, even though this
408:             * might not be what the user had intended. However, this approach allows me to implement robust
409:             * behavior (no exception thrown) even though the user might have made a mistake in the
410:             * definition. The mistake should become immediately obvious when testing the code, since a
411:             * input field definition would show up as separator between two fields.
412:             * --------------------------------------------------------------------------
413:             */
414:            private void createItems(String format) {
415:                Object item;
416:                JTextField field;
417:                String token;
418:                FieldSpec spec;
419:                StringTokenizer tokenizer = new StringTokenizer(format);
420:
421:                while (tokenizer.hasMoreTokens()) {
422:                    token = tokenizer.nextToken();
423:                    try {
424:                        spec = new FieldSpec(token);
425:                        field = new RuleTextField(spec.getColumns(), spec
426:                                .getEditLength(), spec.getType(), spec
427:                                .getUnlimitedEdit(), toolkit);
428:
429:                        // ------------------------------------------------
430:                        // if the previous item is also a field, insert a
431:                        // space as separator
432:                        // ------------------------------------------------
433:                        if (items.size() > 0) {
434:                            item = items.lastElement();
435:
436:                            if (item instanceof  JTextField) {
437:                                items.add(" ");
438:                            }
439:                        }
440:
441:                        items.add(field);
442:                        inputFields.add(field);
443:                        field.addFocusListener(this );
444:                        field.addKeyListener(this );
445:                        field.addCaretListener(this );
446:                    }
447:                    // --------------------------------------------------
448:                    // if we were not successful creating an input field,
449:                    // the token must be a separator or the definition
450:                    // has an error. Simply insert it as separator,
451:                    // when testing the installer the error should become
452:                    // obvious to the developer.
453:                    // --------------------------------------------------
454:                    catch (Throwable exception) {
455:                        if (items.size() == 0) {
456:                            items.add(token);
457:                        } else {
458:                            item = items.lastElement();
459:
460:                            // ----------------------------------------------
461:                            // if the previous item is also a separator,
462:                            // simply concatenate the token with a space
463:                            // inserted in between, don't add it as new
464:                            // separator.
465:                            // ----------------------------------------------
466:                            if (item instanceof  String) {
467:                                items.setElementAt(item + " " + token, (items
468:                                        .size() - 1));
469:                            } else {
470:                                items.add(token);
471:                            }
472:                        }
473:                    }
474:                }
475:
476:                // ----------------------------------------------------
477:                // add the fields and separators to the component
478:                // ----------------------------------------------------
479:                for (int i = 0; i < items.size(); i++) {
480:                    item = items.elementAt(i);
481:
482:                    if (item instanceof  String) {
483:                        add(new JLabel((String) item));
484:                    } else {
485:                        add((JTextField) item);
486:                    }
487:                }
488:            }
489:
490:            /*--------------------------------------------------------------------------*/
491:            /**
492:             * Sets each field to a pre-defined value.
493:             * 
494:             * @param data a <code>String</code> containing the preset values for each field. The format
495:             * of the string is as follows: The content for the individuals fields must be separated by
496:             * whitespace. Each data block is preceeded by the index of the field to set (counting starts at
497:             * 0) followed by a colon ':'and after that the actual data for the field.
498:             */
499:            /*--------------------------------------------------------------------------*/
500:            private void setFields(String data) {
501:                StringTokenizer tokenizer = new StringTokenizer(data);
502:                String token;
503:                String indexString;
504:                int index;
505:                boolean process = false;
506:                String[] vals = null;
507:                int i = 0;
508:
509:                vals = new String[tokenizer.countTokens()];
510:                while (tokenizer.hasMoreTokens()) {
511:                    token = tokenizer.nextToken();
512:                    indexString = token.substring(0, token.indexOf(':'));
513:
514:                    try {
515:                        index = Integer.parseInt(indexString);
516:                        if (index < inputFields.size()) {
517:                            String val = token.substring(
518:                                    (token.indexOf(':') + 1), token.length());
519:                            String className = "";
520:                            if (val.indexOf(":") > -1) {
521:                                className = val.substring(val.indexOf(":") + 1);
522:                                val = val.substring(0, val.indexOf(":"));
523:                            }
524:
525:                            if (!"".equals(className) && !process) {
526:                                process = true;
527:                            }
528:                            VariableSubstitutor vs = new VariableSubstitutor(
529:                                    idata.getVariables());
530:                            val = vs.substitute(val, null);
531:                            vals[i] = val;
532:                            i++;
533:                            ((JTextField) inputFields.elementAt(index))
534:                                    .setText(val);
535:                        }
536:                    } catch (Throwable exception) {
537:                        exception.printStackTrace();
538:                    }
539:                }
540:
541:                if (process) {
542:                    tokenizer = new StringTokenizer(data);
543:                    while (tokenizer.hasMoreTokens()) {
544:                        token = tokenizer.nextToken();
545:                        indexString = token.substring(0, token.indexOf(':'));
546:
547:                        try {
548:                            index = Integer.parseInt(indexString);
549:                            if (index < inputFields.size()) {
550:                                String val = token.substring((token
551:                                        .indexOf(':') + 1), token.length());
552:                                String className = "";
553:                                String presult = "";
554:                                if (val.indexOf(":") > -1) {
555:                                    className = val
556:                                            .substring(val.indexOf(":") + 1);
557:                                    val = val.substring(0, val.indexOf(":"));
558:                                }
559:
560:                                if (!"".equals(className)) {
561:                                    Processor p = (Processor) Class.forName(
562:                                            className).newInstance();
563:                                    presult = p.process(this );
564:                                }
565:                                String[] td = new RE("\\*").split(presult);
566:                                ((JTextField) inputFields.elementAt(index))
567:                                        .setText(td[index]);
568:                            }
569:                        } catch (Throwable exception) {
570:                        }
571:                    }
572:                }
573:            }
574:
575:            /*--------------------------------------------------------------------------*/
576:            /**
577:             * This method validates the field content. Validating is performed through a user supplied
578:             * service class that provides the validation rules.
579:             * 
580:             * @return <code>true</code> if the validation passes or no implementation of a validation
581:             * rule exists. Otherwise <code>false</code> is returned.
582:             */
583:            /*--------------------------------------------------------------------------*/
584:            public boolean validateContents() {
585:                if (validationService != null) {
586:                    return (validationService.validate(this ));
587:                } else {
588:                    return (true);
589:                }
590:            }
591:
592:            /*---------------------------------------------------------------------------*
593:             Implementation for KeyListener
594:             *---------------------------------------------------------------------------*/
595:
596:            /*--------------------------------------------------------------------------*/
597:            /**
598:             * This method is invoked when a key has been typed. The event occurs when a key press is
599:             * followed by a key release.
600:             * 
601:             * @param event the key event forwarded by the system.
602:             */
603:            /*--------------------------------------------------------------------------*/
604:            public void keyTyped(KeyEvent event) {
605:            }
606:
607:            /*--------------------------------------------------------------------------*/
608:            /**
609:             * This method is invoked when a key has been pressed. This method verifies the condition of the
610:             * input field in focus. Once the column count in the field has reached the specified maximum,
611:             * the rule specified for the field in question is invoked. In case the test result is positive,
612:             * focus is set to the next field. If hte test result is negative, the field content is marked
613:             * and the caret set to the start of the field.
614:             * 
615:             * @param event the key event forwarded by the system.
616:             */
617:            /*--------------------------------------------------------------------------*/
618:            public void keyPressed(KeyEvent event) {
619:                if (event.getKeyCode() == KeyEvent.VK_BACK_SPACE) {
620:                    int caretPosition = activeField.getCaretPosition();
621:
622:                    if (caretPosition == 0) {
623:                        int activeIndex = inputFields.indexOf(activeField);
624:
625:                        if (activeIndex > 0) {
626:                            activeIndex--;
627:                            backstep = true;
628:                            activeField = (RuleTextField) inputFields
629:                                    .elementAt(activeIndex);
630:                            activeField.grabFocus();
631:                        }
632:                    }
633:                }
634:            }
635:
636:            /*--------------------------------------------------------------------------*/
637:            /**
638:             * This method is invoked when a key has been released.
639:             * 
640:             * @param event the key event forwarded by the system.
641:             */
642:            /*--------------------------------------------------------------------------*/
643:            public void keyReleased(KeyEvent event) {
644:            }
645:
646:            /*---------------------------------------------------------------------------*
647:             Implementation for FocusListener
648:             *---------------------------------------------------------------------------*/
649:
650:            /*--------------------------------------------------------------------------*/
651:            /**
652:             * Invoked when a component gains the keyboard focus.
653:             * 
654:             * @param event the focus event forwardes by the sytem.
655:             */
656:            /*--------------------------------------------------------------------------*/
657:            /*
658:             * $ @design <- keep this tag in place and don't write on this line!
659:             * 
660:             * Enter design related documentation here.
661:             * --------------------------------------------------------------------------
662:             */
663:            public void focusGained(FocusEvent event) {
664:                activeField = (RuleTextField) event.getSource();
665:
666:                if (backstep) {
667:                    activeField
668:                            .setCaretPosition(activeField.getText().length());
669:                    backstep = false;
670:                } else {
671:                    activeField.selectAll();
672:                }
673:            }
674:
675:            /*--------------------------------------------------------------------------*/
676:            /**
677:             * Invoked when a component loses the keyboard focus. This method does nothing, we are only
678:             * interested in 'focus gained' events.
679:             * 
680:             * @param event the focus event forwardes by the sytem.
681:             */
682:            /*--------------------------------------------------------------------------*/
683:            public void focusLost(FocusEvent event) {
684:            }
685:
686:            /*---------------------------------------------------------------------------*
687:             Implementation for CaretListener
688:             *---------------------------------------------------------------------------*/
689:
690:            /*--------------------------------------------------------------------------*/
691:            /**
692:             * Called when the caret position is updated.
693:             * 
694:             * @param event the caret event received from the text field
695:             */
696:            /*--------------------------------------------------------------------------*/
697:            public void caretUpdate(CaretEvent event) {
698:                if (activeField != null) {
699:                    String text = activeField.getText();
700:                    int fieldSize = activeField.getEditLength();
701:                    int caretPosition = activeField.getCaretPosition();
702:                    int selection = activeField.getSelectionEnd()
703:                            - activeField.getSelectionStart();
704:
705:                    if ((!inputFields.lastElement().equals(activeField))
706:                            && (!activeField.unlimitedEdit())) {
707:                        if ((text.length() == fieldSize) && (selection == 0)
708:                                && (caretPosition == fieldSize) && !backstep) {
709:                            activeField.transferFocus();
710:                        }
711:                    }
712:                }
713:            }
714:
715:            // ----------------------------------------------------------------------------
716:            //
717:            // ----------------------------------------------------------------------------
718:            private static class FieldSpec {
719:
720:                private int MIN_TOKENS = 2;
721:
722:                private int MAX_TOKENS = 3;
723:
724:                private int type;
725:
726:                private int columns;
727:
728:                private int editLength;
729:
730:                private boolean unlimitedEdit = false;
731:
732:                public FieldSpec(String spec) throws Exception {
733:                    StringTokenizer tokenizer = new StringTokenizer(spec, ":");
734:
735:                    if ((tokenizer.countTokens() >= MIN_TOKENS)
736:                            && (tokenizer.countTokens() <= MAX_TOKENS)) {
737:                        String token = tokenizer.nextToken().toUpperCase();
738:                        // ------------------------------------------------
739:                        // test the first token for a valid type identifier
740:                        // if it's valid assign the token to the type.
741:                        // ------------------------------------------------
742:                        if ("N".equals(token)) {
743:                            type = RuleTextField.N;
744:                        } else if ("H".equals(token)) {
745:                            type = RuleTextField.H;
746:                        } else if ("A".equals(token)) {
747:                            type = RuleTextField.A;
748:                        } else if ("O".equals(token)) {
749:                            type = RuleTextField.O;
750:                        } else if ("AN".equals(token)) {
751:                            type = RuleTextField.AN;
752:                        } else {
753:                            throw (new Exception());
754:                        }
755:
756:                        // ------------------------------------------------
757:                        // test for a valid integer to define the size
758:                        // of the field and assing to columns.
759:                        // ------------------------------------------------
760:                        try {
761:                            token = tokenizer.nextToken();
762:                            columns = Integer.parseInt(token);
763:                        } catch (Throwable exception) {
764:                            throw (new Exception());
765:                        }
766:
767:                        // ------------------------------------------------
768:                        // test for a valid integer to define the edit
769:                        // length and assign to editLength. If this fails
770:                        // test for identifier for unlimited edit length.
771:                        // If this works, set unlimitedEdit to true.
772:                        // ------------------------------------------------
773:                        try {
774:                            token = tokenizer.nextToken().toUpperCase();
775:                            editLength = Integer.parseInt(token);
776:                        } catch (Throwable exception) {
777:                            if ("U".equals(token)) {
778:                                unlimitedEdit = true;
779:                            } else {
780:                                throw (new Exception());
781:                            }
782:                        }
783:
784:                    } else {
785:                        throw (new Exception());
786:                    }
787:                }
788:
789:                public int getColumns() {
790:                    return (columns);
791:                }
792:
793:                public int getEditLength() {
794:                    return (editLength);
795:                }
796:
797:                public int getType() {
798:                    return (type);
799:                }
800:
801:                public boolean getUnlimitedEdit() {
802:                    return (unlimitedEdit);
803:                }
804:
805:            }
806:            // ----------------------------------------------------------------------------
807:
808:        }
809:        /*---------------------------------------------------------------------------*/
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.