|
30 | 30 | package nextapp.echo.extras.app; |
31 | 31 |
|
32 | 32 | import java.util.Date; |
| 33 | +import java.util.EventListener; |
33 | 34 |
|
34 | 35 | import nextapp.echo.app.Border; |
35 | 36 | import nextapp.echo.app.Color; |
36 | 37 | import nextapp.echo.app.Component; |
37 | 38 | import nextapp.echo.app.FillImage; |
| 39 | +import nextapp.echo.app.event.ActionEvent; |
| 40 | +import nextapp.echo.app.event.ActionListener; |
38 | 41 |
|
39 | 42 | /** |
40 | 43 | * <code>CalendarSelect</code> component: an input component which allows selection of a single date. Displays a representation of a |
41 | 44 | * calendar, showing the currently selected month/year. May not contain child components. |
42 | 45 | */ |
43 | 46 | public class CalendarSelect extends Component { |
44 | 47 |
|
| 48 | + public static final String ACTION_LISTENERS_CHANGED_PROPERTY = "actionListeners"; |
| 49 | + |
| 50 | + public static final String INPUT_ACTION = "action"; |
| 51 | + |
45 | 52 | public static final String DATE_CHANGED_PROPERTY = "date"; |
| 53 | + public static final String PROPERTY_ACTION_COMMAND = "actionCommand"; |
46 | 54 | public static final String PROPERTY_ADJACENT_MONTH_DATE_BACKGROUND = "adjacentMonthDateBackground"; |
47 | 55 | public static final String PROPERTY_ADJACENT_MONTH_DATE_FOREGROUND = "adjacentMonthDateForeground"; |
48 | 56 | public static final String PROPERTY_BORDER = "border"; |
@@ -87,6 +95,51 @@ public CalendarSelect(Date date) { |
87 | 95 | this.date = date; |
88 | 96 | } |
89 | 97 |
|
| 98 | + /** |
| 99 | + * Adds an <code>ActionListener</code> to the <code>CalendarSelect</code>. |
| 100 | + * The <code>ActionListener</code> will be invoked each time a date is selected, |
| 101 | + * either by changing month, day, or year. |
| 102 | + * <p> |
| 103 | + * Beware of using this listener to *enforce* date selection within a range, as |
| 104 | + * the user may intend to modify one or parameter of a date such that it may |
| 105 | + * be temporarily invalid. |
| 106 | + * |
| 107 | + * @param l the <code>ActionListener</code> to add |
| 108 | + */ |
| 109 | + public void addActionListener(ActionListener l) { |
| 110 | + getEventListenerList().addListener(ActionListener.class, l); |
| 111 | + // Notification of action listener changes is provided due to |
| 112 | + // existence of hasActionListeners() method. |
| 113 | + firePropertyChange(ACTION_LISTENERS_CHANGED_PROPERTY, null, l); |
| 114 | + } |
| 115 | + |
| 116 | + /** |
| 117 | + * Fires an action event to all listeners. |
| 118 | + */ |
| 119 | + private void fireActionEvent() { |
| 120 | + if (!hasEventListenerList()) { |
| 121 | + return; |
| 122 | + } |
| 123 | + EventListener[] listeners = getEventListenerList().getListeners(ActionListener.class); |
| 124 | + ActionEvent e = null; |
| 125 | + for (int i = 0; i < listeners.length; ++i) { |
| 126 | + if (e == null) { |
| 127 | + e = new ActionEvent(this, (String) getRenderProperty(PROPERTY_ACTION_COMMAND)); |
| 128 | + } |
| 129 | + ((ActionListener) listeners[i]).actionPerformed(e); |
| 130 | + } |
| 131 | + } |
| 132 | + |
| 133 | + /** |
| 134 | + * Returns the action command which will be provided in |
| 135 | + * <code>ActionEvent</code>s fired by this <code>CalendarSelect</code>. |
| 136 | + * |
| 137 | + * @return the action command |
| 138 | + */ |
| 139 | + public String getActionCommand() { |
| 140 | + return (String) get(PROPERTY_ACTION_COMMAND); |
| 141 | + } |
| 142 | + |
90 | 143 | /** |
91 | 144 | * Returns the background color of dates in adjacent (previous/next) months. |
92 | 145 | * |
@@ -279,13 +332,49 @@ public Color getSelectedDateForeground() { |
279 | 332 | return (Color) get(PROPERTY_SELECTED_DATE_FOREGROUND); |
280 | 333 | } |
281 | 334 |
|
| 335 | + /** |
| 336 | + * Determines if any <code>ActionListener</code>s are registered. |
| 337 | + * |
| 338 | + * @return true if any action listeners are registered |
| 339 | + */ |
| 340 | + public boolean hasActionListeners() { |
| 341 | + return hasEventListenerList() && getEventListenerList().getListenerCount(ActionListener.class) != 0; |
| 342 | + } |
| 343 | + |
282 | 344 | /** |
283 | 345 | * @see nextapp.echo.app.Component#processInput(java.lang.String, java.lang.Object) |
284 | 346 | */ |
285 | 347 | public void processInput(String inputName, Object inputValue) { |
286 | 348 | if (DATE_CHANGED_PROPERTY.equals(inputName)) { |
287 | 349 | setDate((Date) inputValue); |
| 350 | + } else if (INPUT_ACTION.equals(inputName)) { |
| 351 | + fireActionEvent(); |
| 352 | + } |
| 353 | + } |
| 354 | + |
| 355 | + /** |
| 356 | + * Removes an <code>ActionListener</code> from the <code>CalendarSelect</code>. |
| 357 | + * |
| 358 | + * @param l the <code>ActionListener</code> to remove |
| 359 | + */ |
| 360 | + public void removeActionListener(ActionListener l) { |
| 361 | + if (!hasEventListenerList()) { |
| 362 | + return; |
288 | 363 | } |
| 364 | + getEventListenerList().removeListener(ActionListener.class, l); |
| 365 | + // Notification of action listener changes is provided due to |
| 366 | + // existence of hasActionListeners() method. |
| 367 | + firePropertyChange(ACTION_LISTENERS_CHANGED_PROPERTY, l, null); |
| 368 | + } |
| 369 | + |
| 370 | + /** |
| 371 | + * Sets the action command which will be provided in |
| 372 | + * <code>ActionEvent</code>s fired by this <code>CalendarSelect</code>. |
| 373 | + * |
| 374 | + * @param newValue the new action command |
| 375 | + */ |
| 376 | + public void setActionCommand(String newValue) { |
| 377 | + set(PROPERTY_ACTION_COMMAND, newValue); |
289 | 378 | } |
290 | 379 |
|
291 | 380 | /** |
|
0 commit comments