View Javadoc

1   /*
2    *  File: TimeChooser.java 
3    *  Copyright (c) 2004-2007  Peter Kliem (Peter.Kliem@jaret.de)
4    *  A commercial license is available, see http://www.jaret.de.
5    *
6    * All rights reserved. This program and the accompanying materials
7    * are made available under the terms of the Common Public License v1.0
8    * which accompanies this distribution, and is available at
9    * http://www.eclipse.org/legal/cpl-v10.html
10   */
11  package de.jaret.util.ui.datechooser;
12  
13  import java.text.NumberFormat;
14  import java.util.ArrayList;
15  import java.util.Calendar;
16  import java.util.Date;
17  import java.util.GregorianCalendar;
18  import java.util.List;
19  import java.util.Vector;
20  
21  import org.eclipse.swt.SWT;
22  import org.eclipse.swt.events.DisposeEvent;
23  import org.eclipse.swt.events.DisposeListener;
24  import org.eclipse.swt.events.FocusEvent;
25  import org.eclipse.swt.events.FocusListener;
26  import org.eclipse.swt.events.KeyEvent;
27  import org.eclipse.swt.events.KeyListener;
28  import org.eclipse.swt.events.SelectionAdapter;
29  import org.eclipse.swt.events.SelectionEvent;
30  import org.eclipse.swt.events.ShellAdapter;
31  import org.eclipse.swt.events.ShellEvent;
32  import org.eclipse.swt.events.VerifyEvent;
33  import org.eclipse.swt.events.VerifyListener;
34  import org.eclipse.swt.graphics.Color;
35  import org.eclipse.swt.graphics.Point;
36  import org.eclipse.swt.layout.FillLayout;
37  import org.eclipse.swt.layout.GridData;
38  import org.eclipse.swt.layout.GridLayout;
39  import org.eclipse.swt.widgets.Button;
40  import org.eclipse.swt.widgets.Composite;
41  import org.eclipse.swt.widgets.Display;
42  import org.eclipse.swt.widgets.Event;
43  import org.eclipse.swt.widgets.Listener;
44  import org.eclipse.swt.widgets.Shell;
45  import org.eclipse.swt.widgets.Text;
46  
47  import de.jaret.util.date.JaretDate;
48  
49  /***
50   * A time field with an attached timechooser in a combobox style.
51   * 
52   * @author Peter Kliem
53   * @version $Id: TimeChooser.java 587 2007-10-14 12:32:10Z olk $
54   */
55  public class TimeChooser extends Composite implements FocusListener, IDateChooserListener {
56      /*** Invalid input behaviour: keep the textual input and mark the field. */
57      public static final int KEEP_AND_MARK = 0;
58  
59      /*** Invalid input behaviour: reset the date to the last valid input. */
60      public static final int RESET_TO_LASTVALID = 1;
61  
62      /*** Color used to mark invalid input. */
63      public static final Color MARKER_COLOR = Display.getCurrent().getSystemColor(SWT.COLOR_RED);
64  
65      /*** behaviour on invalid input. */
66      protected int _invalidInputBehaviour = KEEP_AND_MARK;
67  
68      /*** if true: editable. */
69      protected boolean _editable = true;
70  
71      /*** if true: enabled. */
72      private boolean _enabled = true;
73  
74      /*** if true: select all in textfield on focus gain. */
75      private boolean _selectAllOnFocusGained = true;
76  
77      /***
78       * If true mousewheel will roll in the textfield.
79       */
80      private boolean _textfieldMouseWheelEnable = true;
81  
82      /*** listener list of interestedlisteners. */
83      protected List<IDateChooserListener> _listenerList = new Vector<IDateChooserListener>();
84  
85      /*** the date value manipulated by the control. */
86      protected Date _date = new Date();
87  
88      /*** text field widgets used. */
89      protected Text _textField;
90  
91      /*** dropdown button. */
92      protected Button _dropdownButton;
93  
94      /*** shell for the drop down. */
95      protected Shell _dropDownShell;
96  
97      /*** dropped state. */
98      protected boolean _dropped = false;
99  
100     /*** flag regeistering that drop down is about to happen. */
101     boolean _goingToDropDown = false;
102 
103     /*** TimeChooserPanel in the dropdown. */
104     protected TimeChooserPanel _chooserPanel;
105 
106     /*** FieldIdentifier used for field rolling. */
107     protected IFieldIdentifier _fieldIdentifier;
108 
109     /*** initial bg color of the textfield. */
110     private Color _textfieldBGColor;
111 
112     /*** flag to help keeping focus listeners happy. */
113     private boolean _hasFocus = false;
114 
115     /*** number format for time formating. */
116     protected NumberFormat _twoDigitNF;
117 
118     /*** date chooser to synchronize the date with. */
119     protected DateChooser _dateChooser;
120 
121     /*** true if the current niput is valid. */
122     protected boolean _hasValidInput = true;
123 
124     /***
125      * Constructor for the time chooser.
126      * 
127      * @param parent Composite parent
128      * @param style style
129      */
130     public TimeChooser(Composite parent, int style) {
131         super(parent, style);
132         createControls();
133 
134         _twoDigitNF = NumberFormat.getNumberInstance();
135         _twoDigitNF.setMinimumIntegerDigits(2);
136         _twoDigitNF.setMaximumIntegerDigits(2);
137 
138         updateTextField(_date);
139 
140         addDisposeListener(new DisposeListener() {
141             public void widgetDisposed(DisposeEvent e) {
142                 onDispose();
143             }
144         });
145     }
146 
147     /***
148      * create the controls (a text field and the drop down button).
149      */
150     private void createControls() {
151         GridLayout gridLayout = new GridLayout();
152         gridLayout.numColumns = 2;
153         gridLayout.horizontalSpacing = 0;
154         gridLayout.verticalSpacing = 0;
155         gridLayout.marginHeight = 0;
156         gridLayout.marginWidth = 0;
157         setLayout(gridLayout);
158 
159         _textField = new Text(this, SWT.BORDER | SWT.RIGHT);
160         GridData gd = new GridData(GridData.FILL_HORIZONTAL);
161         _textField.setLayoutData(gd);
162         // add this as Focuslistener to parse the date when loosing focus
163         _textField.addFocusListener(this);
164         // save the bg color for resetting mark
165         _textfieldBGColor = _textField.getBackground();
166 
167         _textField.addVerifyListener(new VerifyListener() {
168 
169             public void verifyText(VerifyEvent e) {
170                 if (Character.isDigit(e.character) || e.character < 32 || e.character == 127 || e.character == ':') {
171                     return;
172                 }
173                 e.doit = false;
174             }
175 
176         });
177 
178         // KeyListener to toggle drop down on ctrl-space
179         _textField.addKeyListener(new KeyListener() {
180 
181             public void keyPressed(KeyEvent keyEvent) {
182                 if ((keyEvent.stateMask & SWT.CTRL) != 0 && keyEvent.keyCode == 32) {
183                     setDropped(!isDropped());
184                     keyEvent.doit = false;
185                 } else if (keyEvent.keyCode == SWT.CR) {
186                     // cr to leave the field
187                     _textField.traverse(SWT.TRAVERSE_TAB_NEXT);
188                 } else if (keyEvent.keyCode == SWT.ARROW_UP) {
189                     rollField(1);
190                     keyEvent.doit = false;
191                 } else if (keyEvent.keyCode == SWT.ARROW_DOWN) {
192                     rollField(-1);
193                     keyEvent.doit = false;
194                 } else if (keyEvent.keyCode == ':') {
195                     System.out.println("::::");
196                 }
197             }
198 
199             public void keyReleased(KeyEvent arg0) {
200             }
201 
202         });
203 
204         // mousewheel rolling of fields
205         Listener listener = new Listener() {
206 
207             public void handleEvent(Event event) {
208                 switch (event.type) {
209                 case SWT.MouseWheel:
210                     int count = -event.count / 3;
211                     if (_textfieldMouseWheelEnable) {
212                         rollField(count);
213                     }
214                     break;
215                 default:
216                     throw new RuntimeException("unsupported event");
217 
218                 }
219             }
220         };
221 
222         addListener(SWT.MouseWheel, listener);
223 
224         _dropdownButton = new Button(this, SWT.ARROW | SWT.DOWN); // | (style & SWT.FLAT)
225         gd = new GridData();
226         _dropdownButton.setLayoutData(gd);
227         // SelectionListener for the dropdown button toggles dropdown state
228         _dropdownButton.addSelectionListener(new SelectionAdapter() {
229 
230             public void widgetSelected(SelectionEvent arg0) {
231                 setDropped(!isDropped());
232             }
233         });
234 
235     }
236 
237     /***
238      * dispose has to take care of some additional disposals.
239      */
240     public void onDispose() {
241         if (_dropDownShell != null) {
242             _dropDownShell.dispose();
243         }
244     }
245 
246     /***
247      * Roll the field (if identifiable) by the given delta.
248      * 
249      * @param delta delta to roll the field
250      */
251     private void rollField(int delta) {
252         if (validateInput()) {
253             // proceed only if the current input is valid
254             int caretpos = _textField.getCaretPosition();
255             if (caretpos < 3) {
256                 // roll hours
257                 Calendar cal = new GregorianCalendar();
258                 cal.setTime(_date);
259                 cal.roll(Calendar.HOUR_OF_DAY, delta);
260                 setDate(cal.getTime());
261             } else {
262                 // roll minues
263                 Calendar cal = new GregorianCalendar();
264                 cal.setTime(_date);
265                 cal.roll(Calendar.MINUTE, delta);
266                 setDate(cal.getTime());
267             }
268         }
269     }
270 
271     /***
272      * Check whether the drop down is dropped down.
273      * 
274      * @return true if the dropdow is dropped down
275      */
276     public boolean isDropped() {
277         return _dropped;
278     }
279 
280     /***
281      * Set the state of the dropdown.
282      * 
283      * @param dropped if true the dropdowbn will be displayed.
284      */
285     public void setDropped(boolean dropped) {
286         if (dropped != _dropped) {
287             _dropped = dropped;
288             if (_dropped && _editable && _enabled) {
289                 if (_dropDownShell == null) {
290                     _dropDownShell = createDropDown();
291                 }
292 
293                 _goingToDropDown = true;
294 
295                 _chooserPanel.setDate(getDate());
296                 Point size = _dropdownButton.getSize();
297                 Point dispLocation = toDisplay(_dropdownButton.getLocation());
298                 Point dropDownSize = _dropDownShell.computeSize(SWT.DEFAULT, SWT.DEFAULT);
299                 int dsWidth = dropDownSize.x;
300                 int dsHeight = dropDownSize.y;
301                 int locx = dispLocation.x + size.x - dsWidth;
302                 int locy = dispLocation.y + size.y + 3;
303                 // corrections if the display would not be complete
304                 // x
305                 if (locx < 0) {
306                     locx = 0;
307                 } else if (locx + dsWidth > Display.getCurrent().getBounds().width) {
308                     locx = Display.getCurrent().getBounds().width - dsWidth;
309                 }
310                 // y
311                 if (locy + dsHeight > Display.getCurrent().getBounds().height) {
312                     locy = dispLocation.y - dsHeight - 3;
313                 }
314 
315                 _dropDownShell.setLocation(locx, locy);
316                 _dropDownShell.setSize(dsWidth, dsHeight);
317                 _dropDownShell.pack();
318                 _dropDownShell.layout(true);
319 
320                 _dropDownShell.setVisible(true);
321                 _dropDownShell.setActive();
322                 _chooserPanel.forceFocus();
323                 resetMark(); // in case of an invalid input reset the amrk since the input continues
324             } else if (_dropDownShell != null) {
325                 _dropDownShell.setVisible(false);
326                 _goingToDropDown = false;
327                 _textField.setFocus();
328             }
329         }
330 
331     }
332 
333     /***
334      * Create the dropdown shell and the chooser panel.
335      * 
336      * @return the created Shell
337      */
338     private Shell createDropDown() {
339         Shell dropDown = new Shell(getShell(), SWT.NO_TRIM | SWT.BORDER);
340         dropDown.setLayout(new FillLayout());
341         _chooserPanel = new TimeChooserPanel(dropDown, SWT.NULL | SWT.BORDER);
342         _chooserPanel.setDate(getDate());
343         _chooserPanel.addDateChooserListener(this);
344         _chooserPanel.setBackground(getBackground());
345         _chooserPanel.addFocusListener(this);
346         /*
347          * The dropdown should be hidden if the focus gets assigned to any other component. This is accomplished by
348          * using a ShellListener and hide the dropdown on deactivation. The drawback of this mechanism is that the mouse
349          * event of the deactivation will get lost. This seems to be acceptable.
350          */
351         dropDown.addShellListener(new ShellAdapter() {
352             public void shellDeactivated(ShellEvent event) {
353                 setDropped(false);
354             }
355         });
356         return dropDown;
357     }
358 
359     /***
360      * Get the date portion of the selected date in an eventually wired DateChooser and set it on the date.
361      * 
362      * @param date date to correct
363      * @return corrected date
364      */
365     private Date correctDate(Date date) {
366         if (_dateChooser != null && _dateChooser.getDateInternal() != null) {
367             JaretDate d = new JaretDate(_dateChooser.getDateInternal());
368             JaretDate time = new JaretDate(date);
369             d.setHours(time.getHours());
370             d.setMinutes(time.getMinutes());
371             date = d.getDate();
372         }
373         return date;
374     }
375 
376     /***
377      * Retrieve the current selected time (as the time in the date). If a datechooser is set the date part will be taken
378      * from the date chooser.
379      * 
380      * @return Returns the time in a date.
381      */
382     public Date getDate() {
383         _date = correctDate(_date);
384         return _date;
385     }
386 
387     /***
388      * Retrieve internal date field without adaption by a possible set datechooser.
389      * 
390      * @return date
391      */
392     protected Date getDateInternal() {
393         return _date;
394     }
395 
396     /***
397      * Set the date.
398      * 
399      * @param date The date to set.
400      */
401     public void setDate(Date date) {
402         _date = date;
403         updateTextField(_date);
404     }
405 
406     /***
407      * Format the time in the date as a String.
408      * 
409      * @param date date containing the time
410      * @return String hh:mm
411      */
412     protected String formatTime(Date date) {
413         JaretDate d = new JaretDate(date);
414         return _twoDigitNF.format(d.getHours()) + ":" + _twoDigitNF.format(d.getMinutes());
415     }
416 
417     /***
418      * Update the text in the textfield.
419      * 
420      * @param date date to update the field with
421      */
422     private void updateTextField(Date date) {
423         if (date != null) {
424             int caretpos = _textField.getCaretPosition(); // save caretpos
425             _textField.setText(formatTime(date));
426             _textField.setSelection(caretpos, caretpos); // restore caretpos
427         } else {
428             _textField.setText("");
429         }
430     }
431 
432     /***
433      * Set the input in the textfield direct.
434      * 
435      * @param text new text of the textfield
436      */
437     public void setText(String text) {
438         _textField.setText(text);
439     }
440 
441     /***
442      * Select the text fields contents.
443      * 
444      */
445     public void selectAll() {
446         _textField.selectAll();
447     }
448 
449     /***
450      * Set the selection on the textfield.
451      * 
452      * @param pos position
453      */
454     public void setSelection(int pos) {
455         _textField.setSelection(pos);
456     }
457 
458     /***
459      * Clear selection on the textfield.
460      */
461     public void clearSelection() {
462         _textField.clearSelection();
463     }
464 
465     /***
466      * Cut operation of the textfield.
467      */
468     public void cut() {
469         _textField.cut();
470     }
471 
472     /***
473      * Copy operation of the textfield.
474      */
475     public void copy() {
476         _textField.copy();
477     }
478 
479     /***
480      * Paste operation of the textfield.
481      */
482     public void paste() {
483         _textField.paste();
484     }
485 
486     /***
487      * {@inheritDoc} The textfield will get the focus.
488      */
489     public boolean setFocus() {
490         super.setFocus();
491         return _textField.setFocus();
492     }
493 
494     /***
495      * {@inheritDoc} The textfield will get the focus.
496      */
497     public boolean forceFocus() {
498         return _textField.forceFocus();
499     }
500 
501     /***
502      * Access to the embedded textfield widget.
503      * 
504      * @return the textfield
505      */
506     public Text getTextField() {
507         return _textField;
508     }
509 
510     // DateChooserListener
511     /***
512      * {@inheritDoc} If a date has been chosen in the panel, close dropdaown, selection finished.
513      */
514     public void dateChosen(Date date) {
515         setDate(_chooserPanel.getDate());
516         setDropped(false);
517         fireDateChosen(correctDate(date));
518     }
519 
520     /***
521      * {@inheritDoc} Propagate cancelling.
522      */
523     public void choosingCanceled() {
524         updateTextField(_date);
525         setDropped(false);
526         fireChoosingCanceled();
527     }
528 
529     /***
530      * {@inheritDoc} Do an update on the textfield.
531      */
532     public void dateIntermediateChange(Date date) {
533         updateTextField(date);
534         fireIntermediateChange(correctDate(date));
535     }
536 
537     /***
538      * {@inheritDoc} Do nothing.
539      */
540     public void inputInvalid() {
541         // nothing to do: the panel will never fire an invalid event
542     }
543 
544     // End of DateChooser Listener
545 
546     // FocusListener
547     /***
548      * {@inheritDoc} On gaining focus on the textfield, select its content. If the datechooser does not already own the
549      * focus, notify other listeners.
550      */
551     public void focusGained(FocusEvent evt) {
552         // on gaining focus select the textfield contents if configured
553         if (evt.widget.equals(_textField) && _selectAllOnFocusGained) {
554             _textField.selectAll();
555         }
556         if (!_hasFocus) {
557             _hasFocus = true;
558             super.notifyListeners(SWT.FocusIn, new Event());
559         }
560     }
561 
562     /***
563      * {@inheritDoc} On loosing focus validate the input and check whether the focus will be going to the dropdown. In
564      * latter case do not notify other listeners.
565      */
566     public void focusLost(FocusEvent evt) {
567         // on loosing focus parse the text entered
568         validateInput();
569 
570         // check whether the click occured over the dropdown button and deduce this will not modify
571         // the focus state
572         if (Display.getCurrent().getCursorControl() == _dropdownButton) {
573             _goingToDropDown = true;
574         }
575 
576         if (_hasFocus && !_goingToDropDown) {
577             _hasFocus = false;
578             super.notifyListeners(SWT.FocusOut, new Event());
579         }
580 
581     }
582 
583     // End of FocusListener
584 
585     /***
586      * Parse an input string in the format hh:mm and set this time to the given date.
587      * 
588      * @param text text to parse
589      * @param date date to aply the parsed time to
590      * @return date with time of the parsed string or <code>null</code> to indicate a parse error
591      */
592     protected Date parseTime(String text, Date date) {
593         JaretDate d = new JaretDate(date);
594         try {
595             String hourString = text.substring(0, 2);
596             String minuteString = text.substring(3);
597             int h = Integer.parseInt(hourString);
598             int m = Integer.parseInt(minuteString);
599             d.setHours(h);
600             d.setMinutes(m);
601         } catch (Exception e) {
602             return null;
603         }
604         return d.getDate();
605     }
606 
607     /***
608      * Validate the input currently present in the textfield. Resets a mark if set and handles input behaviour for
609      * invalid inputs.
610      * 
611      * @return true if valid
612      */
613     public boolean validateInput() {
614         boolean valid = false;
615         String text = _textField.getText();
616         Date date = null;
617         date = parseTime(text, _date);
618         valid = date != null;
619 
620         if (date != null) {
621             // parsing successful
622             setDate(date);
623             resetMark(); // in case a mark has been set
624             // fireDateChosen(date);
625         } else {
626             switch (_invalidInputBehaviour) {
627             case KEEP_AND_MARK:
628                 setMark();
629                 break;
630             case RESET_TO_LASTVALID:
631                 updateTextField(_date);
632                 break;
633             default:
634                 throw new RuntimeException("Invalid InputBehaviour set");
635             }
636         }
637         if (!valid && _hasValidInput) {
638             _hasValidInput = valid;
639             fireInputInvalid();
640         }
641         _hasValidInput = valid;
642 
643         return valid;
644     }
645 
646     /***
647      * Reset the background color of the textfield.
648      */
649     private void resetMark() {
650         _textField.setBackground(_textfieldBGColor);
651     }
652 
653     /***
654      * Set the background color of the textfield to the marker color.
655      * 
656      */
657     private void setMark() {
658         _textField.setBackground(MARKER_COLOR);
659     }
660 
661     /***
662      * @return Returns the invalidInputBehaviour.
663      */
664     public int getInvalidInputBehaviour() {
665         return _invalidInputBehaviour;
666     }
667 
668     /***
669      * @param invalidInputBehaviour The invalidInputBehaviour to set.
670      */
671     public void setInvalidInputBehaviour(int invalidInputBehaviour) {
672         _invalidInputBehaviour = invalidInputBehaviour;
673     }
674 
675     /***
676      * @return Returns the editable state.
677      */
678     public boolean isEditable() {
679         return _editable;
680     }
681 
682     /***
683      * Set the editable state. If set to false the textfiled be set to editable(false) and the dropdown will be
684      * disabled.
685      * 
686      * @param editable The editable state to be set.
687      */
688     public void setEditable(boolean editable) {
689         _editable = editable;
690         _textField.setEditable(editable);
691         setDropped(false);
692     }
693 
694     /***
695      * @return the enabled state of the widget.
696      */
697     public boolean isEnabled() {
698         return _enabled;
699     }
700 
701     /***
702      * Set the enabled state of the widget.
703      * 
704      * @param enabled the enabled state to set
705      */
706     public void setEnabled(boolean enabled) {
707         super.setEnabled(enabled);
708         _enabled = enabled;
709         _textField.setEnabled(enabled);
710         _dropdownButton.setEnabled(enabled);
711         setDropped(false);
712     }
713 
714     /***
715      * Return the chooser panel used by the DateChooser.
716      * 
717      * @return DateChooserPanel used by the date chooser.
718      */
719     public TimeChooserPanel getTimeChooserPanel() {
720         // chooser panel need not to be instantiated by now
721         if (_dropDownShell == null) {
722             _dropDownShell = createDropDown();
723         }
724         return _chooserPanel;
725     }
726 
727     /***
728      * Add a DateChooserListener to be informed about changes.
729      * 
730      * @param listener the DateChooserListener to be added
731      */
732     public void addDateChooserListener(IDateChooserListener listener) {
733         if (_listenerList == null) {
734             _listenerList = new ArrayList<IDateChooserListener>();
735         }
736         _listenerList.add(listener);
737     }
738 
739     /***
740      * Remove a DateChooserListener.
741      * 
742      * @param listener the DateChooserListener to be removed
743      */
744     public void remDateChooserListener(IDateChooserListener listener) {
745         if (_listenerList == null) {
746             return;
747         }
748         _listenerList.remove(listener);
749     }
750 
751     /***
752      * Inform listeners that a date has been chosen.
753      * 
754      * @param date chosen date
755      */
756     protected void fireDateChosen(Date date) {
757         if (_listenerList != null) {
758             for (IDateChooserListener listener : _listenerList) {
759                 listener.dateChosen(date);
760             }
761         }
762     }
763 
764     /***
765      * Inform listeners about an intermediate change of the date.
766      * 
767      * @param date current date
768      */
769     protected void fireIntermediateChange(Date date) {
770         if (_listenerList != null) {
771             for (IDateChooserListener listener : _listenerList) {
772                 listener.dateIntermediateChange(date);
773             }
774         }
775     }
776 
777     /***
778      * Inform listeners that the choosing has been cancelled.
779      */
780     protected void fireChoosingCanceled() {
781         if (_listenerList != null) {
782             for (IDateChooserListener listener : _listenerList) {
783                 listener.choosingCanceled();
784             }
785         }
786     }
787 
788     /***
789      * Inform listeners that the current input has become invalid.
790      */
791     protected void fireInputInvalid() {
792         if (_listenerList != null) {
793             for (IDateChooserListener listener : _listenerList) {
794                 listener.inputInvalid();
795             }
796         }
797     }
798 
799     /***
800      * @return Returns the selectAllOnFocusGained.
801      */
802     public boolean isSelectAllOnFocusGained() {
803         return _selectAllOnFocusGained;
804     }
805 
806     /***
807      * @param selectAllOnFocusGained The selectAllOnFocusGained to set.
808      */
809     public void setSelectAllOnFocusGained(boolean selectAllOnFocusGained) {
810         _selectAllOnFocusGained = selectAllOnFocusGained;
811     }
812 
813     /***
814      * @return Returns the fieldIdentifier.
815      */
816     public IFieldIdentifier getFieldIdentifier() {
817         return _fieldIdentifier;
818     }
819 
820     /***
821      * @param fieldIdentifier The fieldIdentifier to set.
822      */
823     public void setFieldIdentifier(IFieldIdentifier fieldIdentifier) {
824         _fieldIdentifier = fieldIdentifier;
825     }
826 
827     /***
828      * Retrieve state of mousewheel support on textfield.
829      * 
830      * @return true if enabled
831      */
832     public boolean isTextfieldMouseWheelEnable() {
833         return _textfieldMouseWheelEnable;
834     }
835 
836     /***
837      * Enable/Disable mousewheel for rolling on text field. Default is true.
838      * 
839      * @param mouseWheelEnable true for enable
840      */
841     public void setTextfieldMouseWheelEnable(boolean mouseWheelEnable) {
842         _textfieldMouseWheelEnable = mouseWheelEnable;
843     }
844 
845     /***
846      * Retrieve a date chooser that has been set for synchronizing the date part of the returned date.
847      * 
848      * @return date chooser or <code>null</code>
849      */
850     public DateChooser getDateChooser() {
851         return _dateChooser;
852     }
853 
854     /***
855      * Set a date chooser that supplies the date part for any returned date (as long as the datechooser provides a
856      * date).
857      * 
858      * @param dateChooser date chooser to sync with
859      */
860     public void setDateChooser(DateChooser dateChooser) {
861         _dateChooser = dateChooser;
862     }
863 
864 }