KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openharmonise > swing > datefield > JDateField


1 /*
2  * The contents of this file are subject to the
3  * Mozilla Public License Version 1.1 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at http://www.mozilla.org/MPL/
6  *
7  * Software distributed under the License is distributed on an "AS IS"
8  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
9  * See the License for the specific language governing rights and
10  * limitations under the License.
11  *
12  * The Initial Developer of the Original Code is Simulacra Media Ltd.
13  * Portions created by Simulacra Media Ltd are Copyright (C) Simulacra Media Ltd, 2004.
14  *
15  * All Rights Reserved.
16  *
17  * Contributor(s):
18  */

19 package org.openharmonise.swing.datefield;
20
21 import java.awt.*;
22 import java.awt.event.*;
23 import java.util.*;
24 import java.util.List JavaDoc;
25
26 import javax.swing.*;
27 import javax.swing.text.*;
28
29 /**
30  * <p>JDateField is a lightweight component that allows constrained free text date
31  * entry. The format string is based on the {@link java.text.SimpleDateFormat} one with some
32  * caveats:</p>
33  * <ol>
34  * <li> Only numerical representations of dates are allowed, except for the Era
35  * field with can only be represented as "AD" or "BC".</li>
36  *
37  * <li>The format length for each field needs to be the same length as the expected
38  * input. So for a 4 digit year you must use "yyyy", where as the {@link java.text.SimpleDateFormat}
39  * class will accept "yyy" and "yyyyy". The only excpetion to this rule is the Era field
40  * which must be represented as "G".</li>
41  * </ol>
42  *
43  * @author Matthew Large
44  * @version $Revision: 1.1 $
45  *
46  */

