Author: [EMAIL PROTECTED] Date: Fri Nov 21 21:23:04 2008 New Revision: 4165
Added: branches/1_6_datepicker/user/test/com/google/gwt/user/client/ui/DateBoxTest.java branches/1_6_datepicker/user/test/com/google/gwt/user/client/ui/DatePickerTest.java branches/1_6_datepicker/user/test/com/google/gwt/user/client/ui/DateValueChangeTester.java Modified: branches/1_6_datepicker/reference/code-museum/src/com/google/gwt/museum/SingleIssue.gwt.xml branches/1_6_datepicker/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForDateBox.java branches/1_6_datepicker/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForDatePicker.java branches/1_6_datepicker/user/src/com/google/gwt/user/client/ui/PopupPanel.java branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/DateBox.java branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/DatePicker.java branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/DefaultCalendarView.java branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/DefaultMonthSelector.java branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/ElementMapper.java branches/1_6_datepicker/user/test/com/google/gwt/user/UISuite.java branches/1_6_datepicker/user/test/com/google/gwt/user/client/ui/TextBoxBaseTestBase.java Log: Makes DateBox implement ValueChange, and makes it, like, work. Adds unit tests for DateBox and DatePicker. Removes some broken event handling methods from DateBox that aren't worth fixing b/c they can be done directly to its textbox instead. Adds notiong of an autoHidePartner to PopupPanel, to keep picker from disappearing during mouse events in the date box text field. Should be generally useful. Modified: branches/1_6_datepicker/reference/code-museum/src/com/google/gwt/museum/SingleIssue.gwt.xml ============================================================================== --- branches/1_6_datepicker/reference/code-museum/src/com/google/gwt/museum/SingleIssue.gwt.xml (original) +++ branches/1_6_datepicker/reference/code-museum/src/com/google/gwt/museum/SingleIssue.gwt.xml Fri Nov 21 21:23:04 2008 @@ -6,7 +6,7 @@ <inherits name="com.google.gwt.user.theme.standard.StandardResources"/> <!-- Specify the app entry point class. --> - <entry-point class='com.google.gwt.museum.client.defaultmuseum.VisualsForDatePicker'/> + <entry-point class='com.google.gwt.museum.client.defaultmuseum.VisualsForDateBox'/> <source path="client/common"/> <source path="client/defaultmuseum"/> <source path="client/viewer"/> Modified: branches/1_6_datepicker/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForDateBox.java ============================================================================== --- branches/1_6_datepicker/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForDateBox.java (original) +++ branches/1_6_datepicker/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForDateBox.java Fri Nov 21 21:23:04 2008 @@ -26,11 +26,14 @@ import com.google.gwt.i18n.client.DateTimeFormat; import com.google.gwt.museum.client.common.AbstractIssue; import com.google.gwt.user.client.ui.Button; +import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.Widget; import com.google.gwt.user.datepicker.client.DateBox; +import com.google.gwt.user.datepicker.client.DatePicker; +import com.google.gwt.user.datepicker.client.DateBox.InvalidDateReporter; import java.util.Date; @@ -38,20 +41,42 @@ * Visuals for date box. */ public class VisualsForDateBox extends AbstractIssue { - + @Override public Widget createIssue() { - return dateRange(); + VerticalPanel v = new VerticalPanel(); + v.add(new HTML("<div style='height:25px'></div>")); + v.add(dateRange()); + v.add(new HTML("<div style='height:25px'></div>")); + final Label startErrors = makeErrorLabel(); + + Widget errorReportingDateBox = dateRange(new DateBox.InvalidDateReporter() { + public void clearError() { + startErrors.setText(""); + } + public void reportError(String input) { + startErrors.setText("\"" + input + "\" is not a date"); + } + }); + + v.add(errorReportingDateBox); + v.add(startErrors); + + return v; } @Override public String getInstructions() { - return "Click on first date box, see that date picker is displayed, use arrow keys to navigate to second date box, select a date"; + return "Click on first date box, see that date picker is displayed, " + + "use arrow keys to navigate to second date box, select a date. " + + "The second set includes an error display, see that it notices " + + "when you type garbage, and that its error message is cleared" + + "when you empty the field or provide a valid date."; } @Override public String getSummary() { - return "date box visual test"; + return "date box visual test"; } @Override @@ -60,28 +85,32 @@ } private Widget dateRange() { + return dateRange(null); + } + + private Widget dateRange(InvalidDateReporter invalidDateReporter) { VerticalPanel v = new VerticalPanel(); HorizontalPanel p = new HorizontalPanel(); v.add(p); - final DateBox start = new DateBox(); - start.setWidth("15em"); - final DateBox end = new DateBox(); - end.setWidth("15em"); + final DateBox start = newDateBox(invalidDateReporter); + start.setWidth("13em"); + final DateBox end = newDateBox(invalidDateReporter); + end.setWidth("13em"); start.setAnimationEnabled(true); end.setAnimationEnabled(true); - start.addKeyDownHandler(new KeyDownHandler() { + start.getTextBox().addKeyDownHandler(new KeyDownHandler() { public void onKeyDown(KeyDownEvent e) { if (e.getNativeKeyCode() == KeyCodes.KEY_RIGHT - && start.getCursorPos() == start.getText().length()) { + && start.getCursorPos() == start.getTextBox().getText().length()) { start.hideDatePicker(); end.setFocus(true); } } }); - end.addKeyDownHandler(new KeyDownHandler() { + end.getTextBox().addKeyDownHandler(new KeyDownHandler() { public void onKeyDown(KeyDownEvent e) { if ((e.getNativeKeyCode() == KeyCodes.KEY_LEFT) && end.getCursorPos() == 0) { @@ -97,13 +126,15 @@ } }); - start.showDate(new Date()); + start.setValue(new Date()); p.add(start); Label l = new Label(" - "); l.setStyleName("filler"); p.add(l); p.add(end); + final Label value = new Label(); + p.add(value); HorizontalPanel h2 = new HorizontalPanel(); v.add(h2); h2.add(new Button("Short format", new ClickHandler() { @@ -120,12 +151,38 @@ } })); - h2.add(new Button("clear", new ClickHandler() { + h2.add(new Button("Clear", new ClickHandler() { public void onClick(ClickEvent sender) { - start.clear(); - end.clear(); + start.setValue(null); + end.setValue(null); + } + })); + + h2.add(new Button("Get Value", new ClickHandler() { + public void onClick(ClickEvent event) { + DateTimeFormat f = DateTimeFormat.getShortDateFormat(); + Date d1 = start.getValue(); + Date d2 = end.getValue(); + value.setText("Start: \"" + + (d1 == null ? "null" : f.format(d1)) + + "\" End:\"" + + (d2 == null ? "null" : f.format(d2)) + + "\""); } })); return v; + } + + private Label makeErrorLabel() { + final Label startErrors = new Label(); + startErrors.getElement().getStyle().setProperty("color", "red"); + return startErrors; + } + + private DateBox newDateBox(InvalidDateReporter invalidDateReporter) { + DateBox dateBox = + invalidDateReporter == null ? new DateBox() : new DateBox( + new DatePicker(), invalidDateReporter); + return dateBox; } } Modified: branches/1_6_datepicker/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForDatePicker.java ============================================================================== --- branches/1_6_datepicker/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForDatePicker.java (original) +++ branches/1_6_datepicker/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForDatePicker.java Fri Nov 21 21:23:04 2008 @@ -16,7 +16,16 @@ package com.google.gwt.museum.client.defaultmuseum; +import com.google.gwt.event.logical.shared.HighlightEvent; +import com.google.gwt.event.logical.shared.HighlightHandler; +import com.google.gwt.event.logical.shared.ShowRangeEvent; +import com.google.gwt.event.logical.shared.ShowRangeHandler; +import com.google.gwt.event.logical.shared.ValueChangeEvent; +import com.google.gwt.event.logical.shared.ValueChangeHandler; +import com.google.gwt.i18n.client.DateTimeFormat; import com.google.gwt.museum.client.common.AbstractIssue; +import com.google.gwt.user.client.ui.Label; +import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.Widget; import com.google.gwt.user.datepicker.client.DatePicker; @@ -29,9 +38,35 @@ @Override public Widget createIssue() { + VerticalPanel p = new VerticalPanel(); DatePicker picker = new DatePicker(); - picker.setValue(new Date()); - return picker; + p.add(picker); + final Label value = new Label("value"); + p.add(value); + final Label highlight = new Label("highlight"); + p.add(highlight); + final Label range = new Label("range"); + p.add(range); + picker.addValueChangeHandler(new ValueChangeHandler<Date>() { + public void onValueChange(ValueChangeEvent<Date> event) { + value.setText(DateTimeFormat.getShortDateFormat().format(event.getValue())); + } + }); + picker.addHighlightHandler(new HighlightHandler<Date>() { + public void onHighlight(HighlightEvent<Date> event) { + highlight.setText(DateTimeFormat.getShortDateFormat().format(event.getHighlighted())); + } + }); + picker.addShowRangeHandler(new ShowRangeHandler<Date>() { + public void onShowRange(ShowRangeEvent<Date> event) { + Date start = event.getStart(); + Date end = event.getEnd(); + DateTimeFormat format = DateTimeFormat.getShortDateFormat(); + range.setText(format.format(start) + " - " + format.format(end)); + } + }); +// picker.setValue(new Date()); + return p; }; @Override Modified: branches/1_6_datepicker/user/src/com/google/gwt/user/client/ui/PopupPanel.java ============================================================================== --- branches/1_6_datepicker/user/src/com/google/gwt/user/client/ui/PopupPanel.java (original) +++ branches/1_6_datepicker/user/src/com/google/gwt/user/client/ui/PopupPanel.java Fri Nov 21 21:23:04 2008 @@ -272,6 +272,8 @@ private String desiredWidth; private boolean isAnimationEnabled = false; + + private Element autoHidePartner; /** * The [EMAIL PROTECTED] ResizeAnimation} used to open and close the [EMAIL PROTECTED] PopupPanel}s. @@ -454,6 +456,7 @@ return modal; } + @SuppressWarnings("deprecation") public boolean onEventPreview(Event event) { Element target = DOM.eventGetTarget(event); @@ -485,7 +488,7 @@ return true; } - if (!eventTargetsPopup && autoHide) { + if (!eventTargetsPopup && shouldAutoHide(event)) { hide(true); return true; } @@ -503,7 +506,8 @@ // If it's an outside click and auto-hide is enabled: // hide the popup and _don't_ eat the event. ONMOUSEDOWN is used to // prevent problems with showing a popup in response to a mousedown. - if (!eventTargetsPopup && autoHide && (type == Event.ONMOUSEDOWN)) { + if (!eventTargetsPopup && shouldAutoHide(event) + && (type == Event.ONMOUSEDOWN)) { hide(true); return true; } @@ -581,6 +585,15 @@ } /** + * If the auto hide partner is non null, its mouse events will + * not hide a panel set to autohide. + * @param element new auto hide partner + */ + public void setAutoHidePartner(Element element) { + this.autoHidePartner = element; + } + + /** * Sets the height of the panel's child widget. If the panel's child widget * has not been set, the height passed in will be cached and used to set the * height immediately after the child widget is set. @@ -613,7 +626,7 @@ public void setModal(boolean modal) { this.modal = modal; } - + /** * Sets the popup's position relative to the browser's client area. The * popup's position may be set before calling [EMAIL PROTECTED] #show()}. @@ -820,7 +833,12 @@ elt.blur(); } }-*/; - + + private boolean eventInPartner(Event event) { + return autoHidePartner != null + && autoHidePartner.isOrHasChild(event.getTarget()); + } + /** * Positions the popup, called after the offset width and height of the popup are known. * @@ -948,6 +966,11 @@ top += relativeObject.getOffsetHeight(); } setPopupPosition(left, top); + } + + private boolean shouldAutoHide(Event event) { + boolean shouldAutoHide = autoHide && !eventInPartner(event); + return shouldAutoHide; } } Modified: branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/DateBox.java ============================================================================== --- branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/DateBox.java (original) +++ branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/DateBox.java Fri Nov 21 21:23:04 2008 @@ -22,7 +22,6 @@ import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.FocusEvent; import com.google.gwt.event.dom.client.FocusHandler; -import com.google.gwt.event.dom.client.HasKeyDownHandlers; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.event.dom.client.KeyDownEvent; import com.google.gwt.event.dom.client.KeyDownHandler; @@ -33,8 +32,8 @@ import com.google.gwt.user.client.Command; import com.google.gwt.user.client.DeferredCommand; import com.google.gwt.user.client.ui.Composite; -import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.HasAnimation; +import com.google.gwt.user.client.ui.HasValue; import com.google.gwt.user.client.ui.PopupPanel; import com.google.gwt.user.client.ui.TextBox; @@ -43,26 +42,97 @@ /** * A simple date box. */ -public class DateBox extends Composite implements HasKeyDownHandlers, - HasAnimation { +public class DateBox extends Composite implements HasAnimation, HasValue<Date> { + + /** + * Implemented by a delegate to report errors parsing date values from the + * user's input. + */ + public interface InvalidDateReporter { + /** + * Called when a valid date has been parsed, or the datebox has been + * cleared. + */ + void clearError(); + + /** + * Given an unparseable string, explain the situation to the user. + * + * @param input what the user typed + */ + void reportError(String input); + } + + private class DateBoxHandler implements ValueChangeHandler<Date>, + FocusHandler, BlurHandler, ClickHandler, KeyDownHandler { + + public void onBlur(BlurEvent event) { + if (!popup.isVisible()) { + updateDateFromTextBox(); + } + } + + public void onClick(ClickEvent event) { + showDatePicker(); + } + + public void onFocus(FocusEvent event) { + if (allowDPShow) { + showDatePicker(); + } + } + + public void onKeyDown(KeyDownEvent event) { + switch (event.getNativeKeyCode()) { + case KeyCodes.KEY_ENTER: + case KeyCodes.KEY_TAB: + case KeyCodes.KEY_ESCAPE: + case KeyCodes.KEY_UP: + updateDateFromTextBox(); + hideDatePicker(); + break; + case KeyCodes.KEY_DOWN: + showDatePicker(); + break; + } + } + + public void onValueChange(ValueChangeEvent<Date> event) { + setValue(event.getValue()); + hideDatePicker(); + preventDatePickerPopup(); + box.setFocus(true); + } + } /** * Default style name. */ public static final String DEFAULT_STYLENAME = "gwt-DateBox"; - private static final DateTimeFormat DEFAULT_FORMATTER = DateTimeFormat.getMediumDateFormat(); - private boolean dirtyText = false; - private PopupPanel popup = new PopupPanel(); - private TextBox box = new TextBox(); - private DatePicker picker; - private DateTimeFormat dateFormatter; + + public static final InvalidDateReporter DEFAULT_INVALID_DATE_REPORTER = + new InvalidDateReporter() { + public void clearError() { } + public void reportError(String input) { } + }; + private static final DateTimeFormat DEFAULT_FORMATTER = + DateTimeFormat.getMediumDateFormat(); + + private final PopupPanel popup; + private final TextBox box = new TextBox(); + private final DatePicker picker; + + private final InvalidDateReporter invalidDateReporter; + private DateTimeFormat dateFormatter = DEFAULT_FORMATTER; + private boolean allowDPShow = true; /** - * Create a new date box. + * Create a new date box with a new [EMAIL PROTECTED] DatePicker} and the + * [EMAIL PROTECTED] #DEFAULT_INVALID_DATE_REPORTER}, which does nothing. */ public DateBox() { - this(new DatePicker()); + this(new DatePicker(), DEFAULT_INVALID_DATE_REPORTER); } /** @@ -70,69 +140,16 @@ * * @param picker the picker to drop down from the date box */ - public DateBox(final DatePicker picker) { - this(picker, DEFAULT_FORMATTER); - } - - /** - * Constructor. - * - * @param picker the picker to drop down - * @param formatter date time formatter to use for parsing the dates in this - * date box - */ - public DateBox(final DatePicker picker, DateTimeFormat formatter) { - FlowPanel p = new FlowPanel(); - this.dateFormatter = formatter; - p.add(box); + public DateBox(DatePicker picker, InvalidDateReporter invalidDateReporter) { this.picker = picker; + this.invalidDateReporter = invalidDateReporter; + this.popup = new PopupPanel(); + popup.setAutoHideEnabled(true); + popup.setAutoHidePartner(box.getElement()); popup.setWidget(picker); - initWidget(p); + initWidget(box); setStyleName(DEFAULT_STYLENAME); - class DateBoxHandler implements ValueChangeHandler<Date>, FocusHandler, - BlurHandler, ClickHandler, KeyDownHandler { - - public void onBlur(BlurEvent event) { - if (dirtyText) { - updateDateFromTextBox(); - } - } - - public void onClick(ClickEvent event) { - showCurrentDate(); - } - - public void onFocus(FocusEvent event) { - if (allowDPShow) { - showCurrentDate(); - } - } - - public void onKeyDown(KeyDownEvent event) { - switch (event.getNativeKeyCode()) { - case KeyCodes.KEY_ENTER: - case KeyCodes.KEY_TAB: - case KeyCodes.KEY_ESCAPE: - case KeyCodes.KEY_UP: - updateDateFromTextBox(); - popup.hide(); - break; - case KeyCodes.KEY_DOWN: - showCurrentDate(); - break; - default: - dirtyText = true; - } - } - - public void onValueChange(ValueChangeEvent<Date> event) { - setText(event.getValue()); - hideDatePicker(); - preventDatePickerPopup(); - box.setFocus(true); - } - } DateBoxHandler handler = new DateBoxHandler(); picker.addValueChangeHandler(handler); box.addFocusHandler(handler); @@ -141,16 +158,9 @@ box.addKeyDownHandler(handler); } - public HandlerRegistration addKeyDownHandler(KeyDownHandler handler) { - return addHandler(handler, KeyDownEvent.getType()); - } - - /** - * Clears the current selection. - */ - public void clear() { - picker.setValue(null, false); - box.setText(""); + public HandlerRegistration addValueChangeHandler( + ValueChangeHandler<Date> handler) { + return addHandler(handler, ValueChangeEvent.getType()); } /** @@ -182,21 +192,23 @@ } /** - * Get current text in text box. + * Get text box. * - * @return the text in the date box + * @return the text box used to enter the formatted date */ - public String getText() { - return box.getText(); + public TextBox getTextBox() { + return box; } /** - * Get text box. + * Get the date displayed, or null if the text box is empty, or cannot + * be interpretted. The [EMAIL PROTECTED] InvalidDateReporter} may fire as a side + * effect of this call. * - * @return the text box used to enter the formatted date + * @return the Date */ - public TextBox getTextBox() { - return box; + public Date getValue() { + return parseDate(true); } /** @@ -233,21 +245,17 @@ /** * Sets the date format to the given format. If date box is not empty, - * contents of date box will be replaced with current date in new format. + * contents of date box will be replaced with current date in new format. If + * the date cannot be parsed, the current value will be preserved and the + * InvalidDateReporter notified as usual. * * @param format format. */ public void setDateFormat(DateTimeFormat format) { if (format != dateFormatter) { + Date date = getValue(); dateFormatter = format; - String cur = box.getText(); - if (cur != null && cur.length() != 0) { - try { - box.setText(dateFormatter.format(picker.getValue())); - } catch (IllegalArgumentException e) { - box.setText(""); - } - } + setValue(date); } } @@ -259,7 +267,7 @@ public void setEnabled(boolean enabled) { box.setEnabled(enabled); } - + /** * Explicitly focus/unfocus this widget. Only one widget can have focus at a * time, and the widget that does will receive all keyboard events. @@ -283,21 +291,35 @@ } /** - * Parses the current date box's value and shows that date. + * Set the date. */ - public void showCurrentDate() { - Date current = null; + public void setValue(Date date) { + setValue(date, false); + } - String value = box.getText().trim(); - if (!value.equals("")) { - try { - current = dateFormatter.parse(value); - } catch (IllegalArgumentException e) { - // Does not trigger error reporting because user has not left the text - // box yet. - } + public void setValue(Date date, boolean fireEvents) { + Date oldDate = getValue(); + + if (date == null) { + picker.setValue(null); + box.setText(""); + } else { + picker.setValue(date, false); + picker.setCurrentMonth(date); + setDate(date); } + + invalidDateReporter.clearError(); + if (fireEvents) { + ValueChangeEvent.fireIfNotEqual(this, oldDate, date); + } + } + /** + * Parses the current date box's value and shows that date. + */ + public void showDatePicker() { + Date current = parseDate(false); if (current == null) { current = new Date(); } @@ -305,16 +327,19 @@ popup.showRelativeTo(this); } - /** - * Show the given date. - * - * @param date picker - */ - public void showDate(Date date) { - picker.setValue(date, false); - picker.setCurrentMonth(date); - setText(date); - dirtyText = false; + private Date parseDate(boolean reportError) { + Date d = null; + String text = box.getText().trim(); + if (!text.equals("")) { + try { + d = dateFormatter.parse(text); + } catch (IllegalArgumentException exception) { + if (reportError) { + invalidDateReporter.reportError(text); + } + } + } + return d; } private void preventDatePickerPopup() { @@ -326,23 +351,18 @@ }); } - private void setText(Date value) { + /** + * Does the actual work of setting the date. Performs no validation, + * fires no events. + */ + private void setDate(Date value) { box.setText(dateFormatter.format(value)); - dirtyText = false; } - + private void updateDateFromTextBox() { - String text = box.getText().trim(); - if (text.equals("")) { - return; + Date parsedDate = parseDate(true); + if (parsedDate != null) { + setValue(parsedDate); } - try { - Date d = dateFormatter.parse(text); - showDate(d); - } catch (IllegalArgumentException exception) { - // TODO(ECC) use new reporter interface here. - } - dirtyText = false; } - } Modified: branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/DatePicker.java ============================================================================== --- branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/DatePicker.java (original) +++ branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/DatePicker.java Fri Nov 21 21:23:04 2008 @@ -243,7 +243,7 @@ public HandlerRegistration addHighlightHandler(HighlightHandler<Date> handler) { return addHandler(handler, HighlightEvent.getType()); } - + public HandlerRegistration addShowRangeHandler(ShowRangeHandler<Date> handler) { return addHandler(handler, ShowRangeEvent.getType()); } @@ -258,7 +258,7 @@ public HandlerRegistration addShowRangeHandlerAndFire( ShowRangeHandler<Date> handler) { ShowRangeEvent<Date> event = new ShowRangeEvent<Date>( - getView().getFirstDate(), getView().getLastDate()) { + getView().getFirstDate(), getView().getLastDate()) { }; handler.onShowRange(event); return addShowRangeHandler(handler); @@ -498,7 +498,7 @@ * @param newValue the new value */ public final void setValue(Date newValue) { - setValue(newValue, true); + setValue(newValue, false); } /** @@ -518,7 +518,9 @@ if (value != null) { addGlobalStyleToDate(css().dayIsValue(), value); } - ValueChangeEvent.fire(this, newValue); + if (fireEvents) { + ValueChangeEvent.fireIfNotEqual(this, oldValue, newValue); + } } /** @@ -558,7 +560,7 @@ getMonthSelector().refresh(); ShowRangeEvent.fire(this, getFirstDate(), getLastDate()); } - + /** * Sets up the date picker. */ @@ -584,13 +586,12 @@ /** * Sets the highlighted date. * - * @param highlighted highlighted date + * @param highlightedDate highlighted date */ void setHighlightedDate(Date highlighted) { this.highlighted = highlighted; HighlightEvent.fire(this, highlighted); } - private boolean assertVisible(Date date, Date... moreDates) { assert isDateVisible(date) : date + " must be visible"; if (moreDates != null) { Modified: branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/DefaultCalendarView.java ============================================================================== --- branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/DefaultCalendarView.java (original) +++ branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/DefaultCalendarView.java Fri Nov 21 21:23:04 2008 @@ -24,7 +24,7 @@ /** * Simple calendar view. Not extensible as we wish to evolve it freely over - * time. Please copy though, as we like it getting used. + * time. */ @SuppressWarnings(/* Date manipulation required */{"deprecation"}) @@ -71,7 +71,7 @@ @Override public void onSelected(boolean selected) { if (selected) { - getDatePicker().setValue(getValue()); + getDatePicker().setValue(getValue(), true); if (isFiller()) { getDatePicker().setCurrentMonth(getValue()); } Modified: branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/DefaultMonthSelector.java ============================================================================== --- branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/DefaultMonthSelector.java (original) +++ branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/DefaultMonthSelector.java Fri Nov 21 21:23:04 2008 @@ -23,9 +23,8 @@ import com.google.gwt.user.client.ui.HTMLTable.CellFormatter; /** - * A simple [EMAIL PROTECTED] MonthSelector} used for the default date picker. Not part of - * the public API as we wish to evolve it freely over time. Please copy though, - * as we like it getting used. + * A simple [EMAIL PROTECTED] MonthSelector} used for the default date picker. Not + * extensible as we wish to evolve it freely over time. */ public final class DefaultMonthSelector extends MonthSelector { Modified: branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/ElementMapper.java ============================================================================== --- branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/ElementMapper.java (original) +++ branches/1_6_datepicker/user/src/com/google/gwt/user/datepicker/client/ElementMapper.java Fri Nov 21 21:23:04 2008 @@ -28,9 +28,9 @@ /** * Creates a mapping from elements to their associated ui objects. * - * @param <MappedType> the type that the element is mapped to + * @param <T> the type that the element is mapped to */ -class ElementMapper<MappedType extends UIObject> { +class ElementMapper<T extends UIObject> { private static class FreeNode { int index; @@ -57,7 +57,7 @@ private ElementMapper.FreeNode freeList = null; - private final ArrayList<MappedType> uiObjectList = new ArrayList<MappedType>(); + private final ArrayList<T> uiObjectList = new ArrayList<T>(); /** * Returns the uiObject associated with the given element. @@ -65,7 +65,7 @@ * @param elem uiObject's element * @return the uiObject */ - public MappedType get(Element elem) { + public T get(Element elem) { int index = getIndex(elem); if (index < 0) { return null; @@ -78,7 +78,7 @@ * * @param uiObject uiObject to add */ - public void put(MappedType uiObject) { + public void put(T uiObject) { int index; if (freeList == null) { index = uiObjectList.size(); @@ -106,9 +106,9 @@ * * @return the iterator */ - public Iterator<MappedType> iterator() { + public Iterator<T> iterator() { - return new Iterator() { + return new Iterator<T>() { int lastIndex = -1; int nextIndex = -1; { @@ -119,11 +119,11 @@ return nextIndex < uiObjectList.size(); } - public Object next() { + public T next() { if (!hasNext()) { throw new NoSuchElementException(); } - Object result = uiObjectList.get(nextIndex); + T result = uiObjectList.get(nextIndex); lastIndex = nextIndex; findNext(); return result; @@ -133,6 +133,7 @@ if (lastIndex < 0) { throw new IllegalStateException(); } + // TODO(ecc) ??? Widget w = (Widget) uiObjectList.get(lastIndex); assert (w.getParent() instanceof HTMLTable); w.removeFromParent(); Modified: branches/1_6_datepicker/user/test/com/google/gwt/user/UISuite.java ============================================================================== --- branches/1_6_datepicker/user/test/com/google/gwt/user/UISuite.java (original) +++ branches/1_6_datepicker/user/test/com/google/gwt/user/UISuite.java Fri Nov 21 21:23:04 2008 @@ -26,6 +26,8 @@ import com.google.gwt.user.client.ui.CompositeTest; import com.google.gwt.user.client.ui.CustomButtonTest; import com.google.gwt.user.client.ui.DOMTest; +import com.google.gwt.user.client.ui.DateBoxTest; +import com.google.gwt.user.client.ui.DatePickerTest; import com.google.gwt.user.client.ui.DeckPanelTest; import com.google.gwt.user.client.ui.DecoratedPopupTest; import com.google.gwt.user.client.ui.DecoratedStackPanelTest; @@ -94,6 +96,8 @@ suite.addTestSuite(CompositeTest.class); suite.addTestSuite(CookieTest.class); suite.addTestSuite(CustomButtonTest.class); + suite.addTestSuite(DateBoxTest.class); + suite.addTestSuite(DatePickerTest.class); suite.addTestSuite(DeckPanelTest.class); suite.addTestSuite(DecoratedPopupTest.class); suite.addTestSuite(DecoratedStackPanelTest.class); Added: branches/1_6_datepicker/user/test/com/google/gwt/user/client/ui/DateBoxTest.java ============================================================================== --- (empty file) +++ branches/1_6_datepicker/user/test/com/google/gwt/user/client/ui/DateBoxTest.java Fri Nov 21 21:23:04 2008 @@ -0,0 +1,34 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.google.gwt.user.client.ui; + +import com.google.gwt.junit.client.GWTTestCase; +import com.google.gwt.user.datepicker.client.DateBox; + +/** + * Tests DateBox. + */ +public class DateBoxTest extends GWTTestCase { + public String getModuleName() { + return "com.google.gwt.user.User"; + } + + public void testValueChangeEvent() { + DateBox db = new DateBox(); + RootPanel.get().add(db); + new DateValueChangeTester(db).run(); + } +} Added: branches/1_6_datepicker/user/test/com/google/gwt/user/client/ui/DatePickerTest.java ============================================================================== --- (empty file) +++ branches/1_6_datepicker/user/test/com/google/gwt/user/client/ui/DatePickerTest.java Fri Nov 21 21:23:04 2008 @@ -0,0 +1,41 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.google.gwt.user.client.ui; + +import com.google.gwt.junit.client.GWTTestCase; +import com.google.gwt.user.datepicker.client.DatePicker; + +/** + * Tests DatePicker. + */ +public class DatePickerTest extends GWTTestCase { + private DatePicker dp; + + public String getModuleName() { + return "com.google.gwt.user.User"; + } + + @Override + protected void gwtSetUp() throws Exception { + super.gwtSetUp(); + dp = new DatePicker(); + RootPanel.get().add(dp); + } + + public void testValueChangeEvent() { + new DateValueChangeTester(dp).run(); + } +} Added: branches/1_6_datepicker/user/test/com/google/gwt/user/client/ui/DateValueChangeTester.java ============================================================================== --- (empty file) +++ branches/1_6_datepicker/user/test/com/google/gwt/user/client/ui/DateValueChangeTester.java Fri Nov 21 21:23:04 2008 @@ -0,0 +1,70 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.google.gwt.user.client.ui; + +import com.google.gwt.event.logical.shared.ValueChangeEvent; +import com.google.gwt.event.logical.shared.ValueChangeHandler; + +import junit.framework.TestCase; + +import java.util.Date; + +/** + * Handy tool for testing classes that implement [EMAIL PROTECTED] HasValue<Date>}. + */ +public class DateValueChangeTester { + static class Handler implements ValueChangeHandler<Date> { + Date received = null; + + public void onValueChange(ValueChangeEvent<Date> event) { + received = event.getValue(); + } + } + + private final HasValue<Date> subject; + public DateValueChangeTester(HasValue<Date> subject) { + this.subject = subject; + } + + @SuppressWarnings("deprecation") + public void run() { + subject.setValue(null); + TestCase.assertNull(subject.getValue()); + + Date able = new Date(1999, 5, 15); + subject.setValue(able); + TestCase.assertEquals(able, subject.getValue()); + + DateValueChangeTester.Handler h = new Handler(); + subject.addValueChangeHandler(h); + + subject.setValue(able); + TestCase.assertNull(h.received); + + Date baker = new Date(1965, 12, 7); + subject.setValue(baker); + TestCase.assertNull(h.received); + + subject.setValue(baker, true); + TestCase.assertNull(h.received); + + subject.setValue(able, true); + TestCase.assertEquals(able, h.received); + + subject.setValue(baker, true); + TestCase.assertEquals(baker, h.received); + } +} \ No newline at end of file Modified: branches/1_6_datepicker/user/test/com/google/gwt/user/client/ui/TextBoxBaseTestBase.java ============================================================================== --- branches/1_6_datepicker/user/test/com/google/gwt/user/client/ui/TextBoxBaseTestBase.java (original) +++ branches/1_6_datepicker/user/test/com/google/gwt/user/client/ui/TextBoxBaseTestBase.java Fri Nov 21 21:23:04 2008 @@ -104,16 +104,19 @@ Handler h = new Handler(); tb.addValueChangeHandler(h); tb.setText("able"); + assertEquals("able", tb.getValue()); assertNull(h.received); - + tb.setValue("able"); + assertEquals("able", tb.getValue()); assertNull(h.received); tb.setValue("baker"); assertNull(h.received); tb.setValue("baker", true); + assertEquals("baker", tb.getValue()); assertNull(h.received); - + tb.setValue("able", true); assertEquals("able", h.received); --~--~---------~--~----~------------~-------~--~----~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~----------~----~----~----~------~----~------~--~---