Source Code Cross Referenced for AbstractField.java in  » Web-Framework » Millstone » org » millstone » base » ui » 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 » Web Framework » Millstone » org.millstone.base.ui 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* *************************************************************************
002:         
003:         Millstone(TM) 
004:         Open Sourced User Interface Library for
005:         Internet Development with Java
006:
007:         Millstone is a registered trademark of IT Mill Ltd
008:         Copyright (C) 2000-2005 IT Mill Ltd
009:         
010:         *************************************************************************
011:
012:         This library is free software; you can redistribute it and/or
013:         modify it under the terms of the GNU Lesser General Public
014:         license version 2.1 as published by the Free Software Foundation.
015:
016:         This library is distributed in the hope that it will be useful,
017:         but WITHOUT ANY WARRANTY; without even the implied warranty of
018:         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
019:         Lesser General Public License for more details.
020:
021:         You should have received a copy of the GNU Lesser General Public
022:         License along with this library; if not, write to the Free Software
023:         Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
024:
025:         *************************************************************************
026:         
027:         For more information, contact:
028:         
029:         IT Mill Ltd                           phone: +358 2 4802 7180
030:         Ruukinkatu 2-4                        fax:  +358 2 4802 7181
031:         20540, Turku                          email: info@itmill.com
032:         Finland                               company www: www.itmill.com
033:         
034:         Primary source for MillStone information and releases: www.millstone.org
035:
036:         ********************************************************************** */
037:
038:        package org.millstone.base.ui;
039:
040:        import java.lang.reflect.Method;
041:        import java.util.Collection;
042:        import java.util.Collections;
043:        import java.util.Date;
044:        import java.util.Iterator;
045:        import java.util.LinkedList;
046:
047:        import org.millstone.base.data.Buffered;
048:        import org.millstone.base.data.Property;
049:        import org.millstone.base.data.Validatable;
050:        import org.millstone.base.data.Validator;
051:        import org.millstone.base.terminal.ErrorMessage;
052:        import org.millstone.base.terminal.PaintException;
053:        import org.millstone.base.terminal.PaintTarget;
054:
055:        /**
056:         * <p>
057:         * Abstract field component for implementing buffered property editors. The
058:         * field may hold an internal value, or it may be connected to any data source
059:         * that implements the {@link org.millstone.base.data.Property}interface.
060:         * <code>AbstractField</code> implements that interface itself, too, so
061:         * accessing the Property value represented by it is straightforward.
062:         * </p>
063:         * 
064:         * <p>
065:         * AbstractField also provides the {@link org.millstone.base.data.Buffered}
066:         * interface for buffering the data source value. By default the Field is in
067:         * write through-mode and {@link #setWriteThrough(boolean)}should be called to
068:         * enable buffering.
069:         * </p>
070:         * 
071:         * <p>
072:         * The class also supports {@link org.millstone.base.data.Validator validators}
073:         * to make sure the value contained in the field is valid.
074:         * </p>
075:         * 
076:         * @author IT Mill Ltd.
077:         * @version
078:         * 3.1.1
079:         * @since 3.0
080:         */
081:        public abstract class AbstractField extends AbstractComponent implements 
082:                Field, Property.ReadOnlyStatusChangeNotifier {
083:
084:            /* Private members ************************************************* */
085:
086:            private boolean delayedFocus;
087:
088:            /** Value of the datafield */
089:            private Object value;
090:
091:            /** Connected data-source. */
092:            private Property dataSource = null;
093:
094:            /** The list of validators. */
095:            private LinkedList validators = null;
096:
097:            /** Auto commit mode. */
098:            private boolean writeTroughMode = true;
099:
100:            /** Read the value from data-source, when it is not modified. */
101:            private boolean readTroughMode = true;
102:
103:            /** Is the field modified but not committed. */
104:            private boolean modified = false;
105:
106:            /** Current source exception */
107:            private Buffered.SourceException currentBufferedSourceException = null;
108:
109:            /** Are the invalid values alloved in fields ? */
110:            private boolean invalidAllowed = true;
111:
112:            /** Are the invalid values committed */
113:            private boolean invalidCommitted = false;
114:
115:            /** The tab order number of this field */
116:            private int tabIndex = 0;
117:
118:            /** Unique focusable id */
119:            private long focusableId = -1;
120:
121:            /** Required field */
122:            private boolean required = false;
123:
124:            /* Component basics ************************************************ */
125:
126:            public AbstractField() {
127:                this .focusableId = Window.getNewFocusableId(this );
128:            }
129:
130:            /*
131:             * Paint the field. Don't add a JavaDoc comment here, we use the default
132:             * documentation from the implemented interface.
133:             */
134:            public void paintContent(PaintTarget target) throws PaintException {
135:
136:                // Focus control id
137:                if (this .focusableId > 0) {
138:                    target.addAttribute("focusid", this .focusableId);
139:                }
140:
141:                // The tab ordering number
142:                if (this .tabIndex > 0)
143:                    target.addAttribute("tabindex", this .tabIndex);
144:
145:                // If the field is modified, but not committed, set modified attribute
146:                if (isModified())
147:                    target.addAttribute("modified", true);
148:
149:                // Add required attribute
150:                if (isRequired())
151:                    target.addAttribute("required", true);
152:
153:            }
154:
155:            /*
156:             * Gets the field type Don't add a JavaDoc comment here, we use the default
157:             * documentation from the implemented interface.
158:             */
159:            public abstract Class getType();
160:
161:            /**
162:             * The abstract field is read only also if the data source is in readonly
163:             * mode.
164:             */
165:            public boolean isReadOnly() {
166:                return super .isReadOnly()
167:                        || (dataSource != null && dataSource.isReadOnly());
168:            }
169:
170:            /**
171:             * Change the readonly state and throw read-only status change events.
172:             * 
173:             * @see org.millstone.base.ui.Component#setReadOnly(boolean)
174:             */
175:            public void setReadOnly(boolean readOnly) {
176:                super .setReadOnly(readOnly);
177:                fireReadOnlyStatusChange();
178:            }
179:
180:            /* Buffering ******************************************************* */
181:
182:            public boolean isInvalidCommitted() {
183:                return invalidCommitted;
184:            }
185:
186:            public void setInvalidCommitted(boolean isCommitted) {
187:                this .invalidCommitted = isCommitted;
188:            }
189:
190:            /*
191:             * Save the current value to the data source Don't add a JavaDoc comment
192:             * here, we use the default documentation from the implemented interface.
193:             */
194:            public void commit() throws Buffered.SourceException {
195:                if (dataSource != null && (isInvalidCommitted() || isValid())
196:                        && !dataSource.isReadOnly()) {
197:                    Object newValue = getValue();
198:                    try {
199:
200:                        // Commit the value to datasource
201:                        dataSource.setValue(newValue);
202:
203:                    } catch (Throwable e) {
204:
205:                        // Set the buffering state
206:                        currentBufferedSourceException = new Buffered.SourceException(
207:                                this , e);
208:                        requestRepaint();
209:
210:                        // Throw the source exception
211:                        throw currentBufferedSourceException;
212:                    }
213:                }
214:
215:                boolean repaintNeeded = false;
216:
217:                // The abstract field is not modified anymore
218:                if (modified) {
219:                    modified = false;
220:                    repaintNeeded = true;
221:                }
222:
223:                // If successful, remove set the buffering state to be ok
224:                if (currentBufferedSourceException != null) {
225:                    currentBufferedSourceException = null;
226:                    repaintNeeded = true;
227:                }
228:
229:                if (repaintNeeded)
230:                    requestRepaint();
231:            }
232:
233:            /*
234:             * Update the value from the data source. Don't add a JavaDoc comment here,
235:             * we use the default documentation from the implemented interface.
236:             */
237:            public void discard() throws Buffered.SourceException {
238:                if (dataSource != null) {
239:
240:                    // Get the correct value from datasource
241:                    Object newValue;
242:                    try {
243:
244:                        // Discard buffer by overwriting from datasource
245:                        newValue = dataSource.getValue();
246:
247:                        // If successful, remove set the buffering state to be ok
248:                        if (currentBufferedSourceException != null) {
249:                            currentBufferedSourceException = null;
250:                            requestRepaint();
251:                        }
252:                    } catch (Throwable e) {
253:
254:                        // Set the buffering state
255:                        currentBufferedSourceException = new Buffered.SourceException(
256:                                this , e);
257:                        requestRepaint();
258:
259:                        // Throw the source exception
260:                        throw currentBufferedSourceException;
261:                    }
262:
263:                    boolean wasModified = isModified();
264:                    modified = false;
265:
266:                    // If the new value differs from the previous one
267:                    if ((newValue == null && value != null)
268:                            || (newValue != null && !newValue.equals(value))) {
269:                        setInternalValue(newValue);
270:                        fireValueChange();
271:                    }
272:
273:                    // If the value did not change, but the modification status did
274:                    else if (wasModified) {
275:                        requestRepaint();
276:                    }
277:                }
278:            }
279:
280:            /*
281:             * Has the field been modified since the last commit()? Don't add a JavaDoc
282:             * comment here, we use the default documentation from the implemented
283:             * interface.
284:             */
285:            public boolean isModified() {
286:                return modified;
287:            }
288:
289:            /*
290:             * Test if the field is in write-through mode. Don't add a JavaDoc comment
291:             * here, we use the default documentation from the implemented interface.
292:             */
293:            public boolean isWriteThrough() {
294:                return writeTroughMode;
295:            }
296:
297:            /*
298:             * Set the field's write-through mode to the specified status Don't add a
299:             * JavaDoc comment here, we use the default documentation from the
300:             * implemented interface.
301:             */
302:            public void setWriteThrough(boolean writeTrough)
303:                    throws Buffered.SourceException {
304:                if (writeTroughMode == writeTrough)
305:                    return;
306:                writeTroughMode = writeTrough;
307:                if (writeTroughMode)
308:                    commit();
309:            }
310:
311:            /*
312:             * Test if the field is in read-through mode. Don't add a JavaDoc comment
313:             * here, we use the default documentation from the implemented interface.
314:             */
315:            public boolean isReadThrough() {
316:                return readTroughMode;
317:            }
318:
319:            /*
320:             * Set the field's read-through mode to the specified status Don't add a
321:             * JavaDoc comment here, we use the default documentation from the
322:             * implemented interface.
323:             */
324:            public void setReadThrough(boolean readTrough)
325:                    throws Buffered.SourceException {
326:                if (readTroughMode == readTrough)
327:                    return;
328:                readTroughMode = readTrough;
329:                if (!isModified() && readTroughMode && dataSource != null) {
330:                    setInternalValue(dataSource.getValue());
331:                    fireValueChange();
332:                }
333:            }
334:
335:            /* Property interface implementation ******************************* */
336:
337:            /**
338:             * Returns the value of the Property in human readable textual format.
339:             * 
340:             * @return <code>String</code> representation of the value stored in the
341:             *         Property
342:             */
343:            public String toString() {
344:                Object value = getValue();
345:                if (value == null)
346:                    return null;
347:                return getValue().toString();
348:            }
349:
350:            /**
351:             * Gets the current value of the field. This is the visible, modified and
352:             * possible invalid value the user have entered to the field. In the
353:             * read-through mode, the abstract buffer is also updated and validation is
354:             * performed.
355:             * 
356:             * @return the current value of the field
357:             */
358:            public Object getValue() {
359:
360:                // Give the value from abstract buffers if the field if possible
361:                if (dataSource == null || !isReadThrough() || isModified())
362:                    return value;
363:
364:                Object newValue = dataSource.getValue();
365:                if ((newValue == null && value != null)
366:                        || (newValue != null && !newValue.equals(value))) {
367:                    setInternalValue(newValue);
368:                    fireValueChange();
369:                }
370:
371:                return newValue;
372:            }
373:
374:            /**
375:             * Set the value of the field.
376:             * 
377:             * @param newValue
378:             *            New value of the field.
379:             */
380:            public void setValue(Object newValue)
381:                    throws Property.ReadOnlyException,
382:                    Property.ConversionException {
383:
384:                if ((newValue == null && value != null)
385:                        || (newValue != null && !newValue.equals(value))) {
386:
387:                    // Read only fields can not be changed
388:                    if (isReadOnly())
389:                        throw new Property.ReadOnlyException();
390:
391:                    // If invalid values are not allowed, the value must be checked
392:                    if (!isInvalidAllowed()) {
393:                        Collection v = getValidators();
394:                        if (v != null)
395:                            for (Iterator i = v.iterator(); i.hasNext();)
396:                                ((Validator) i.next()).validate(newValue);
397:                    }
398:
399:                    // Change the value
400:                    setInternalValue(newValue);
401:                    modified = dataSource != null;
402:
403:                    // In write trough mode , try to commit
404:                    if (isWriteThrough() && dataSource != null
405:                            && (isInvalidCommitted() || isValid())) {
406:                        try {
407:
408:                            // Commit the value to datasource
409:                            dataSource.setValue(newValue);
410:
411:                            // The buffer is now unmodified
412:                            modified = false;
413:
414:                        } catch (Throwable e) {
415:
416:                            // Set the buffering state
417:                            currentBufferedSourceException = new Buffered.SourceException(
418:                                    this , e);
419:                            requestRepaint();
420:
421:                            // Throw the source exception
422:                            throw currentBufferedSourceException;
423:                        }
424:                    }
425:
426:                    // If successful, remove set the buffering state to be ok
427:                    if (currentBufferedSourceException != null) {
428:                        currentBufferedSourceException = null;
429:                        requestRepaint();
430:                    }
431:
432:                    // Fire value change
433:                    fireValueChange();
434:                }
435:            }
436:
437:            /* External data source ******************************************** */
438:
439:            /**
440:             * Gets the current data source of the field, if any.
441:             * 
442:             * @return The current data source as a Property, or <code>null</code> if
443:             *         none defined.
444:             */
445:            public Property getPropertyDataSource() {
446:                return dataSource;
447:            }
448:
449:            /**
450:             * <p>
451:             * Sets the specified Property as the data source for the field. All
452:             * uncommitted changes to the field are discarded and the value is refreshed
453:             * from the new data source.
454:             * </p>
455:             * 
456:             * <p>
457:             * If the datasource has any validators, the same validators are added to
458:             * the field. Because the default behavior of the field is to allow invalid
459:             * values, but not to allow committing them, this only adds visual error
460:             * messages to fields and do not allow committing them as long as the value
461:             * is invalid. After the value is valid, the error message is not shown and
462:             * the commit can be done normally.
463:             * </p>
464:             * 
465:             * @param newDataSource
466:             *            the new data source Property
467:             */
468:            public void setPropertyDataSource(Property newDataSource) {
469:
470:                // Save the old value
471:                Object oldValue = value;
472:
473:                // Discard all changes to old datasource
474:                try {
475:                    discard();
476:                } catch (Buffered.SourceException ignored) {
477:                }
478:
479:                // Stop listening the old data source changes
480:                if (dataSource != null
481:                        && Property.ValueChangeNotifier.class
482:                                .isAssignableFrom(dataSource.getClass()))
483:                    ((Property.ValueChangeNotifier) dataSource)
484:                            .removeListener(this );
485:
486:                // Set the new data source
487:                dataSource = newDataSource;
488:
489:                // Get the value from source
490:                try {
491:                    if (dataSource != null)
492:                        setInternalValue(dataSource.getValue());
493:                    modified = false;
494:                } catch (Throwable e) {
495:                    currentBufferedSourceException = new Buffered.SourceException(
496:                            this , e);
497:                    modified = true;
498:                }
499:
500:                // Listen the new data source if possible
501:                if (dataSource instanceof  Property.ValueChangeNotifier)
502:                    ((Property.ValueChangeNotifier) dataSource)
503:                            .addListener(this );
504:
505:                // Copy the validators from the data source
506:                if (dataSource instanceof  Validatable) {
507:                    Collection validators = ((Validatable) dataSource)
508:                            .getValidators();
509:                    if (validators != null)
510:                        for (Iterator i = validators.iterator(); i.hasNext();)
511:                            addValidator((Validator) i.next());
512:                }
513:
514:                // Fire value change if the value has changed
515:                if ((value != oldValue)
516:                        && ((value != null && !value.equals(oldValue)) || value == null))
517:                    fireValueChange();
518:            }
519:
520:            /* Validation ****************************************************** */
521:
522:            /**
523:             * Adds a new validator for the field's value. All validators added to a
524:             * field are checked each time the its value changes.
525:             * 
526:             * @param validator
527:             *            the new validator to be added
528:             */
529:            public void addValidator(Validator validator) {
530:                if (validators == null)
531:                    validators = new LinkedList();
532:                validators.add(validator);
533:            }
534:
535:            /**
536:             * Gets the validators of the field.
537:             * 
538:             * @return Unmodifiable collection that holds all validators for the field.
539:             */
540:            public Collection getValidators() {
541:                if (validators == null || validators.isEmpty())
542:                    return null;
543:                return Collections.unmodifiableCollection(validators);
544:            }
545:
546:            /**
547:             * Removes a validator from the field.
548:             * 
549:             * @param validator
550:             *            the validator to remove
551:             */
552:            public void removeValidator(Validator validator) {
553:                if (validators != null)
554:                    validators.remove(validator);
555:            }
556:
557:            /**
558:             * Tests the current value against all registered validators.
559:             * 
560:             * @return <code>true</code> if all registered validators claim that the
561:             *         current value is valid, <code>false</code> otherwise
562:             */
563:            public boolean isValid() {
564:
565:                if (validators == null)
566:                    return true;
567:
568:                Object value = getValue();
569:                for (Iterator i = validators.iterator(); i.hasNext();)
570:                    if (!((Validator) i.next()).isValid(value))
571:                        return false;
572:
573:                return true;
574:            }
575:
576:            public void validate() throws Validator.InvalidValueException {
577:
578:                // If there is no validator, there can not be any errors
579:                if (validators == null)
580:                    return;
581:
582:                // Initialize temps
583:                Validator.InvalidValueException firstError = null;
584:                LinkedList errors = null;
585:                Object value = getValue();
586:
587:                // Get all the validation errors
588:                for (Iterator i = validators.iterator(); i.hasNext();)
589:                    try {
590:                        ((Validator) i.next()).validate(value);
591:                    } catch (Validator.InvalidValueException e) {
592:                        if (firstError == null)
593:                            firstError = e;
594:                        else {
595:                            if (errors == null) {
596:                                errors = new LinkedList();
597:                                errors.add(firstError);
598:                            }
599:                            errors.add(e);
600:                        }
601:                    }
602:
603:                // If there were no error
604:                if (firstError == null)
605:                    return;
606:
607:                // If only one error occurred, throw it forwards
608:                if (errors == null)
609:                    throw firstError;
610:
611:                // Create composite validator
612:                Validator.InvalidValueException[] exceptions = new Validator.InvalidValueException[errors
613:                        .size()];
614:                int index = 0;
615:                for (Iterator i = errors.iterator(); i.hasNext();)
616:                    exceptions[index++] = (Validator.InvalidValueException) i
617:                            .next();
618:
619:                throw new Validator.InvalidValueException(null, exceptions);
620:            }
621:
622:            /**
623:             * Fields allow invalid values by default. In most cases this is wanted,
624:             * because the field otherwise visually forget the user input immediately.
625:             * 
626:             * @see org.millstone.base.data.Validatable#isInvalidAllowed()
627:             * 
628:             * @return true iff the invalid values are allowed.
629:             */
630:            public boolean isInvalidAllowed() {
631:                return invalidAllowed;
632:            }
633:
634:            /**
635:             * Fields allow invalid values by default. In most cases this is wanted,
636:             * because the field otherwise visually forget the user input immediately.
637:             * In common setting where the user wants to assure the correctness of the
638:             * datasource, but allow temporarily invalid contents in the field, the user
639:             * should add the validators to datasource, that should not allow invalid
640:             * values. The validators are automatically copied to the field when the
641:             * datasource is set.
642:             * 
643:             * @see org.millstone.base.data.Validatable#setInvalidAllowed(boolean)
644:             */
645:            public void setInvalidAllowed(boolean invalidAllowed)
646:                    throws UnsupportedOperationException {
647:                this .invalidAllowed = invalidAllowed;
648:            }
649:
650:            /**
651:             * Error messages shown by the fields are composites of the error message
652:             * thrown by the superclasses (that is the component error message),
653:             * validation errors and buffered source errors.
654:             * 
655:             * @see org.millstone.base.ui.AbstractComponent#getErrorMessage()
656:             */
657:            public ErrorMessage getErrorMessage() {
658:                ErrorMessage super Error = super .getErrorMessage();
659:                return super Error;
660:                /*
661:                 * TODO: Check the logic of this ErrorMessage validationError = null;
662:                 * try { validate(); } catch (Validator.InvalidValueException e) {
663:                 * validationError = e; }
664:                 * 
665:                 * if (superError == null && validationError == null &&
666:                 * currentBufferedSourceException == null) return null; // Throw
667:                 * combination of the error types return new CompositeErrorMessage( new
668:                 * ErrorMessage[] { superError, validationError,
669:                 * currentBufferedSourceException });
670:                 */
671:
672:            }
673:
674:            /* Value change events ****************************************** */
675:
676:            private static final Method VALUE_CHANGE_METHOD;
677:
678:            static {
679:                try {
680:                    VALUE_CHANGE_METHOD = Property.ValueChangeListener.class
681:                            .getDeclaredMethod(
682:                                    "valueChange",
683:                                    new Class[] { Property.ValueChangeEvent.class });
684:                } catch (java.lang.NoSuchMethodException e) {
685:                    // This should never happen
686:                    throw new java.lang.RuntimeException();
687:                }
688:            }
689:
690:            /*
691:             * Add a value change listener for the field. Don't add a JavaDoc comment
692:             * here, we use the default documentation from the implemented interface.
693:             */
694:            public void addListener(Property.ValueChangeListener listener) {
695:                addListener(AbstractField.ValueChangeEvent.class, listener,
696:                        VALUE_CHANGE_METHOD);
697:            }
698:
699:            /*
700:             * Remove a value change listener from the field. Don't add a JavaDoc
701:             * comment here, we use the default documentation from the implemented
702:             * interface.
703:             */
704:            public void removeListener(Property.ValueChangeListener listener) {
705:                removeListener(AbstractField.ValueChangeEvent.class, listener,
706:                        VALUE_CHANGE_METHOD);
707:            }
708:
709:            /**
710:             * Emit a value change event. The value contained in the field is validated
711:             * before the event is created.
712:             */
713:            protected void fireValueChange() {
714:                fireEvent(new AbstractField.ValueChangeEvent(this ));
715:                requestRepaint();
716:            }
717:
718:            /* Read-only status change events *************************************** */
719:
720:            private static final Method READ_ONLY_STATUS_CHANGE_METHOD;
721:
722:            static {
723:                try {
724:                    READ_ONLY_STATUS_CHANGE_METHOD = Property.ReadOnlyStatusChangeListener.class
725:                            .getDeclaredMethod(
726:                                    "readOnlyStatusChange",
727:                                    new Class[] { Property.ReadOnlyStatusChangeEvent.class });
728:                } catch (java.lang.NoSuchMethodException e) {
729:                    // This should never happen
730:                    throw new java.lang.RuntimeException();
731:                }
732:            }
733:
734:            /**
735:             * An <code>Event</code> object specifying the Property whose read-only
736:             * status has changed.
737:             * 
738:             * @author IT Mill Ltd.
739:             * @version
740:             * 3.1.1
741:             * @since 3.0
742:             */
743:            public class ReadOnlyStatusChangeEvent extends Component.Event
744:                    implements  Property.ReadOnlyStatusChangeEvent {
745:
746:                /**
747:                 * Serial generated by eclipse.
748:                 */
749:                private static final long serialVersionUID = 3258688823264161846L;
750:
751:                /**
752:                 * New instance of text change event
753:                 * 
754:                 * @param source
755:                 *            Source of the event.
756:                 */
757:                public ReadOnlyStatusChangeEvent(AbstractField source) {
758:                    super (source);
759:                }
760:
761:                /**
762:                 * Property where the event occurred
763:                 * 
764:                 * @return Source of the event.
765:                 */
766:                public Property getProperty() {
767:                    return (Property) getSource();
768:                }
769:            }
770:
771:            /*
772:             * Add a read-only status change listener for the field. Don't add a JavaDoc
773:             * comment here, we use the default documentation from the implemented
774:             * interface.
775:             */
776:            public void addListener(
777:                    Property.ReadOnlyStatusChangeListener listener) {
778:                addListener(Property.ReadOnlyStatusChangeEvent.class, listener,
779:                        READ_ONLY_STATUS_CHANGE_METHOD);
780:            }
781:
782:            /*
783:             * Removes a read-only status change listener from the field. Don't add a
784:             * JavaDoc comment here, we use the default documentation from the
785:             * implemented interface.
786:             */
787:            public void removeListener(
788:                    Property.ReadOnlyStatusChangeListener listener) {
789:                removeListener(Property.ReadOnlyStatusChangeEvent.class,
790:                        listener, READ_ONLY_STATUS_CHANGE_METHOD);
791:            }
792:
793:            /**
794:             * Emit a read-only status change event. The value contained in the field is
795:             * validated before the event is created.
796:             */
797:            protected void fireReadOnlyStatusChange() {
798:                fireEvent(new AbstractField.ReadOnlyStatusChangeEvent(this ));
799:            }
800:
801:            /**
802:             * This method listens to data source value changes and passes the changes
803:             * forwards.
804:             * 
805:             * @param event
806:             *            the value change event telling the data source contents have
807:             *            changed
808:             */
809:            public void valueChange(Property.ValueChangeEvent event) {
810:                if (isReadThrough() || !isModified())
811:                    fireValueChange();
812:            }
813:
814:            /** Ask the terminal to place the cursor to this field. */
815:            public void focus() {
816:                Window w = getWindow();
817:                if (w != null) {
818:                    w.setFocusedComponent(this );
819:                } else {
820:                    this .delayedFocus = true;
821:                }
822:            }
823:
824:            /**
825:             * Create abstract field by the type of the property.
826:             * 
827:             * <p>
828:             * This returns most suitable field type for editing property of given type
829:             * </p>
830:             * 
831:             * @param propertyType
832:             *            Type of the property, that needs to be edited.
833:             */
834:            public static AbstractField constructField(Class propertyType) {
835:
836:                // Null typed properties can not be edited
837:                if (propertyType == null)
838:                    return null;
839:
840:                // Date field
841:                if (Date.class.isAssignableFrom(propertyType)) {
842:                    return new DateField();
843:                }
844:
845:                // Boolean field
846:                if (Boolean.class.isAssignableFrom(propertyType)) {
847:                    Button button = new Button("");
848:                    button.setSwitchMode(true);
849:                    button.setImmediate(false);
850:                    return button;
851:                }
852:
853:                // Text field is used by default
854:                return new TextField();
855:            }
856:
857:            /**
858:             * Get the tab index of this field. The tab index property is used to
859:             * specify the natural tab ordering of fields.
860:             * 
861:             * @return Tab index of this field. Negative value means unspecified.
862:             */
863:            public int getTabIndex() {
864:                return tabIndex;
865:            }
866:
867:            /**
868:             * Get the tab index of this field. The tab index property is used to
869:             * specify the natural tab ordering of fields.
870:             * 
871:             * @param tabIndex
872:             *            The tab order of this component. Negative value means
873:             *            unspecified.
874:             */
875:            public void setTabIndex(int tabIndex) {
876:                this .tabIndex = tabIndex;
877:            }
878:
879:            /**
880:             * Set the internal field value. This is purely used by AbstractField to
881:             * change the internal Field value. It does not trigger any events. It can
882:             * be overriden by the inheriting classes to update all dependent variables.
883:             * 
884:             * @param newValue
885:             *            The new value to be set.
886:             */
887:            protected void setInternalValue(Object newValue) {
888:                this .value = newValue;
889:            }
890:
891:            /**
892:             * @see org.millstone.base.ui.Component.Focusable#getFocusableId()
893:             */
894:            public long getFocusableId() {
895:                return this .focusableId;
896:            }
897:
898:            /**
899:             * @see org.millstone.base.ui.Component#attach()
900:             */
901:            public void attach() {
902:                super .attach();
903:                if (this .delayedFocus) {
904:                    this .delayedFocus = false;
905:                    this .focus();
906:                }
907:            }
908:
909:            /**
910:             * Is this field required.
911:             * 
912:             * Required fields must filled by the user.
913:             * 
914:             * @return true if the
915:             */
916:            public boolean isRequired() {
917:                return required;
918:            }
919:
920:            /**
921:             * Set the field required. Required fields must filled by the user.
922:             * 
923:             * @param required
924:             *            Is the field required
925:             */
926:            public void setRequired(boolean required) {
927:                this .required = required;
928:            }
929:
930:            /**
931:             * Free used resources.
932:             */
933:            public void finalize() throws Throwable {
934:                if (focusableId > -1) {
935:                    Window.removeFocusableId(focusableId);
936:                }
937:                super.finalize();
938:            }
939:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.