47 public class JDateField extends JTextField implements KeyListener, FocusListener, MouseWheelListener, MouseListener {
48
49     /**
50      * Date format string.
51      */

52     private String JavaDoc m_sFormat = null;
53     
54     /**
55      * Date format parser.
56      */

57     private DateFormatParser m_dateFormatParser = null;
58     
59     /**
60      * List of {@link DateBlock} objects.
61      */

62     private List JavaDoc m_aDateBlocks = new ArrayList();
63     
64     /**
65      * Index of the currently active date block.
66      */

67     private int m_nActiveBlockIndex = -1;
68     
69     /**
70      * List of allowed characters.
71      */

72     private static final ArrayList m_aAllowedChars = new ArrayList();
73     
74     /**
75      * List of allowed numbers.
76      */

77     private static final ArrayList m_aAllowedNums = new ArrayList();
78     
79     /**
80      * Calendar adaptor containing the current date value.
81      */

82     private CalendarAdaptor m_calendar = new CalendarAdaptor();
83     
84     /**
85      * Reusable temporary calendar adaptor, used for testing values against constraints before allowing them to be set.
86      */

87     private CalendarAdaptor m_tempCalendar = new CalendarAdaptor();
88     
89     /**
90      * Calendar adaptor representing the minimum allowed date, or null if one isn't set.
91      */

92     private CalendarAdaptor m_minCalendar = null;
93     
94     /**
95      * Calendar adaptor representing the maximum allowed date, or null if one isn't set.
96      */

97     private CalendarAdaptor m_maxCalendar = null;
98     
99     /**
100      * List of {@link DateFieldListener} objects.
101      */

102     private ArrayList m_dateFieldListeners = new ArrayList();
103     
104     static {
105         m_aAllowedNums.add("0");
106         m_aAllowedNums.add("1");
107         m_aAllowedNums.add("2");
108         m_aAllowedNums.add("3");
109         m_aAllowedNums.add("4");
110         m_aAllowedNums.add("5");
111         m_aAllowedNums.add("6");
112         m_aAllowedNums.add("7");
113         m_aAllowedNums.add("8");
114         m_aAllowedNums.add("9");
115         
116         m_aAllowedChars.add("a");
117         m_aAllowedChars.add("b");
118         m_aAllowedChars.add("c");
119         m_aAllowedChars.add("d");
120         m_aAllowedChars.add("A");
121         m_aAllowedChars.add("B");
122         m_aAllowedChars.add("C");
123         m_aAllowedChars.add("D");
124     }
125
126     /**
127      * Constructs a new date field.
128      *
129      * @param sFormat Format string
130      */

131     public JDateField(String JavaDoc sFormat) {
132         super();
133         this.m_sFormat = sFormat;
134         this.setup();
135     }
136     
137     /**
138      * Configures this date field.
139      *
140      */

141     private void setup() {
142         this.setFocusTraversalKeysEnabled(false);
143         this.addKeyListener(this);
144         this.addFocusListener(this);
145         this.addMouseListener(this);
146         this.addMouseWheelListener(this);
147         
148         this.m_dateFormatParser = new DateFormatParser(this.m_sFormat);
149         
150         int nPos = 0;
151         this.m_aDateBlocks.clear();
152
153         Iterator itor = this.m_dateFormatParser.getFormatBlocks().iterator();
154         while (itor.hasNext()) {
155             DateFormatBlock formatBlock = (DateFormatBlock) itor.next();
156     
157             DateBlock dateBlock = new DateBlock(formatBlock, nPos, "");
158             this.m_aDateBlocks.add(dateBlock);
159     
160             nPos = nPos + formatBlock.getInputLength();
161         }
162         
163         this.clear();
164         
165         this.highlightNextActiveBlock(-1);
166     }
167     
168     /**
169      * Clears the date field, resetting the display to the input
170      * format string.
171      *
172      */

173     public void clear() {
174         Iterator itor = this.m_aDateBlocks.iterator();
175         while (itor.hasNext()) {
176             DateBlock dateBlock = (DateBlock) itor.next();
177             dateBlock.clear();
178             if(dateBlock.getFormatBlock().isActiveBlock() && !dateBlock.getValue().equalsIgnoreCase(dateBlock.getFormatBlock().getEntryFormat())) {
179                 this.m_calendar.setStringValue(dateBlock.getFormatBlock().getCalendarField(), dateBlock.getValue());
180             }
181         }
182         this.redisplayDate(0);
183     }
184     
185     /**
186      * Returns the active date block.
187      *
188      * @return Active date block
189      */

190     private DateBlock getActiveBlock() {
191         DateBlock activeBlock = null;
192         
193         if(this.m_nActiveBlockIndex>-1) {
194             activeBlock = (DateBlock) this.m_aDateBlocks.get(m_nActiveBlockIndex);
195         }
196         
197         return activeBlock;
198     }
199     
200     /**
201      * Returns the date format string used when constructing this date
202      * field.
203      *
204      * @return Format string
205      */

206     public String JavaDoc getDateFormat() {
207         return this.m_sFormat;
208     }
209     
210     /**
211      * Handles all key events for this component.
212      *
213      * @param ke Key event
214      * @param nType Type of event 0=pressed, 1=released and 2=typed
215      */

216     private void keyEventHandler(KeyEvent ke, int nType) {
217         
218         if(nType==0 && ke.getKeyCode()==KeyEvent.VK_TAB && ((ke.getModifiersEx() & KeyEvent.SHIFT_DOWN_MASK) == KeyEvent.SHIFT_DOWN_MASK)) {
219             DateBlock dateBlock = this.getActiveBlock();
220             this.handleFieldExit(dateBlock);
221             boolean bBlockFound = this.highlightPreviousActiveBlock(this.m_nActiveBlockIndex);
222             if(!bBlockFound) {
223                 this.transferFocusBackward();
224             }
225
226             ke.consume();
227             
228         } else if(nType==0 && ke.getKeyCode()==KeyEvent.VK_ESCAPE) {
229             this.replaceWithPreviousValues(1);
230             this.highlightActiveBlock();
231     
232             ke.consume();
233         } else if(nType==0 && (ke.getKeyCode()==KeyEvent.VK_ENTER)) {
234             DateBlock dateBlock = this.getActiveBlock();
235             this.handleFieldExit(dateBlock);
236             this.transferFocus();
237             ke.consume();
238         } else if(nType==0 && ke.getKeyCode()==KeyEvent.VK_TAB) {
239             
240             DateBlock dateBlock = this.getActiveBlock();
241             this.handleFieldExit(dateBlock);
242             
243             boolean bBlockFound = this.highlightNextActiveBlock(this.m_nActiveBlockIndex);
244             if(!bBlockFound) {
245                 this.transferFocus();
246             }
247
248             ke.consume();
249         } else if(nType==0 && ke.getKeyCode()==KeyEvent.VK_RIGHT) {
250             
251             DateBlock dateBlock = this.getActiveBlock();
252             this.handleFieldExit(dateBlock);
253             
254             boolean bBlockFound = this.highlightNextActiveBlock(this.m_nActiveBlockIndex);
255             if(!bBlockFound) {
256                 this.highlightActiveBlock();
257             }
258             ke.consume();
259         } else if(nType==0 && ke.getKeyCode()==KeyEvent.VK_LEFT) {
260             
261             DateBlock dateBlock = this.getActiveBlock();
262             this.handleFieldExit(dateBlock);
263             boolean bBlockFound = this.highlightPreviousActiveBlock(this.m_nActiveBlockIndex);
264             if(!bBlockFound) {
265                 this.highlightActiveBlock();
266             }
267             ke.consume();
268         } else if(nType==0 && ke.getKeyCode()==KeyEvent.VK_UP) {
269             this.handleUpEvent();
270             ke.consume();
271         } else if(nType==0 && ke.getKeyCode()==KeyEvent.VK_DOWN) {
272             this.handleDownEvent();
273             ke.consume();
274         } else if(nType==2 && ke.getKeyCode()==KeyEvent.VK_DELETE || ke.getKeyCode()==KeyEvent.VK_BACK_SPACE) {
275             ke.consume();
276             if(this.getSelectedText()!=null && this.getSelectedText().length()==this.getText().length()) {
277                 this.setText("");
278                 this.clear();
279                 this.fireValueChanged();
280             }
281         } else {
282             DateBlock dateBlock = this.getActiveBlock();
283
284             String JavaDoc sKeyText = KeyEvent.getKeyText(ke.getKeyCode());
285             sKeyText = sKeyText.replaceAll("NumPad-", "");
286         
287             if(nType==1 &&
288                 ( (dateBlock.getFormatBlock().getCalendarField()==Calendar.ERA && JDateField.m_aAllowedChars.contains(sKeyText) )
289                     || (dateBlock.getFormatBlock().getCalendarField()!=Calendar.ERA && JDateField.m_aAllowedNums.contains(sKeyText)) )
290                 ) {
291             
292                 if(dateBlock!=null) {
293                     String JavaDoc sValue = null;
294
295                     DateFormatBlock formatBlock = dateBlock.getFormatBlock();
296                 
297                     String JavaDoc sCurrentValue = dateBlock.getValue();
298                     StringBuffer JavaDoc sBuff = new StringBuffer JavaDoc();
299
300                     sCurrentValue = this.rTrim(sCurrentValue);
301                     
302                     if(sCurrentValue.equalsIgnoreCase(formatBlock.getFormat())
303                             || sCurrentValue.trim().startsWith("cc")
304                             || sCurrentValue.length()>=formatBlock.getInputLength() ) {
305                                 sCurrentValue = "";
306                             }
307                         
308                     sBuff = new StringBuffer JavaDoc(sCurrentValue);
309                     
310                     
311                     sBuff.append(sKeyText);
312                     if(sBuff.length()<formatBlock.getInputLength()) {
313                         for(int i=sBuff.length(); i<formatBlock.getInputLength(); i++) {
314                             sBuff.append(" ");
315                         }
316                     }
317                     sValue = sBuff.toString();
318                     
319                     dateBlock.setValue(sValue);
320                     this.redisplayDate(dateBlock.getStartPos() + sCurrentValue.length()+1);
321                     if(sCurrentValue.length()+1>=formatBlock.getInputLength()) {
322                         
323                         if(dateBlock.getFormatBlock().getCalendarField()==Calendar.ERA
324                             && !sValue.equalsIgnoreCase("ad")
325                             && !sValue.equalsIgnoreCase("bc")) {
326                                 dateBlock.setValue( this.m_calendar.getStringValue(Calendar.ERA) );
327                         }
328
329                         this.m_calendar.setStringValue(dateBlock.getFormatBlock().getCalendarField(), dateBlock.getValue());
330                         
331                         if(!this.m_calendar.getStringValue(dateBlock.getFormatBlock().getCalendarField()).equalsIgnoreCase(dateBlock.getValue())) {
332                             dateBlock.setValue(this.m_calendar.getStringValue(dateBlock.getFormatBlock().getCalendarField()));
333                         }
334                         this.updateValuesFromCalendar(dateBlock.getStartPos() + sCurrentValue.length()+1);
335                         this.highlightNextActiveBlock(this.m_nActiveBlockIndex);
336                         
337                         if(!this.isAboveMin(dateBlock) || !this.isUnderMax(dateBlock)) {
338                             if(this.isAboveMin(dateBlock)) {
339                                 this.fireValidationMessage(DateFieldListener.VALIDATION_FAIL_BELOW_MIN);
340                             }
341                             if(this.isUnderMax(dateBlock)) {
342                                 this.fireValidationMessage(DateFieldListener.VALIDATION_FAIL_ABOVE_MAX);
343                             }
344                         } else {
345                             this.fireValueChanged();
346                         }
347                     }
348                 
349                 }
350             }
351             
352             ke.consume();
353         }
354         
355     }
356     
357     public String JavaDoc rTrim(String JavaDoc sValue) {
358         StringBuffer JavaDoc sBuff = new StringBuffer JavaDoc();
359         boolean bFoundRight = false;
360         
361         for (int i = sValue.length()-1; i > -1 ; i--) {
362             if(sValue.charAt(i)!=' ') {
363                 bFoundRight=true;
364             }
365             if(bFoundRight) {
366                 sBuff.append(sValue.charAt(i));
367             }
368         }
369         
370         StringBuffer JavaDoc sNewBuff = new StringBuffer JavaDoc();
371         for (int i = sBuff.length()-1; i > -1; i--) {
372             sNewBuff.append(sBuff.charAt(i));
373         }
374         return sNewBuff.toString();
375     }
376     
377     /**
378      * Fires a validation failed message to all the {@link DateFieldListener}
379      * objects.
380      *
381      * @param nReason Reason for failure
382      */

383     private void fireValidationMessage(int nReason) {
384         Iterator itor = this.m_dateFieldListeners.iterator();
385         while (itor.hasNext()) {
386             DateFieldListener listener = (DateFieldListener) itor.next();
387             listener.validationFailed(this, nReason);
388         }
389     }
390     
391     /**
392      * Checks if the current date is above the minimum allowed.
393      *
394      * @param dateBlock Changed date block
395      * @return true if the current date is above the minimum
396      */

397     private boolean isAboveMin(DateBlock dateBlock) {
398         boolean bReturn = true;
399         
400         if(this.m_minCalendar!=null) {
401             try {
402                 this.m_tempCalendar.setStringValue(dateBlock.getFormatBlock().getCalendarField(), dateBlock.getValue());
403                 bReturn = (this.m_tempCalendar.getTime().getTime()>=this.m_minCalendar.getTime().getTime());
404             } catch(NumberFormatException JavaDoc nfe) {
405                 //NO-OP
406
}
407         }
408         
409         return bReturn;
410     }
411
412     /**
413      * Checks if the current date is below the maximum allowed.
414      *
415      * @param dateBlock Changed date block
416      * @return true if the current date is below the maximum
417      */

418     private boolean isUnderMax(DateBlock dateBlock) {
419         boolean bReturn = true;
420         
421         if(this.m_maxCalendar!=null) {
422             try {
423                 this.m_tempCalendar.setStringValue(dateBlock.getFormatBlock().getCalendarField(), dateBlock.getValue());
424                 bReturn = (this.m_tempCalendar.getTime().getTime()<=this.m_maxCalendar.getTime().getTime());
425             } catch(NumberFormatException JavaDoc nfe) {
426                 //NO-OP
427
}
428         }
429         
430         return bReturn;
431     }
432     
433     /**
434      * Handles the situation where a date field is exited early by the user
435      * by using the tab or arrow keys.
436      *
437      * @param dateBlock Date block exited
438      */

439     private void handleFieldExit(DateBlock dateBlock) {
440         String JavaDoc sDatePreviousValue = dateBlock.getPreviousValue();
441         
442         if(this.rTrim(dateBlock.getValue()).length()<dateBlock.getFormatBlock().getInputLength()) {
443             if(dateBlock.getFormatBlock().getCalendarField()==Calendar.YEAR) {
444                 StringBuffer JavaDoc sBuff = new StringBuffer JavaDoc();
445                 if(dateBlock.getValue().trim().length()<8) {
446                     sBuff.append(" ");
447                 }
448                 if(dateBlock.getValue().trim().length()<7) {
449                     sBuff.append(" ");
450                 }
451                 if(dateBlock.getValue().trim().length()<6) {
452                     sBuff.append(" ");
453                 }
454                 if(dateBlock.getValue().trim().length()<5) {
455                     sBuff.append(" ");
456                 }
457                 if(dateBlock.getValue().trim().length()<4) {
458                     sBuff.append("0");
459                 }
460                 if(dateBlock.getValue().trim().length()<3) {
461                     sBuff.append("0");
462                 }
463                 if(dateBlock.getValue().trim().length()<2) {
464                     sBuff.append("0");
465                 }
466                 sBuff.append(dateBlock.getValue().trim());
467                 dateBlock.setPreviousValue(sBuff.toString());
468                 dateBlock.setValue(sBuff.toString());
469                 this.m_calendar.setStringValue(dateBlock.getFormatBlock().getCalendarField(), dateBlock.getValue());
470                 System.out.println("Comparing cal=" + this.m_calendar.getStringValue(dateBlock.getFormatBlock().getCalendarField()).replaceAll("0", "") + " with val=" + dateBlock.getValue().replaceAll("0", ""));
471                 if(!this.m_calendar.getStringValue(dateBlock.getFormatBlock().getCalendarField()).replaceAll("0", "").equalsIgnoreCase(dateBlock.getValue().replaceAll("0", ""))) {
472                     dateBlock.setValue(this.m_calendar.getStringValue(dateBlock.getFormatBlock().getCalendarField()));
473                     dateBlock.setPreviousValue(dateBlock.getValue());
474                 }
475             } else if(dateBlock.getFormatBlock().getCalendarField()==Calendar.ERA) {
476                 dateBlock.setValue(dateBlock.getPreviousValue());
477                 this.m_calendar.setStringValue(dateBlock.getFormatBlock().getCalendarField(), dateBlock.getValue());
478             } else {
479                 StringBuffer JavaDoc sBuff = new StringBuffer JavaDoc();
480                 for(int i=0; i<dateBlock.getFormatBlock().getInputLength()-dateBlock.getValue().trim().length(); i++) {
481                     sBuff.append("0");
482                 }
483                 sBuff.append(dateBlock.getValue().trim());
484                 dateBlock.setPreviousValue(sBuff.toString());
485                 dateBlock.setValue(sBuff.toString());
486                 this.m_calendar.setStringValue(dateBlock.getFormatBlock().getCalendarField(), dateBlock.getValue());
487                 
488                 if(!this.m_calendar.getStringValue(dateBlock.getFormatBlock().getCalendarField()).equalsIgnoreCase(dateBlock.getValue())) {
489                     dateBlock.setValue(this.m_calendar.getStringValue(dateBlock.getFormatBlock().getCalendarField()));
490                     dateBlock.setPreviousValue(dateBlock.getValue());
491                 }
492             }
493         }
494         
495         
496         if(!this.isAboveMin(dateBlock) || !this.isUnderMax(dateBlock)) {
497             if(this.isAboveMin(dateBlock)) {
498                 this.fireValidationMessage(DateFieldListener.VALIDATION_FAIL_BELOW_MIN);
499             }
500             if(this.isUnderMax(dateBlock)) {
501                 this.fireValidationMessage(DateFieldListener.VALIDATION_FAIL_ABOVE_MAX);
502             }
503         } else if(!dateBlock.getValue().equalsIgnoreCase(sDatePreviousValue)) {
504             this.fireValueChanged();
505         }
506         this.redisplayDate(1);
507     }
508     
509     /**
510      * Fires a value changed event to all the {@link DateFieldListener} objects.
511      *
512      */

513     private void fireValueChanged() {
514         
515         if(this.hasValue()) {
516             Iterator itor = this.m_dateFieldListeners.iterator();
517             while (itor.hasNext()) {
518                 DateFieldListener listener = (DateFieldListener) itor.next();
519                 listener.valueChanged(this);
520             }
521         }
522     }
523     
524     /**
525      * Checks if the date field as a complete value.
526      *
527      * @return true if the date field has a complete value
528      */

529     public boolean hasValue() {
530         boolean bHasValue = true;
531         Iterator itor = this.m_aDateBlocks.iterator();
532         while (itor.hasNext()) {
533             DateBlock dateBlock = (DateBlock) itor.next();
534             if(!dateBlock.hasValue()) {
535                 bHasValue=false;
536                 break;
537             }
538         }
539         return bHasValue;
540     }
541     
542     /**
543      * Highlights the currently active block.
544      *
545      */

546     private void highlightActiveBlock() {
547         int nIndex = 0;
548         
549         if(this.m_nActiveBlockIndex>-1 && this.m_nActiveBlockIndex<this.m_aDateBlocks.size()) {
550             nIndex = this.m_nActiveBlockIndex;
551         }
552         DateFormatBlock block = ((DateBlock)this.m_aDateBlocks.get(nIndex)).getFormatBlock();
553         this.setCaretPosition(block.getStartPosition());
554         this.moveCaretPosition(block.getStartPosition() + block.getInputLength());
555     }
556     
557     /**
558      * Replaces the date blocks with their
559      * previous value. Used when a user is part way through entering a value
560      * and then presses the escape key.
561      *
562      * @param nCarretPosition Current carret position
563      */

564     private void replaceWithPreviousValues(int nCarretPosition) {
565         Iterator itor = this.m_aDateBlocks.iterator();
566         while (itor.hasNext()) {
567             DateBlock dateBlock = (DateBlock) itor.next();
568             dateBlock.setValue(dateBlock.getPreviousValue());
569         }
570         this.redisplayDate(nCarretPosition);
571     }
572     
573     /**
574      * Updates date blocks with values from the current date value. Used
575      * to make sure other fields roll over correctly with the current field,
576      * e.g. the year rolls over then the month goes up from 12 to 1.
577      *
578      * @param nCarretPosition
579      */

580     private void updateValuesFromCalendar(int nCarretPosition) {
581         Iterator itor = this.m_aDateBlocks.iterator();
582         while (itor.hasNext()) {
583             DateBlock dateBlock = (DateBlock) itor.next();
584             if(dateBlock.getFormatBlock().isActiveBlock() && !dateBlock.getValue().equalsIgnoreCase(dateBlock.getFormatBlock().getEntryFormat())) {
585                 String JavaDoc sCalValue = this.m_calendar.getStringValue(dateBlock.getFormatBlock().getCalendarField());
586                 dateBlock.setPreviousValue(dateBlock.getValue());
587                 dateBlock.setValue(sCalValue);
588             }
589         }
590         this.m_tempCalendar.setTime(this.m_calendar.getTime());
591         this.redisplayDate(nCarretPosition);
592     }
593     
594     /**
595      * Sets the date value.
596      *
597      * @param dt Date value
598      */

599     public void setDate(Date dt) {
600         if(dt!=null) {
601             this.m_calendar.setTime(dt);
602             Iterator itor = this.m_aDateBlocks.iterator();
603             while (itor.hasNext()) {
604                 DateBlock dateBlock = (DateBlock) itor.next();
605                 if(dateBlock.getFormatBlock().isActiveBlock()) {
606                     dateBlock.setValue( this.m_calendar.getStringValue(dateBlock.getFormatBlock().getCalendarField()) );
607                     dateBlock.setPreviousValue( this.m_calendar.getStringValue(dateBlock.getFormatBlock().getCalendarField()) );
608                 }
609             }
610             this.redisplayDate(1);
611         }
612     }
613     
614     /**
615      * Returns the date value.
616      *
617      * @return Date value or null if there isn'n one
618      */

619     public Date getDate() {
620         if(this.hasValue()) {
621             return this.m_calendar.getTime();
622         } else {
623             return null;
624         }
625     }
626     
627     /**
628      * Sets the maximum allowed date.
629      *
630      * @param dtMax Maximum date
631      */

632     public void setMaximumDate(Date dtMax) {
633         if(dtMax!=null) {
634             this.m_maxCalendar = new CalendarAdaptor();
635             this.m_maxCalendar.setTime(dtMax);
636         }
637     }
638     
639     /**
640      * Sets the minium allowed date.
641      *
642      * @param dtMin Minimum date
643      */

644     public void setMinimumDate(Date dtMin) {
645         if(dtMin!=null) {
646             this.m_minCalendar = new CalendarAdaptor();
647             this.m_minCalendar.setTime(dtMin);
648         }
649     }
650     
651     /**
652      * Redisplays the values from all the date blocks.
653      *
654      * @param nCarretPosition Current carret position
655      */

656     private void redisplayDate(int nCarretPosition) {
657
658         StringBuffer JavaDoc sBuff = new StringBuffer JavaDoc();
659         
660         Iterator itor = this.m_aDateBlocks.iterator();
661         while (itor.hasNext()) {
662             DateBlock dateBlock = (DateBlock) itor.next();
663             sBuff.append(dateBlock.getValue());
664         }
665         
666         this.setText(sBuff.toString());
667         this.setCaretPosition(nCarretPosition);
668     }
669     
670     /**
671      * Highlights the next active block from the given index.
672      *
673      * @param nActiveBlock Index to start from
674      * @return true if a block was found
675      */

676     private boolean highlightNextActiveBlock(int nActiveBlock) {
677         boolean bBlockFound = false;
678         
679         Iterator itor = this.m_dateFormatParser.getFormatBlocks().iterator();
680
681         DateFormatBlock block =null;
682
683         while (itor.hasNext() && !bBlockFound) {
684             block = (DateFormatBlock) itor.next();
685             bBlockFound = (block.isActiveBlock() && this.m_dateFormatParser.getFormatBlocks().indexOf(block)>nActiveBlock);
686         }
687         
688         if(bBlockFound && block!=null) {
689             this.m_nActiveBlockIndex = this.m_dateFormatParser.getFormatBlocks().indexOf(block);
690             this.setCaretPosition(block.getStartPosition());
691             this.moveCaretPosition(block.getStartPosition() + block.getInputLength());
692         }
693         
694         return bBlockFound;
695     }
696     
697     /**
698      * Highlights the previous active block from the given index.
699      *
700      * @param nActiveBlock Index to start from
701      * @return true if a block was found
702      */

703     private boolean highlightPreviousActiveBlock(int nActiveBlock) {
704         boolean bBlockFound = false;
705         
706         Iterator itor = this.m_dateFormatParser.getFormatBlocks().iterator();
707
708         DateFormatBlock block =null;
709         DateFormatBlock previousBlock =null;
710
711         while (itor.hasNext() && !bBlockFound) {
712             block = (DateFormatBlock) itor.next();
713             bBlockFound = (block.isActiveBlock() && this.m_dateFormatParser.getFormatBlocks().indexOf(block)==nActiveBlock);
714             if(!bBlockFound && block.isActiveBlock()) {
715                 previousBlock = block;
716             }
717         }
718         
719         if(bBlockFound && previousBlock!=null) {
720             this.m_nActiveBlockIndex = this.m_dateFormatParser.getFormatBlocks().indexOf(previousBlock);
721             this.setCaretPosition(previousBlock.getStartPosition());
722             this.moveCaretPosition(previousBlock.getStartPosition() + previousBlock.getInputLength());
723         }
724         
725         return bBlockFound && previousBlock!=null;
726     }
727
728     /* (non-Javadoc)
729      * @see java.awt.event.KeyListener#keyPressed(java.awt.event.KeyEvent)
730      */

731     public void keyPressed(KeyEvent ke) {
732         this.keyEventHandler(ke, 0);
733     }
734
735     /* (non-Javadoc)
736      * @see java.awt.event.KeyListener#keyReleased(java.awt.event.KeyEvent)
737      */

738     public void keyReleased(KeyEvent ke) {
739         this.keyEventHandler(ke, 1);
740     }
741
742     /* (non-Javadoc)
743      * @see java.awt.event.KeyListener#keyTyped(java.awt.event.KeyEvent)
744      */

745     public void keyTyped(KeyEvent ke) {
746         this.keyEventHandler(ke, 2);
747     }
748
749     /**
750      *
751      */

752     private JDateField() {
753         super();
754         this.setup();
755     }
756
757     /**
758      * @param arg0
759      */

760     private JDateField(int arg0) {
761         super(arg0);
762         this.setup();
763     }
764
765     /**
766      * @param arg0
767      * @param arg1
768      */

769     private JDateField(String JavaDoc arg0, int arg1) {
770         super(arg0, arg1);
771         this.setup();
772     }
773
774     /**
775      * @param arg0
776      * @param arg1
777      * @param arg2
778      */

779     private JDateField(Document arg0, String JavaDoc arg1, int arg2) {
780         super(arg0, arg1, arg2);
781         this.setup();
782     }
783
784     /* (non-Javadoc)
785      * @see java.awt.event.FocusListener#focusGained(java.awt.event.FocusEvent)
786      */

787     public void focusGained(FocusEvent fe) {
788         this.highlightNextActiveBlock(-1);
789     }
790
791     /* (non-Javadoc)
792      * @see java.awt.event.FocusListener#focusLost(java.awt.event.FocusEvent)
793      */

794     public void focusLost(FocusEvent arg0) {
795
796     }
797
798     /* (non-Javadoc)
799      * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
800      */

801     public void mouseClicked(MouseEvent me) {
802         if(me.getClickCount()>1) {
803             this.setCaretPosition(0);
804             this.moveCaretPosition(this.getText().length());
805         } else {
806             int nCarretPos = this.getCaretPosition();
807         
808             Iterator itor = this.m_dateFormatParser.getFormatBlocks().iterator();
809             DateFormatBlock block = null;
810         
811             while (itor.hasNext()) {
812                 block = (DateFormatBlock) itor.next();
813             
814                 if(block.isActiveBlock() && block.getStartPosition()<=nCarretPos && (block.getStartPosition() + block.getInputLength()) >=nCarretPos) {
815                     break;
816                 }
817             }
818             this.highlightNextActiveBlock(this.m_dateFormatParser.getFormatBlocks().indexOf(block)-1);
819         }
820     }
821
822     /* (non-Javadoc)
823      * @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent)
824      */

825     public void mouseEntered(MouseEvent arg0) {
826
827     }
828
829     /* (non-Javadoc)
830      * @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent)
831      */

832     public void mouseExited(MouseEvent arg0) {
833
834     }
835
836     /* (non-Javadoc)
837      * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
838      */

839     public void mousePressed(MouseEvent arg0) {
840
841     }
842
843     /* (non-Javadoc)
844      * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
845      */

846     public void mouseReleased(MouseEvent arg0) {
847
848     }
849
850     /**
851      * Adds a date field listener.
852      *
853      * @param listener Listener to add
854      */

855     public void addDateFieldListener(DateFieldListener listener) {
856         this.m_dateFieldListeners.add(listener);
857     }
858
859     /**
860      * Removes a date field listener.
861      *
862      * @param listener Listener to remove
863      */

864     public void removeDateFieldListener(DateFieldListener listener) {
865         this.m_dateFieldListeners.remove(listener);
866     }
867     
868     /* (non-Javadoc)
869      * @see java.awt.Component#getPreferredSize()
870      */

871     public Dimension getPreferredSize() {
872         Dimension dim = super.getPreferredSize();
873         dim.height = dim.height + 5;
874         dim.width = dim.width + 20;
875         return dim;
876     }
877
878     /* (non-Javadoc)
879      * @see java.awt.event.MouseWheelListener#mouseWheelMoved(java.awt.event.MouseWheelEvent)
880      */

881     public void mouseWheelMoved(MouseWheelEvent mwe) {
882         if(mwe.getUnitsToScroll()<0) {
883             this.handleUpEvent();
884         } else {
885             this.handleDownEvent();
886         }
887     }
888     
889     /**
890      * Handles a down arrow key event.
891      *
892      */

893     private void handleDownEvent() {
894         DateBlock dateBlock = this.getActiveBlock();
895             
896         this.m_calendar.add(dateBlock.getFormatBlock().getCalendarField(), -1);
897         dateBlock.setValue(this.m_calendar.getStringValue(dateBlock.getFormatBlock().getCalendarField()));
898         this.updateValuesFromCalendar(0);
899         this.highlightActiveBlock();
900         if(!this.isAboveMin(dateBlock) || !this.isUnderMax(dateBlock)) {
901             if(this.isAboveMin(dateBlock)) {
902                 this.fireValidationMessage(DateFieldListener.VALIDATION_FAIL_BELOW_MIN);
903             }
904             if(this.isUnderMax(dateBlock)) {
905                 this.fireValidationMessage(DateFieldListener.VALIDATION_FAIL_ABOVE_MAX);
906             }
907         } else {
908             this.fireValueChanged();
909         }
910     }
911     
912     /**
913      * Handles an up arrow key event.
914      *
915      */

916     private void handleUpEvent() {
917         DateBlock dateBlock = this.getActiveBlock();
918             
919         this.m_calendar.add(dateBlock.getFormatBlock().getCalendarField(), 1);
920         dateBlock.setValue(this.m_calendar.getStringValue(dateBlock.getFormatBlock().getCalendarField()));
921             
922         this.updateValuesFromCalendar(0);
923         this.highlightActiveBlock();
924         if(!this.isAboveMin(dateBlock) || !this.isUnderMax(dateBlock)) {
925             if(this.isAboveMin(dateBlock)) {
926                 this.fireValidationMessage(DateFieldListener.VALIDATION_FAIL_BELOW_MIN);
927             }
928             if(this.isUnderMax(dateBlock)) {
929                 this.fireValidationMessage(DateFieldListener.VALIDATION_FAIL_ABOVE_MAX);
930             }
931         } else {
932             this.fireValueChanged();
933         }
934     }
935
936 }
937
Popular Tags