This patch:
- reuses editors in every IsEditor widget (issue 5479)
- adds a ValueLabel widget, and DateLabel and NumberLabel subclasses
(issue 5507), introduces a NumberFormatRenderer (similar to the
existing DateTimeFormatRenderer) for use in NumberLabel (this one is
a paraterized class to make it usable with Editors:
NumberLabel<Double>, NumberLabel<Integer>, etc.)
- makes ToggleButton an IsEditor<LeafValueEditor<Boolean>> (issue
5571)
- makes SimpleCheckBox a TakesValue<Boolean> and
IsEditor<LeafValueEditor<Boolean>> to put it on par with CheckBox
- makes Hidden implement TakesValue<String> and
IsEditor<LeafValueEditor<String>>, which makes it usable with editors
*and* FormPanel (SimpleEditor is OK if you're not using FormPanel)
Public review at http://gwt-code-reviews.appspot.com/1099801/show
Patch by: tbroyer
Review by: rjrjr, jat
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9297 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/i18n/client/DateTimeFormatInfo.java b/user/src/com/google/gwt/i18n/client/DateTimeFormatInfo.java
index a4d3fb2..6672ac8 100644
--- a/user/src/com/google/gwt/i18n/client/DateTimeFormatInfo.java
+++ b/user/src/com/google/gwt/i18n/client/DateTimeFormatInfo.java
@@ -98,7 +98,7 @@
* @param timePattern the time pattern String
* @param datePattern the data pattern String
*/
- String dateTimeShort(String datePattern, String timePattern);
+ String dateTimeShort(String timePattern, String datePattern);
/**
* Returns an array of the full era names.
diff --git a/user/src/com/google/gwt/text/client/DateTimeFormatRenderer.java b/user/src/com/google/gwt/text/client/DateTimeFormatRenderer.java
index 9a8699b..78af84d 100644
--- a/user/src/com/google/gwt/text/client/DateTimeFormatRenderer.java
+++ b/user/src/com/google/gwt/text/client/DateTimeFormatRenderer.java
@@ -47,6 +47,7 @@
* Create an instance with the given format and time zone.
*/
public DateTimeFormatRenderer(DateTimeFormat format, TimeZone timeZone) {
+ assert format != null;
this.format = format;
this.timeZone = timeZone;
}
diff --git a/user/src/com/google/gwt/text/client/NumberFormatRenderer.java b/user/src/com/google/gwt/text/client/NumberFormatRenderer.java
new file mode 100644
index 0000000..b6e1e88
--- /dev/null
+++ b/user/src/com/google/gwt/text/client/NumberFormatRenderer.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2010 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.text.client;
+
+import com.google.gwt.i18n.client.NumberFormat;
+import com.google.gwt.text.shared.AbstractRenderer;
+
+/**
+ * Renders {@link Number} objects with a {@link NumberFormat}.
+ */
+public class NumberFormatRenderer extends AbstractRenderer<Number> {
+ private final NumberFormat format;
+
+ /**
+ * Create an instance using {@link NumberFormat#getDecimalFormat()}.
+ */
+ public NumberFormatRenderer() {
+ this(NumberFormat.getDecimalFormat());
+ }
+
+ /**
+ * Create an instance with the given format.
+ */
+ public NumberFormatRenderer(NumberFormat format) {
+ this.format = format;
+ }
+
+ public String render(Number object) {
+ if (object == null) {
+ return "";
+ }
+ return format.format(object);
+ }
+}
diff --git a/user/src/com/google/gwt/uibinder/elementparsers/DateLabelParser.java b/user/src/com/google/gwt/uibinder/elementparsers/DateLabelParser.java
new file mode 100644
index 0000000..1359664
--- /dev/null
+++ b/user/src/com/google/gwt/uibinder/elementparsers/DateLabelParser.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2010 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.uibinder.elementparsers;
+
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.typeinfo.JClassType;
+import com.google.gwt.core.ext.typeinfo.JType;
+import com.google.gwt.core.ext.typeinfo.TypeOracle;
+import com.google.gwt.core.ext.typeinfo.TypeOracleException;
+import com.google.gwt.i18n.client.DateTimeFormat;
+import com.google.gwt.i18n.client.TimeZone;
+import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat;
+import com.google.gwt.uibinder.rebind.UiBinderWriter;
+import com.google.gwt.uibinder.rebind.XMLElement;
+
+/**
+ * Parses {@link com.google.gwt.user.client.ui.DateLabel} widgets.
+ */
+public class DateLabelParser implements ElementParser {
+
+ static final String AT_MOST_ONE_SPECIFIED_FORMAT = "May have at most one of format, predefinedFormat and customFormat.";
+ static final String AT_MOST_ONE_SPECIFIED_TIME_ZONE = "May have at most one of timezone and timezoneOffset.";
+ static final String NO_TIMEZONE_WITHOUT_SPECIFIED_FORMAT = "May not specify a time zone if no format is given.";
+
+ public void parse(XMLElement elem, String fieldName, JClassType type,
+ UiBinderWriter writer) throws UnableToCompleteException {
+ boolean supportsTimeZone = hasDateTimeFormatAndTimeZoneConstructor(
+ writer.getOracle(), type);
+ if (hasDateTimeFormatConstructor(writer.getOracle(), type)
+ || supportsTimeZone) {
+ String format = consumeFormat(elem, writer);
+
+ if (format != null) {
+ String timeZone = (supportsTimeZone ? consumeTimeZone(elem, writer)
+ : null);
+
+ writer.setFieldInitializerAsConstructor(fieldName, type, makeArgs(
+ format, timeZone));
+ } else if (supportsTimeZone && hasTimeZone(elem)) {
+ writer.die(elem, NO_TIMEZONE_WITHOUT_SPECIFIED_FORMAT);
+ }
+ }
+ }
+
+ private String consumeFormat(XMLElement elem, UiBinderWriter writer)
+ throws UnableToCompleteException {
+ String format = elem.consumeAttribute("format",
+ writer.getOracle().findType(DateTimeFormat.class.getCanonicalName()));
+ String predefinedFormat = elem.consumeAttribute("predefinedFormat",
+ writer.getOracle().findType(PredefinedFormat.class.getCanonicalName()));
+ String customFormat = elem.consumeStringAttribute("customFormat");
+
+ if (format != null) {
+ if (predefinedFormat != null || customFormat != null) {
+ writer.die(elem, AT_MOST_ONE_SPECIFIED_FORMAT);
+ }
+ return format;
+ }
+ if (predefinedFormat != null) {
+ if (customFormat != null) {
+ writer.die(elem, AT_MOST_ONE_SPECIFIED_FORMAT);
+ }
+ return makeGetFormat(predefinedFormat);
+ }
+ if (customFormat != null) {
+ return makeGetFormat(customFormat);
+ }
+ return null;
+ }
+
+ private String consumeTimeZone(XMLElement elem, UiBinderWriter writer)
+ throws UnableToCompleteException {
+ String timeZone = elem.consumeAttribute("timezone",
+ writer.getOracle().findType(TimeZone.class.getCanonicalName()));
+ String timeZoneOffset = elem.consumeAttribute("timezoneOffset",
+ getIntType(writer.getOracle()));
+ if (timeZone != null && timeZoneOffset != null) {
+ writer.die(elem, AT_MOST_ONE_SPECIFIED_TIME_ZONE);
+ }
+ if (timeZone != null) {
+ return timeZone;
+ }
+ if (timeZoneOffset != null) {
+ return TimeZone.class.getCanonicalName() + ".createTimeZone("
+ + timeZoneOffset + ")";
+ }
+ return null;
+ }
+
+ private JType getIntType(TypeOracle oracle) {
+ try {
+ return oracle.parse("int");
+ } catch (TypeOracleException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private boolean hasDateTimeFormatAndTimeZoneConstructor(
+ TypeOracle typeOracle, JClassType type) {
+ JType dateTimeFormatType = typeOracle.findType(DateTimeFormat.class.getName());
+ JType timeZoneType = typeOracle.findType(TimeZone.class.getName());
+ return type.findConstructor(new JType[] {dateTimeFormatType, timeZoneType}) != null;
+ }
+
+ private boolean hasDateTimeFormatConstructor(TypeOracle typeOracle,
+ JClassType type) {
+ JType dateTimeFormatType = typeOracle.findType(DateTimeFormat.class.getName());
+ return type.findConstructor(new JType[] {dateTimeFormatType}) != null;
+ }
+
+ private boolean hasTimeZone(XMLElement elem) {
+ return elem.hasAttribute("timezone") || elem.hasAttribute("timezoneOffset");
+ }
+
+ private String[] makeArgs(String format, String timeZone) {
+ if (timeZone == null) {
+ return new String[] {format};
+ }
+ return new String[] {format, timeZone};
+ }
+
+ private String makeGetFormat(String format) {
+ return DateTimeFormat.class.getCanonicalName() + ".getFormat(" + format
+ + ")";
+ }
+}
diff --git a/user/src/com/google/gwt/uibinder/elementparsers/NumberLabelParser.java b/user/src/com/google/gwt/uibinder/elementparsers/NumberLabelParser.java
new file mode 100644
index 0000000..5ff6656
--- /dev/null
+++ b/user/src/com/google/gwt/uibinder/elementparsers/NumberLabelParser.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2010 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.uibinder.elementparsers;
+
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.typeinfo.JClassType;
+import com.google.gwt.core.ext.typeinfo.JType;
+import com.google.gwt.core.ext.typeinfo.TypeOracle;
+import com.google.gwt.i18n.client.CurrencyData;
+import com.google.gwt.i18n.client.DateTimeFormat;
+import com.google.gwt.i18n.client.NumberFormat;
+import com.google.gwt.uibinder.rebind.UiBinderWriter;
+import com.google.gwt.uibinder.rebind.XMLElement;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Parses {@link com.google.gwt.user.client.ui.DateLabel} widgets.
+ */
+public class NumberLabelParser implements ElementParser {
+
+ static final String AT_MOST_ONE_SPECIFIED_FORMAT = "May have only one of format, predefinedFormat and customFormat.";
+ static final String AT_MOST_ONE_SPECIFIED_CURRENCY = "May have only one of currencyData and customCode.";
+ static final String NO_CURRENCY_WITH_FORMAT = "May not specify both a NumberFormat and a currency code.";
+ static final String NO_CURRENCY_WITHOUT_SPECIFIED_FORMAT = "May not specify a currency code if no format is given.";
+ static final String NO_CURRENCY_WITH_PREDEFINED_FORMAT = "May not specify a currency code with a predefined format (except the CURRENCY format)";
+ static final String UNKNOWN_PREDEFINED_FORMAT = "Unknown predefined format: %s";
+
+ private static final Map<String, String> predefinedFormats;
+
+ static {
+ String prefix = NumberFormat.class.getCanonicalName();
+ Map<String, String> formats = new HashMap<String, String>(4);
+ formats.put("DECIMAL", prefix + ".getDecimalFormat()");
+ formats.put("PERCENT", prefix + ".getPercentFormat()");
+ formats.put("SCIENTIFIC", prefix + ".getScientificFormat()");
+ // CURRENCY is special-cased in consumeFormat.
+ predefinedFormats = Collections.unmodifiableMap(formats);
+ }
+
+ public void parse(XMLElement elem, String fieldName, JClassType type,
+ UiBinderWriter writer) throws UnableToCompleteException {
+ if (hasNumberFormatConstructor(writer.getOracle(), type)) {
+ String format = consumeFormat(elem, writer);
+
+ if (format != null) {
+ writer.setFieldInitializerAsConstructor(fieldName, type, format);
+ }
+ }
+ }
+
+ private String consumeCurrency(XMLElement elem, UiBinderWriter writer)
+ throws UnableToCompleteException {
+ String currencyData = elem.consumeAttribute("currencyData",
+ writer.getOracle().findType(CurrencyData.class.getCanonicalName()));
+ String currencyCode = elem.consumeStringAttribute("currencyCode");
+
+ if (currencyData != null && currencyCode != null) {
+ writer.die(elem, AT_MOST_ONE_SPECIFIED_CURRENCY);
+ }
+ return currencyData != null ? currencyData : currencyCode;
+ }
+
+ private String consumeFormat(XMLElement elem, UiBinderWriter writer)
+ throws UnableToCompleteException {
+ String format = elem.consumeAttribute("format",
+ writer.getOracle().findType(DateTimeFormat.class.getCanonicalName()));
+ String predefinedFormat = elem.consumeRawAttribute("predefinedFormat");
+ String customFormat = elem.consumeStringAttribute("customFormat");
+
+ if (format != null) {
+ if (predefinedFormat != null || customFormat != null) {
+ writer.die(elem, AT_MOST_ONE_SPECIFIED_FORMAT);
+ }
+ if (hasCurrency(elem)) {
+ writer.die(elem, NO_CURRENCY_WITH_FORMAT);
+ }
+ return format;
+ }
+ if (predefinedFormat != null) {
+ if (customFormat != null) {
+ writer.die(elem, AT_MOST_ONE_SPECIFIED_FORMAT);
+ }
+ if ("CURRENCY".equals(predefinedFormat)) {
+ String currency = consumeCurrency(elem, writer);
+ return NumberFormat.class.getCanonicalName() + ".getCurrencyFormat("
+ + (currency != null ? currency : "") + ")";
+ }
+ if (hasCurrency(elem)) {
+ writer.die(elem, NO_CURRENCY_WITH_PREDEFINED_FORMAT);
+ }
+ String f = predefinedFormats.get(predefinedFormat);
+ if (f == null) {
+ writer.die(elem, UNKNOWN_PREDEFINED_FORMAT, predefinedFormat);
+ }
+ return f;
+ }
+ if (customFormat != null) {
+ String currency = consumeCurrency(elem, writer);
+ return NumberFormat.class.getCanonicalName() + ".getFormat(" + customFormat
+ + (currency != null ? ", " + currency : "") + ")";
+ }
+ if (hasCurrency(elem)) {
+ writer.die(elem, NO_CURRENCY_WITHOUT_SPECIFIED_FORMAT);
+ }
+ return null;
+ }
+
+ private boolean hasCurrency(XMLElement elem) {
+ return elem.hasAttribute("currencyData")
+ || elem.hasAttribute("currencyCode");
+ }
+
+ private boolean hasNumberFormatConstructor(TypeOracle typeOracle,
+ JClassType type) {
+ JType numberFormatType = typeOracle.findType(NumberFormat.class.getName());
+ return type.findConstructor(new JType[] {numberFormatType}) != null;
+ }
+}
diff --git a/user/src/com/google/gwt/uibinder/rebind/UiBinderParser.java b/user/src/com/google/gwt/uibinder/rebind/UiBinderParser.java
index bc5c3a3..4297a32 100644
--- a/user/src/com/google/gwt/uibinder/rebind/UiBinderParser.java
+++ b/user/src/com/google/gwt/uibinder/rebind/UiBinderParser.java
@@ -264,10 +264,10 @@
/* Perhaps it is provided via @UiField */
if (ownerField != null) {
- if (!resourceType.equals(ownerField.getType().getRawType())) {
+ if (!resourceType.getErasedType().equals(ownerField.getType().getRawType()
+ .getErasedType())) {
writer.die(elem, "Type must match %s", ownerField);
}
-
if (ownerField.isProvided()) {
String initializer;
if (writer.getDesignTime().isDesignTime()) {
diff --git a/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java b/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java
index e807ac6..a7589b5 100644
--- a/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java
+++ b/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java
@@ -998,6 +998,8 @@
addWidgetParser("ListBox");
addWidgetParser("Grid");
addWidgetParser("HasAlignment");
+ addWidgetParser("DateLabel");
+ addWidgetParser("NumberLabel");
}
/**
diff --git a/user/src/com/google/gwt/user/client/ui/CheckBox.java b/user/src/com/google/gwt/user/client/ui/CheckBox.java
index 75635ee..3549e0d 100644
--- a/user/src/com/google/gwt/user/client/ui/CheckBox.java
+++ b/user/src/com/google/gwt/user/client/ui/CheckBox.java
@@ -59,6 +59,7 @@
HasWordWrap, IsEditor<LeafValueEditor<Boolean>> {
InputElement inputElem;
LabelElement labelElem;
+ private LeafValueEditor<Boolean> editor;
private boolean valueChangeHandlerInitialized;
/**
@@ -134,7 +135,10 @@
}
public LeafValueEditor<Boolean> asEditor() {
- return TakesValueEditor.of(this);
+ if (editor == null) {
+ editor = TakesValueEditor.of(this);
+ }
+ return editor;
}
/**
@@ -172,7 +176,7 @@
/**
* Determines whether this check box is currently checked.
* <p>
- * Note that this <em>is not</em> return the value property of the checkbox
+ * Note that this <em>does not</em> return the value property of the checkbox
* input element wrapped by this widget. For access to that property, see
* {@link #getFormValue()}
*
diff --git a/user/src/com/google/gwt/user/client/ui/DateLabel.java b/user/src/com/google/gwt/user/client/ui/DateLabel.java
new file mode 100644
index 0000000..0c925a8
--- /dev/null
+++ b/user/src/com/google/gwt/user/client/ui/DateLabel.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2010 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.i18n.client.DateTimeFormat;
+import com.google.gwt.i18n.client.TimeZone;
+import com.google.gwt.text.client.DateTimeFormatRenderer;
+
+import java.util.Date;
+
+/**
+ * Extends {@link ValueLabel} for convenience when dealing with dates and
+ * {@link DateTimeFormat}, especially in
+ * {@link com.google.gwt.uibinder.client.UiBinder UiBinder} templates. (Note
+ * that this class does not accept renderers. To do so use {@link ValueLabel}
+ * directly.)
+ *
+ * <h3>Use in UiBinder Templates</h3>
+ * In {@link com.google.gwt.uibinder.client.UiBinder UiBinder} templates, both the format and time zone can be configured.
+ * <p>
+ * The format can be given with one of these attributes:
+ * <dl>
+ * <dt>format</dt><dd>a reference to a {@link DateTimeFormat} instance.</dd>
+ * <dt>predefinedFormat</dt><dd>a {@link DateTimeFormat.PredefinedFormat}.</dd>
+ * <dt>customFormat</dt><dd>a date time pattern that can be passed to {@link DateTimeFormat#getFormat(String)}.</dd>
+ * </dl>
+ * <p>
+ * The time zone can be specified with either of these attributes:
+ * <dl>
+ * <dt>timezone</dt><dd>a reference to a {@link TimeZone} instance.</dd>
+ * <dt>timezoneOffset</dt><dd>the time zone offset in minutes.</dd>
+ * </dl>
+ */
+public class DateLabel extends ValueLabel<Date> {
+
+ public DateLabel() {
+ super(new DateTimeFormatRenderer());
+ }
+
+ public DateLabel(DateTimeFormat format) {
+ super(new DateTimeFormatRenderer(format));
+ }
+
+ public DateLabel(DateTimeFormat format, TimeZone timeZone) {
+ super(new DateTimeFormatRenderer(format, timeZone));
+ }
+}
diff --git a/user/src/com/google/gwt/user/client/ui/Hidden.java b/user/src/com/google/gwt/user/client/ui/Hidden.java
index fcd978b..d9f1466 100644
--- a/user/src/com/google/gwt/user/client/ui/Hidden.java
+++ b/user/src/com/google/gwt/user/client/ui/Hidden.java
@@ -18,11 +18,15 @@
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.InputElement;
+import com.google.gwt.editor.client.IsEditor;
+import com.google.gwt.editor.client.LeafValueEditor;
+import com.google.gwt.editor.client.adapters.TakesValueEditor;
+import com.google.gwt.user.client.TakesValue;
/**
* Represents a hidden field in an HTML form.
*/
-public class Hidden extends Widget implements HasName {
+public class Hidden extends Widget implements HasName, TakesValue<String>, IsEditor<LeafValueEditor<String>> {
/**
* Creates a Hidden widget that wraps an existing <input type='hidden'>
@@ -47,6 +51,8 @@
return hidden;
}
+ private LeafValueEditor<String> editor;
+
/**
* Constructor for <code>Hidden</code>.
*/
@@ -87,6 +93,13 @@
setElement(element);
}
+ public LeafValueEditor<String> asEditor() {
+ if (editor == null) {
+ editor = TakesValueEditor.of(this);
+ }
+ return editor;
+ }
+
/**
* Gets the default value of the hidden field.
*
diff --git a/user/src/com/google/gwt/user/client/ui/Label.java b/user/src/com/google/gwt/user/client/ui/Label.java
index a2ab4bc..29bb577 100644
--- a/user/src/com/google/gwt/user/client/ui/Label.java
+++ b/user/src/com/google/gwt/user/client/ui/Label.java
@@ -59,7 +59,6 @@
import com.google.gwt.i18n.client.BidiUtils;
import com.google.gwt.i18n.client.HasDirection;
import com.google.gwt.i18n.shared.DirectionEstimator;
-import com.google.gwt.i18n.shared.HasDirectionEstimator;
/**
* A widget that contains arbitrary text, <i>not</i> interpreted as HTML.
@@ -86,10 +85,10 @@
* </p>
*/
@SuppressWarnings("deprecation")
-public class Label extends Widget implements HasDirectionalText, HasWordWrap,
+public class Label extends LabelBase<String> implements HasDirectionalText,
HasDirection, HasClickHandlers, HasDoubleClickHandlers, SourcesClickEvents,
- SourcesMouseEvents, HasAllGestureHandlers, HasAllMouseHandlers, HasAllTouchHandlers,
- HasDirectionEstimator, HasAutoHorizontalAlignment, IsEditor<LeafValueEditor<String>> {
+ SourcesMouseEvents, HasAllGestureHandlers, HasAllMouseHandlers,
+ HasAllTouchHandlers, IsEditor<LeafValueEditor<String>> {
public static final DirectionEstimator DEFAULT_DIRECTION_ESTIMATOR =
DirectionalTextHelper.DEFAULT_DIRECTION_ESTIMATOR;
@@ -117,29 +116,14 @@
return label;
}
- /**
- * The widget's DirectionalTextHelper object.
- */
- final DirectionalTextHelper directionalTextHelper;
-
- /**
- * The widget's auto horizontal alignment policy.
- * @see HasAutoHorizontalAlignment
- */
- private AutoHorizontalAlignmentConstant autoHorizontalAlignment;
-
- /**
- * The widget's horizontal alignment.
- */
- private HorizontalAlignmentConstant horzAlign;
+ private LeafValueEditor<String> editor;
/**
* Creates an empty label.
*/
public Label() {
- setElement(Document.get().createDivElement());
+ super(false);
setStyleName("gwt-Label");
- directionalTextHelper = new DirectionalTextHelper(getElement(), false);
}
/**
@@ -196,12 +180,7 @@
* @param element the element to be used
*/
protected Label(Element element) {
- setElement(element);
- String tagName = element.getTagName();
- boolean isElementInline = tagName.equalsIgnoreCase("span");
- assert isElementInline || tagName.equalsIgnoreCase("div");
- directionalTextHelper = new DirectionalTextHelper(getElement(),
- isElementInline);
+ super(element);
}
public HandlerRegistration addClickHandler(ClickHandler handler) {
@@ -291,14 +270,10 @@
}
public LeafValueEditor<String> asEditor() {
- return HasTextEditor.of(this);
- }
-
- /**
- * {@inheritDoc}
- */
- public AutoHorizontalAlignmentConstant getAutoHorizontalAlignment() {
- return autoHorizontalAlignment;
+ if (editor == null) {
+ editor = HasTextEditor.of(this);
+ }
+ return editor;
}
/**
@@ -310,17 +285,6 @@
return BidiUtils.getDirectionOnElement(getElement());
}
- public DirectionEstimator getDirectionEstimator() {
- return directionalTextHelper.getDirectionEstimator();
- }
-
- /**
- * {@inheritDoc}
- */
- public HorizontalAlignmentConstant getHorizontalAlignment() {
- return horzAlign;
- }
-
public String getText() {
return directionalTextHelper.getTextOrHtml(false);
}
@@ -329,10 +293,6 @@
return directionalTextHelper.getTextDirection();
}
- public boolean getWordWrap() {
- return !getElement().getStyle().getProperty("whiteSpace").equals("nowrap");
- }
-
/**
* @deprecated Use the {@link HandlerRegistration#removeHandler} method on
* the object returned by {@link #addClickHandler} instead
@@ -361,15 +321,6 @@
}
/**
- * {@inheritDoc}
- */
- public void setAutoHorizontalAlignment(AutoHorizontalAlignmentConstant
- autoAlignment) {
- autoHorizontalAlignment = autoAlignment;
- updateHorizontalAlignment();
- }
-
- /**
* Sets the widget element's direction.
* @deprecated Use {@link #setDirectionEstimator} and / or pass explicit
* direction to {@link #setText} instead
@@ -381,44 +332,6 @@
}
/**
- * {@inheritDoc}
- * <p>
- * See note at {@link #setDirectionEstimator(DirectionEstimator)}.
- */
- public void setDirectionEstimator(boolean enabled) {
- directionalTextHelper.setDirectionEstimator(enabled);
- updateHorizontalAlignment();
- }
-
- /**
- * {@inheritDoc}
- * <p>
- * Note: DirectionEstimator should be set before the widget has any content;
- * it's highly recommended to set it using a constructor. Reason: if the
- * widget already has non-empty content, this will update its direction
- * according to the new estimator's result. This may cause flicker, and thus
- * should be avoided.
- */
- public void setDirectionEstimator(DirectionEstimator directionEstimator) {
- directionalTextHelper.setDirectionEstimator(directionEstimator);
- updateHorizontalAlignment();
- }
-
- /**
- * {@inheritDoc}
- *
- * <p> Note: A subsequent call to {@link #setAutoHorizontalAlignment} may
- * override the horizontal alignment set by this method.
- * <p> Note: For {@code null}, the horizontal alignment is cleared, allowing
- * it to be determined by the standard HTML mechanisms such as inheritance and
- * CSS rules.
- * @see #setAutoHorizontalAlignment
- */
- public void setHorizontalAlignment(HorizontalAlignmentConstant align) {
- setAutoHorizontalAlignment(align);
- }
-
- /**
* Sets the label's content to the given text.
* <p>
* Doesn't change the widget's direction or horizontal alignment if {@code
@@ -457,36 +370,4 @@
directionalTextHelper.setTextOrHtml(text, dir, false);
updateHorizontalAlignment();
}
-
- public void setWordWrap(boolean wrap) {
- getElement().getStyle().setProperty("whiteSpace",
- wrap ? "normal" : "nowrap");
- }
-
- /**
- * Sets the horizontal alignment of the widget according to the current
- * AutoHorizontalAlignment setting. Should be invoked whenever the horizontal
- * alignment may be affected, i.e. on every modification of the content or its
- * direction.
- */
- protected void updateHorizontalAlignment() {
- HorizontalAlignmentConstant align;
- if (autoHorizontalAlignment == null) {
- align = null;
- } else if (autoHorizontalAlignment instanceof HorizontalAlignmentConstant) {
- align = (HorizontalAlignmentConstant) autoHorizontalAlignment;
- } else {
- /* autoHorizontalAlignment is a truly automatic policy, i.e. either
- ALIGN_CONTENT_START or ALIGN_CONTENT_END */
- align = autoHorizontalAlignment == ALIGN_CONTENT_START ?
- HorizontalAlignmentConstant.startOf(getTextDirection()) :
- HorizontalAlignmentConstant.endOf(getTextDirection());
- }
-
- if (align != horzAlign) {
- horzAlign = align;
- getElement().getStyle().setProperty("textAlign", horzAlign == null ? ""
- : horzAlign.getTextAlignString());
- }
- }
}
diff --git a/user/src/com/google/gwt/user/client/ui/Label.java.rej b/user/src/com/google/gwt/user/client/ui/Label.java.rej
new file mode 100644
index 0000000..975186f
--- /dev/null
+++ b/user/src/com/google/gwt/user/client/ui/Label.java.rej
@@ -0,0 +1,15 @@
+--- user/src/com/google/gwt/user/client/ui/Label.java (revision 9255)
++++ user/src/com/google/gwt/user/client/ui/Label.java (working copy)
+@@ -69,10 +68,8 @@
+ * </p>
+ */
+ @SuppressWarnings("deprecation")
+-public class Label extends Widget implements HasDirectionalText, HasWordWrap,
+- HasDirection, HasClickHandlers, HasDoubleClickHandlers, SourcesClickEvents,
+- SourcesMouseEvents, HasAllMouseHandlers, HasDirectionEstimator,
+- HasAutoHorizontalAlignment, IsEditor<LeafValueEditor<String>> {
++public class Label extends LabelBase<String> implements HasDirectionalText, HasDirection, HasClickHandlers, HasDoubleClickHandlers, SourcesClickEvents,
++ SourcesMouseEvents, HasAllMouseHandlers, IsEditor<LeafValueEditor<String>> {
+
+ public static final DirectionEstimator DEFAULT_DIRECTION_ESTIMATOR =
+ DirectionalTextHelper.DEFAULT_DIRECTION_ESTIMATOR;
diff --git a/user/src/com/google/gwt/user/client/ui/LabelBase.java b/user/src/com/google/gwt/user/client/ui/LabelBase.java
new file mode 100644
index 0000000..4f15d3f
--- /dev/null
+++ b/user/src/com/google/gwt/user/client/ui/LabelBase.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2010 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.dom.client.Document;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.i18n.shared.DirectionEstimator;
+import com.google.gwt.i18n.shared.HasDirectionEstimator;
+
+/**
+ * Abstract base class for all text display widgets.
+ *
+ * <h3>Use in UiBinder Templates</h3>
+ *
+ * @param <T> the value type
+ */
+public class LabelBase<T> extends Widget implements HasWordWrap,
+ HasDirectionEstimator, HasAutoHorizontalAlignment {
+
+ /**
+ * The widget's DirectionalTextHelper object.
+ */
+ final DirectionalTextHelper directionalTextHelper;
+
+ /**
+ * The widget's auto horizontal alignment policy.
+ *
+ * @see HasAutoHorizontalAlignment
+ */
+ private AutoHorizontalAlignmentConstant autoHorizontalAlignment;
+
+ /**
+ * The widget's horizontal alignment.
+ */
+ private HorizontalAlignmentConstant horzAlign;
+
+ protected LabelBase(boolean inline) {
+ this(inline ? Document.get().createSpanElement()
+ : Document.get().createDivElement(), inline);
+ }
+
+ protected LabelBase(Element element) {
+ this(element, "span".equalsIgnoreCase(element.getTagName()));
+ }
+
+ private LabelBase(Element element, boolean isElementInline) {
+ assert (isElementInline ? "span" : "div").equalsIgnoreCase(element.getTagName());
+ setElement(element);
+ directionalTextHelper = new DirectionalTextHelper(getElement(),
+ isElementInline);
+ }
+
+ public AutoHorizontalAlignmentConstant getAutoHorizontalAlignment() {
+ return autoHorizontalAlignment;
+ }
+
+ public DirectionEstimator getDirectionEstimator() {
+ return directionalTextHelper.getDirectionEstimator();
+ }
+
+ public HorizontalAlignmentConstant getHorizontalAlignment() {
+ return horzAlign;
+ }
+
+ public boolean getWordWrap() {
+ return !getElement().getStyle().getProperty("whiteSpace").equals("nowrap");
+ }
+
+ public void setAutoHorizontalAlignment(
+ AutoHorizontalAlignmentConstant autoAlignment) {
+ autoHorizontalAlignment = autoAlignment;
+ updateHorizontalAlignment();
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * See note at {@link #setDirectionEstimator(DirectionEstimator)}.
+ */
+ public void setDirectionEstimator(boolean enabled) {
+ directionalTextHelper.setDirectionEstimator(enabled);
+ updateHorizontalAlignment();
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Note: DirectionEstimator should be set before the widget has any content;
+ * it's highly recommended to set it using a constructor. Reason: if the
+ * widget already has non-empty content, this will update its direction
+ * according to the new estimator's result. This may cause flicker, and thus
+ * should be avoided.
+ */
+ public void setDirectionEstimator(DirectionEstimator directionEstimator) {
+ directionalTextHelper.setDirectionEstimator(directionEstimator);
+ updateHorizontalAlignment();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>
+ * Note: A subsequent call to {@link #setAutoHorizontalAlignment} may override
+ * the horizontal alignment set by this method.
+ * <p>
+ * Note: For {@code null}, the horizontal alignment is cleared, allowing it to
+ * be determined by the standard HTML mechanisms such as inheritance and CSS
+ * rules.
+ *
+ * @see #setAutoHorizontalAlignment
+ */
+ public void setHorizontalAlignment(HorizontalAlignmentConstant align) {
+ setAutoHorizontalAlignment(align);
+ }
+
+ public void setWordWrap(boolean wrap) {
+ getElement().getStyle().setProperty("whiteSpace",
+ wrap ? "normal" : "nowrap");
+ }
+
+ /**
+ * Sets the horizontal alignment of the widget according to the current
+ * AutoHorizontalAlignment setting. Should be invoked whenever the horizontal
+ * alignment may be affected, i.e. on every modification of the content or its
+ * direction.
+ */
+ protected void updateHorizontalAlignment() {
+ HorizontalAlignmentConstant align;
+ if (autoHorizontalAlignment == null) {
+ align = null;
+ } else if (autoHorizontalAlignment instanceof HorizontalAlignmentConstant) {
+ align = (HorizontalAlignmentConstant) autoHorizontalAlignment;
+ } else {
+ /*
+ * autoHorizontalAlignment is a truly automatic policy, i.e. either
+ * ALIGN_CONTENT_START or ALIGN_CONTENT_END
+ */
+ align = autoHorizontalAlignment == ALIGN_CONTENT_START
+ ? HorizontalAlignmentConstant.startOf(directionalTextHelper.getTextDirection())
+ : HorizontalAlignmentConstant.endOf(directionalTextHelper.getTextDirection());
+ }
+
+ if (align != horzAlign) {
+ horzAlign = align;
+ getElement().getStyle().setProperty("textAlign",
+ horzAlign == null ? "" : horzAlign.getTextAlignString());
+ }
+ }
+}
diff --git a/user/src/com/google/gwt/user/client/ui/NumberLabel.java b/user/src/com/google/gwt/user/client/ui/NumberLabel.java
new file mode 100644
index 0000000..ad398ca
--- /dev/null
+++ b/user/src/com/google/gwt/user/client/ui/NumberLabel.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2010 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.i18n.client.NumberFormat;
+import com.google.gwt.text.client.NumberFormatRenderer;
+
+/**
+ * Extends {@link ValueLabel} for convenience when dealing with numbers and
+ * {@link NumberFormat}, especially in
+ * {@link com.google.gwt.uibinder.client.UiBinder UiBinder} templates. (Note
+ * that this class does not accept renderers. To do so use {@link ValueLabel}
+ * directly.)
+ *
+ * <h3>Use in UiBinder Templates</h3> In
+ * {@link com.google.gwt.uibinder.client.UiBinder UiBinder} templates, the
+ * {@link NumberFormat} can be specified with one of these attributes:
+ * <dl>
+ * <dt>format</dt>
+ * <dd>a reference to a {@link NumberFormat} instance.</dd>
+ * <dt>predefinedFormat</dt>
+ * <dd>a predefined format (see below for the list of acceptable values).</dd>
+ * <dt>customFormat</dt>
+ * <dd>a number format pattern that can be passed to
+ * {@link NumberFormat#getFormat(String)}. See below for a way of specifying a
+ * currency code.</dd>
+ * </dl>
+ * The valid values for the {@code predefinedFormat} attributes are:
+ * <dl>
+ * <dt>DECIMAL</dt>
+ * <dd>the standard decimal format for the current locale, as given by
+ * {@link NumberFormat#getDecimalFormat()}.</dd>
+ * <dt>CURRENCY</dt>
+ * <dd>the standard currency format for the current locale, as given by
+ * {@link NumberFormat#getCurrencyFormat()}. See below for a way of specifying a
+ * currency code.</dd>
+ * <dt>PERCENT</dt>
+ * <dd>the standard percent format for the current locale, as given by
+ * {@link NumberFormat#getPercentFormat()}.</dd>
+ * <dt>SCIENTIFIC</dt>
+ * <dd>the standard scientific format for the current locale, as given by
+ * {@link NumberFormat#getScientificFormat()}.</dd>
+ * </dl>
+ * When using {@code predefinedFormat="CURRENCY"} or a {@code customFormat}, you
+ * can specify a currency code using either of the following attributes:
+ * <dl>
+ * <dt>currencyData</dt>
+ * <dd>a reference to a {@link com.google.gwt.i18n.client.CurrencyData
+ * CurrencyData} instance.</dd>
+ * <dt>currencyCode</dt>
+ * <dd>an ISO4217 currency code.</dd>
+ * </dl>
+ *
+ * @param <T> The exact type of number
+ */
+public class NumberLabel<T extends Number> extends ValueLabel<T> {
+
+ public NumberLabel() {
+ super(new NumberFormatRenderer());
+ }
+
+ public NumberLabel(NumberFormat format) {
+ super(new NumberFormatRenderer(format));
+ }
+}
diff --git a/user/src/com/google/gwt/user/client/ui/SimpleCheckBox.java b/user/src/com/google/gwt/user/client/ui/SimpleCheckBox.java
index 4bc465c..4975554 100644
--- a/user/src/com/google/gwt/user/client/ui/SimpleCheckBox.java
+++ b/user/src/com/google/gwt/user/client/ui/SimpleCheckBox.java
@@ -18,6 +18,10 @@
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.InputElement;
+import com.google.gwt.editor.client.IsEditor;
+import com.google.gwt.editor.client.LeafValueEditor;
+import com.google.gwt.editor.client.adapters.TakesValueEditor;
+import com.google.gwt.user.client.TakesValue;
/**
* A simple checkbox widget, with no label.
@@ -28,7 +32,8 @@
* <li>.gwt-SimpleCheckBox-disabled { Applied when checkbox is disabled }</li>
* </ul>
*/
-public class SimpleCheckBox extends FocusWidget implements HasName {
+public class SimpleCheckBox extends FocusWidget implements HasName,
+ TakesValue<Boolean>, IsEditor<LeafValueEditor<Boolean>> {
/**
* Creates a SimpleCheckBox widget that wraps an existing <input
@@ -53,6 +58,8 @@
return checkBox;
}
+ private LeafValueEditor<Boolean> editor;
+
/**
* Creates a new simple checkbox.
*/
@@ -79,28 +86,66 @@
}
}
+ public LeafValueEditor<Boolean> asEditor() {
+ if (editor == null) {
+ editor = TakesValueEditor.of(this);
+ }
+ return editor;
+ }
+
+ /**
+ * Returns the value property of the input element that backs this widget.
+ * This is the value that will be associated with the check box name and
+ * submitted to the server if a {@link FormPanel} that holds it is submitted
+ * and the box is checked.
+ * <p>
+ * Don't confuse this with {@link #getValue}, which returns true or false if
+ * the widget is checked.
+ */
+ public String getFormValue() {
+ return getInputElement().getValue();
+ }
+
public String getName() {
return getInputElement().getName();
}
/**
* Determines whether this check box is currently checked.
+ * <p>
+ * Note that this <em>does not</em> return the value property of the checkbox
+ * input element wrapped by this widget. For access to that property, see
+ * {@link #getFormValue()}
*
- * @return <code>true</code> if the check box is checked
+ * @return <code>true</code> if the check box is checked, false otherwise.
+ * Will not return null
*/
- public boolean isChecked() {
+ public Boolean getValue() {
String propName = isAttached() ? "checked" : "defaultChecked";
return getInputElement().getPropertyBoolean(propName);
}
/**
+ * Determines whether this check box is currently checked.
+ *
+ * @return <code>true</code> if the check box is checked
+ * @deprecated Use {@link #getValue} instead
+ */
+ @Deprecated
+ public boolean isChecked() {
+ // Funny comparison b/c getValue could in theory return null
+ return getValue() == true;
+ }
+
+ /**
* Checks or unchecks this check box.
*
* @param checked <code>true</code> to check the check box
+ * @deprecated Use {@link #setValue(Boolean)} instead
*/
+ @Deprecated
public void setChecked(boolean checked) {
- getInputElement().setChecked(checked);
- getInputElement().setDefaultChecked(checked);
+ setValue(checked);
}
@Override
@@ -113,18 +158,50 @@
}
}
+ /**
+ * Set the value property on the input element that backs this widget. This is
+ * the value that will be associated with the check box's name and submitted
+ * to the server if a {@link FormPanel} that holds it is submitted and the box
+ * is checked.
+ * <p>
+ * Don't confuse this with {@link #setValue}, which actually checks and
+ * unchecks the box.
+ *
+ * @param value
+ */
+ public void setFormValue(String value) {
+ getInputElement().setAttribute("value", value);
+ }
+
public void setName(String name) {
getInputElement().setName(name);
}
/**
+ * Checks or unchecks the check box.
+ * <p>
+ * Note that this <em>does not</em> set the value property of the checkbox
+ * input element wrapped by this widget. For access to that property, see
+ * {@link #setFormValue(String)}
+ *
+ * @param value true to check, false to uncheck; null value implies false
+ */
+ public void setValue(Boolean value) {
+ if (value == null) {
+ value = Boolean.FALSE;
+ }
+
+ getInputElement().setChecked(value);
+ getInputElement().setDefaultChecked(value);
+ }
+
+ /**
* This method is called when a widget is detached from the browser's
- * document. Overridden because of IE bug that throws away checked state and
- * in order to clear the event listener off of the <code>inputElem</code>.
+ * document. Overridden because of IE bug that throws away checked state.
*/
@Override
protected void onUnload() {
- setChecked(isChecked());
+ setValue(getValue());
}
private InputElement getInputElement() {
diff --git a/user/src/com/google/gwt/user/client/ui/SuggestBox.java b/user/src/com/google/gwt/user/client/ui/SuggestBox.java
index 26c63d7..a95bb5a 100644
--- a/user/src/com/google/gwt/user/client/ui/SuggestBox.java
+++ b/user/src/com/google/gwt/user/client/ui/SuggestBox.java
@@ -674,6 +674,7 @@
private boolean selectsFirstItem = true;
private SuggestOracle oracle;
private String currentText;
+ private LeafValueEditor<String> editor;
private final SuggestionDisplay display;
private final TextBoxBase box;
private final Callback callback = new Callback() {
@@ -831,7 +832,10 @@
* Returns a {@link TakesValueEditor} backed by the DateBox.
*/
public LeafValueEditor<String> asEditor() {
- return TakesValueEditor.of(this);
+ if (editor == null) {
+ editor = TakesValueEditor.of(this);
+ }
+ return editor;
}
/**
diff --git a/user/src/com/google/gwt/user/client/ui/ToggleButton.java b/user/src/com/google/gwt/user/client/ui/ToggleButton.java
index 3ce977b..b337f3f 100644
--- a/user/src/com/google/gwt/user/client/ui/ToggleButton.java
+++ b/user/src/com/google/gwt/user/client/ui/ToggleButton.java
@@ -16,6 +16,9 @@
package com.google.gwt.user.client.ui;
+import com.google.gwt.editor.client.IsEditor;
+import com.google.gwt.editor.client.LeafValueEditor;
+import com.google.gwt.editor.client.adapters.TakesValueEditor;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
@@ -40,9 +43,11 @@
* <h3>Example</h3> {@example com.google.gwt.examples.ToggleButtonExample}
* </p>
*/
-public class ToggleButton extends CustomButton implements HasValue<Boolean> {
+public class ToggleButton extends CustomButton implements HasValue<Boolean>, IsEditor<LeafValueEditor<Boolean>> {
private static String STYLENAME_DEFAULT = "gwt-ToggleButton";
+ private LeafValueEditor<Boolean> editor;
+
{
setStyleName(STYLENAME_DEFAULT);
}
@@ -182,6 +187,13 @@
return addHandler(handler, ValueChangeEvent.getType());
}
+ public LeafValueEditor<Boolean> asEditor() {
+ if (editor == null) {
+ editor = TakesValueEditor.of(this);
+ }
+ return editor;
+ }
+
/**
* Determines whether this button is currently down.
*
diff --git a/user/src/com/google/gwt/user/client/ui/ValueBoxBase.java b/user/src/com/google/gwt/user/client/ui/ValueBoxBase.java
index d24f2a3..05d416e 100644
--- a/user/src/com/google/gwt/user/client/ui/ValueBoxBase.java
+++ b/user/src/com/google/gwt/user/client/ui/ValueBoxBase.java
@@ -45,7 +45,6 @@
*
* @param <T> the value type
*/
-@SuppressWarnings("deprecation")
public class ValueBoxBase<T> extends FocusWidget implements
HasChangeHandlers, HasName, HasDirectionEstimator,
HasValue<T>, AutoDirectionHandler.Target, IsEditor<ValueBoxEditor<T>> {
@@ -83,6 +82,7 @@
private final Parser<T> parser;
private final Renderer<T> renderer;
+ private ValueBoxEditor<T> editor;
private Event currentEvent;
private boolean valueChangeHandlerInitialized;
@@ -125,7 +125,10 @@
* Editor framework.
*/
public ValueBoxEditor<T> asEditor() {
- return ValueBoxEditor.of(this);
+ if (editor == null) {
+ editor = ValueBoxEditor.of(this);
+ }
+ return editor;
}
/**
diff --git a/user/src/com/google/gwt/user/client/ui/ValueLabel.java b/user/src/com/google/gwt/user/client/ui/ValueLabel.java
new file mode 100644
index 0000000..92e29db
--- /dev/null
+++ b/user/src/com/google/gwt/user/client/ui/ValueLabel.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2010 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.dom.client.Document;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.editor.client.IsEditor;
+import com.google.gwt.editor.client.LeafValueEditor;
+import com.google.gwt.editor.client.adapters.TakesValueEditor;
+import com.google.gwt.text.shared.Parser;
+import com.google.gwt.text.shared.Renderer;
+import com.google.gwt.uibinder.client.UiConstructor;
+import com.google.gwt.user.client.TakesValue;
+
+import java.text.ParseException;
+
+/**
+ * A label displaying its value through a renderer.
+ *
+ * @param <T> the value type.
+ */
+public class ValueLabel<T> extends LabelBase<T> implements TakesValue<T>,
+ IsEditor<LeafValueEditor<T>> {
+
+ /**
+ * Creates a ValueLabel widget that wraps an existing <span> element.
+ * <p>
+ * The ValueLabel's value will be <code>null</code>, whether the element being
+ * wrapped has content or not. Use {@link #wrap(Element, Renderer, Parser)} to
+ * parse the initial element's content to initialize the ValueLabel's value.
+ * <p>
+ * This element must already be attached to the document. If the element is
+ * removed from the document, you must call
+ * {@link RootPanel#detachNow(Widget)}.
+ *
+ * @param element the element to be wrapped
+ * @param renderer the renderer used to render values into the element
+ */
+ public static <T> ValueLabel<T> wrap(Element element,
+ Renderer<? super T> renderer) {
+ // Assert that the element is attached.
+ assert Document.get().getBody().isOrHasChild(element);
+
+ ValueLabel<T> label = new ValueLabel<T>(element, renderer);
+
+ // Mark it attached and remember it for cleanup.
+ label.onAttach();
+ RootPanel.detachOnWindowClose(label);
+
+ return label;
+ }
+
+ /**
+ * Creates a ValueLabel widget that wraps an existing <span> element.
+ * <p>
+ * The ValueLabel's value will be initialized with the element's content,
+ * passed through the <code>parser</code>.
+ * <p>
+ * This element must already be attached to the document. If the element is
+ * removed from the document, you must call
+ * {@link RootPanel#detachNow(Widget)}.
+ *
+ * @param element the element to be wrapped
+ * @param renderer the renderer used to render values into the element
+ * @param parser the parser used to initialize the ValueLabel's value from the
+ * element's content
+ */
+ public static <T> ValueLabel<T> wrap(Element element,
+ Renderer<? super T> renderer, Parser<? extends T> parser)
+ throws ParseException {
+ ValueLabel<T> label = wrap(element, renderer);
+
+ label.setValue(parser.parse(element.getInnerText()));
+
+ // Mark it attached and remember it for cleanup.
+ label.onAttach();
+ RootPanel.detachOnWindowClose(label);
+
+ return label;
+ }
+
+ private final Renderer<? super T> renderer;
+ private T value;
+ private LeafValueEditor<T> editor;
+
+ /**
+ * Creates an empty value label.
+ *
+ * @param inline
+ * @param renderer
+ */
+ @UiConstructor
+ public ValueLabel(Renderer<? super T> renderer) {
+ super(true);
+ this.renderer = renderer;
+ }
+
+ /**
+ * This constructor may be used by subclasses to explicitly use an existing
+ * element. This element must be either a <span> or a <div>
+ * element.
+ *
+ * @param element the element to be used
+ */
+ protected ValueLabel(Element element, Renderer<? super T> renderer) {
+ super(element);
+ this.renderer = renderer;
+ }
+
+ public LeafValueEditor<T> asEditor() {
+ if (editor == null) {
+ editor = TakesValueEditor.of(this);
+ }
+ return editor;
+ }
+
+ public T getValue() {
+ return value;
+ }
+
+ public void setValue(T value) {
+ this.value = value;
+ directionalTextHelper.setTextOrHtml(renderer.render(value), false);
+ updateHorizontalAlignment();
+ }
+}
\ No newline at end of file
diff --git a/user/src/com/google/gwt/user/client/ui/ValueListBox.java b/user/src/com/google/gwt/user/client/ui/ValueListBox.java
index 24b8b93..4fffa9a 100644
--- a/user/src/com/google/gwt/user/client/ui/ValueListBox.java
+++ b/user/src/com/google/gwt/user/client/ui/ValueListBox.java
@@ -49,6 +49,7 @@
private final Renderer<T> renderer;
private final ProvidesKey<T> keyProvider;
+ private TakesValueEditor<T> editor;
private T value;
public ValueListBox(Renderer<T> renderer) {
@@ -81,7 +82,10 @@
* Returns a {@link TakesValueEditor} backed by the ValueListBox.
*/
public TakesValueEditor<T> asEditor() {
- return TakesValueEditor.of(this);
+ if (editor == null) {
+ editor = TakesValueEditor.of(this);
+ }
+ return editor;
}
public T getValue() {
diff --git a/user/src/com/google/gwt/user/client/ui/ValuePicker.java b/user/src/com/google/gwt/user/client/ui/ValuePicker.java
index 8003cec..7ec9259 100644
--- a/user/src/com/google/gwt/user/client/ui/ValuePicker.java
+++ b/user/src/com/google/gwt/user/client/ui/ValuePicker.java
@@ -56,6 +56,7 @@
private final CellList<T> cellList;
private SingleSelectionModel<T> smodel = new SingleSelectionModel<T>();
+ private LeafValueEditor<T> editor;
public ValuePicker(CellList<T> cellList) {
this.cellList = cellList;
@@ -80,7 +81,10 @@
* Returns a {@link TakesValueEditor} backed by the ValuePicker.
*/
public LeafValueEditor<T> asEditor() {
- return TakesValueEditor.of(this);
+ if (editor == null) {
+ editor = TakesValueEditor.of(this);
+ }
+ return editor;
}
/**
diff --git a/user/src/com/google/gwt/user/datepicker/client/DateBox.java b/user/src/com/google/gwt/user/datepicker/client/DateBox.java
index c9ebf25..3d6b25b 100644
--- a/user/src/com/google/gwt/user/datepicker/client/DateBox.java
+++ b/user/src/com/google/gwt/user/datepicker/client/DateBox.java
@@ -249,6 +249,7 @@
private final PopupPanel popup;
private final TextBox box = new TextBox();
private final DatePicker picker;
+ private LeafValueEditor<Date> editor;
private Format format;
private boolean allowDPShow = true;
@@ -298,7 +299,10 @@
* Returns a {@link TakesValueEditor} backed by the DateBox.
*/
public LeafValueEditor<Date> asEditor() {
- return TakesValueEditor.of(this);
+ if (editor == null) {
+ editor = TakesValueEditor.of(this);
+ }
+ return editor;
}
/**
diff --git a/user/src/com/google/gwt/user/datepicker/client/DatePicker.java b/user/src/com/google/gwt/user/datepicker/client/DatePicker.java
index ddb55a4..439875a 100644
--- a/user/src/com/google/gwt/user/datepicker/client/DatePicker.java
+++ b/user/src/com/google/gwt/user/datepicker/client/DatePicker.java
@@ -253,6 +253,7 @@
private Date value;
private Date highlighted;
private StandardCss css = StandardCss.DEFAULT;
+ private LeafValueEditor<Date> editor;
/**
* Create a new date picker.
@@ -381,7 +382,10 @@
* Returns a {@link TakesValueEditor} backed by the DatePicker.
*/
public LeafValueEditor<Date> asEditor() {
- return TakesValueEditor.of(this);
+ if (editor == null) {
+ editor = TakesValueEditor.of(this);
+ }
+ return editor;
}
/**
diff --git a/user/test/com/google/gwt/text/TextSuite.java b/user/test/com/google/gwt/text/TextSuite.java
index cfe30d3..d14d55f 100644
--- a/user/test/com/google/gwt/text/TextSuite.java
+++ b/user/test/com/google/gwt/text/TextSuite.java
@@ -20,6 +20,7 @@
import com.google.gwt.text.client.DoubleParserTest;
import com.google.gwt.text.client.IntegerParserTest;
import com.google.gwt.text.client.LongParserTest;
+import com.google.gwt.text.client.NumberFormatRendererTest;
import junit.framework.Test;
@@ -34,6 +35,7 @@
suite.addTestSuite(DoubleParserTest.class);
suite.addTestSuite(IntegerParserTest.class);
suite.addTestSuite(LongParserTest.class);
+ suite.addTestSuite(NumberFormatRendererTest.class);
return suite;
}
}
diff --git a/user/test/com/google/gwt/text/client/NumberFormatRendererTest.java b/user/test/com/google/gwt/text/client/NumberFormatRendererTest.java
new file mode 100644
index 0000000..f57c016
--- /dev/null
+++ b/user/test/com/google/gwt/text/client/NumberFormatRendererTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2010 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.text.client;
+
+import com.google.gwt.i18n.client.NumberFormat;
+import com.google.gwt.junit.client.GWTTestCase;
+
+/**
+ * Eponymous unit test.
+ */
+public class NumberFormatRendererTest extends GWTTestCase {
+
+ @Override
+ public String getModuleName() {
+ return "com.google.gwt.text.TextSuite";
+ }
+
+ public void testDefault() {
+ assertEquals(NumberFormat.getDecimalFormat().format(Math.PI),
+ new NumberFormatRenderer().render(Math.PI));
+ }
+
+ public void testScientific() {
+ assertEquals(
+ NumberFormat.getScientificFormat().format(Math.PI),
+ new NumberFormatRenderer(NumberFormat.getScientificFormat()).render(Math.PI));
+ }
+
+ public void testNull() {
+ assertEquals("", new NumberFormatRenderer().render(null));
+ }
+}
diff --git a/user/test/com/google/gwt/uibinder/UiBinderJreSuite.java b/user/test/com/google/gwt/uibinder/UiBinderJreSuite.java
index bdceca6..5436f36 100644
--- a/user/test/com/google/gwt/uibinder/UiBinderJreSuite.java
+++ b/user/test/com/google/gwt/uibinder/UiBinderJreSuite.java
@@ -26,6 +26,7 @@
import com.google.gwt.uibinder.attributeparsers.TextAlignConstantParserTest;
import com.google.gwt.uibinder.attributeparsers.VerticalAlignmentConstantParserTest;
import com.google.gwt.uibinder.elementparsers.AbsolutePanelParserTest;
+import com.google.gwt.uibinder.elementparsers.DateLabelParserTest;
import com.google.gwt.uibinder.elementparsers.DialogBoxParserTest;
import com.google.gwt.uibinder.elementparsers.DisclosurePanelParserTest;
import com.google.gwt.uibinder.elementparsers.DockLayoutPanelParserTest;
@@ -36,6 +37,7 @@
import com.google.gwt.uibinder.elementparsers.ListBoxParserTest;
import com.google.gwt.uibinder.elementparsers.MenuBarParserTest;
import com.google.gwt.uibinder.elementparsers.MenuItemParserTest;
+import com.google.gwt.uibinder.elementparsers.NumberLabelParserTest;
import com.google.gwt.uibinder.elementparsers.StackLayoutPanelParserTest;
import com.google.gwt.uibinder.elementparsers.StackPanelParserTest;
import com.google.gwt.uibinder.elementparsers.TabLayoutPanelParserTest;
@@ -88,6 +90,7 @@
// elementparsers
suite.addTestSuite(AbsolutePanelParserTest.class);
+ suite.addTestSuite(DateLabelParserTest.class);
suite.addTestSuite(DialogBoxParserTest.class);
suite.addTestSuite(DisclosurePanelParserTest.class);
suite.addTestSuite(DockLayoutPanelParserTest.class);
@@ -98,6 +101,7 @@
suite.addTestSuite(ListBoxParserTest.class);
suite.addTestSuite(MenuBarParserTest.class);
suite.addTestSuite(MenuItemParserTest.class);
+ suite.addTestSuite(NumberLabelParserTest.class);
suite.addTestSuite(StackLayoutPanelParserTest.class);
suite.addTestSuite(StackPanelParserTest.class);
suite.addTestSuite(TabLayoutPanelParserTest.class);
diff --git a/user/test/com/google/gwt/uibinder/elementparsers/DateLabelParserTest.java b/user/test/com/google/gwt/uibinder/elementparsers/DateLabelParserTest.java
new file mode 100644
index 0000000..131f614
--- /dev/null
+++ b/user/test/com/google/gwt/uibinder/elementparsers/DateLabelParserTest.java
@@ -0,0 +1,324 @@
+/*
+ * Copyright 2010 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.uibinder.elementparsers;
+
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.dev.javac.impl.MockJavaResource;
+import com.google.gwt.i18n.client.DateTimeFormat;
+import com.google.gwt.i18n.client.TimeZone;
+import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat;
+import com.google.gwt.uibinder.rebind.FieldWriter;
+import com.google.gwt.user.client.ui.DateLabel;
+
+import junit.framework.TestCase;
+
+import org.xml.sax.SAXException;
+
+/**
+ * Eponymous unit test.
+ */
+public class DateLabelParserTest extends TestCase {
+ private static final String PARSED_TYPE = "com.google.gwt.user.client.ui.DateLabel";
+
+ private static final MockJavaResource DATELABEL_SUBCLASS_NO_CONSTRUCTOR = new MockJavaResource(
+ "my.MyDateLabel") {
+ @Override
+ protected CharSequence getContent() {
+ StringBuffer code = new StringBuffer();
+ code.append("package my;\n");
+ code.append("import com.google.gwt.user.client.ui.DateLabel;\n");
+ code.append("public class MyDateLabel extends DateLabel {\n");
+ code.append("}\n");
+ return code;
+ }
+ };
+ private static final MockJavaResource DATELABEL_SUBCLASS_FORMAT_CONSTRUCTOR = new MockJavaResource(
+ "my.MyConstructedDateLabel") {
+ @Override
+ protected CharSequence getContent() {
+ StringBuffer code = new StringBuffer();
+ code.append("package my;\n");
+ code.append("import com.google.gwt.user.client.ui.DateLabel;\n");
+ code.append("import com.google.gwt.i18n.client.DateTimeFormat;\n");
+ code.append("public class MyConstructedDateLabel extends DateLabel {\n");
+ code.append(" public MyConstructedDateLabel(DateTimeFormat f) { super(f); }");
+ code.append("}\n");
+ return code;
+ }
+ };
+ private static final MockJavaResource DATELABEL_SUBCLASS_FORMAT_AND_TZ_CONSTRUCTOR = new MockJavaResource(
+ "my.MyConstructedDateLabel2") {
+ @Override
+ protected CharSequence getContent() {
+ StringBuffer code = new StringBuffer();
+ code.append("package my;\n");
+ code.append("import com.google.gwt.user.client.ui.DateLabel;\n");
+ code.append("import com.google.gwt.i18n.client.DateTimeFormat;\n");
+ code.append("import com.google.gwt.i18n.client.TimeZone;\n");
+ code.append("public class MyConstructedDateLabel2 extends DateLabel {\n");
+ code.append(" public MyConstructedDateLabel2(DateTimeFormat f, TimeZone tz) { super(f, tz); }");
+ code.append("}\n");
+ return code;
+ }
+ };
+ private static final MockJavaResource DATELABEL_SUBCLASS_TZ_CONSTRUCTOR = new MockJavaResource(
+ "my.MyConstructedDateLabel3") {
+ @Override
+ protected CharSequence getContent() {
+ StringBuffer code = new StringBuffer();
+ code.append("package my;\n");
+ code.append("import com.google.gwt.user.client.ui.DateLabel;\n");
+ code.append("import com.google.gwt.i18n.client.TimeZone;\n");
+ code.append("public class MyConstructedDateLabel3 extends DateLabel {\n");
+ code.append(" public MyConstructedDateLabel3(TimeZone tz) { super(); }");
+ code.append("}\n");
+ return code;
+ }
+ };
+ private ElementParserTester tester;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ tester = new ElementParserTester(PARSED_TYPE, new DateLabelParser());
+ }
+
+ public void testHappyWithDefaultInstantiableSubclass()
+ throws UnableToCompleteException, SAXException {
+ tester = new ElementParserTester("my.MyDateLabel", new DateLabelParser(),
+ DATELABEL_SUBCLASS_NO_CONSTRUCTOR);
+ DateLabelParser parser = new DateLabelParser();
+ StringBuffer b = new StringBuffer();
+
+ b.append("<ui:UiBinder xmlns:ui='" + ElementParserTester.BINDER_URI + "'");
+ b.append(" xmlns:my='urn:import:my'");
+ b.append(" xmlns:g='urn:import:com.google.gwt.user.client.ui'>");
+ b.append(" <my:MyDateLabel format='{someDateTimeFormat}' timezone='{someTimeZone}' /> ");
+ b.append("</ui:UiBinder>");
+
+ parser.parse(tester.getElem(b.toString(), "my:MyDateLabel"), "fieldName",
+ tester.parsedType, tester.writer);
+ FieldWriter w = tester.fieldManager.lookup("fieldName");
+ assertNull(w.getInitializer());
+
+ assertTrue(tester.writer.statements.isEmpty());
+ assertNull(tester.logger.died);
+ }
+
+ public void testHappyWithSubclassWithDateTimeFormatConstructor()
+ throws UnableToCompleteException, SAXException {
+ DateLabelParser parser = new DateLabelParser();
+ tester = new ElementParserTester("my.MyConstructedDateLabel",
+ new DateLabelParser(), DATELABEL_SUBCLASS_FORMAT_CONSTRUCTOR);
+
+ StringBuffer b = new StringBuffer();
+
+ b.append("<ui:UiBinder xmlns:ui='" + ElementParserTester.BINDER_URI + "'");
+ b.append(" xmlns:my='urn:import:my'");
+ b.append(" xmlns:g='urn:import:com.google.gwt.user.client.ui'>");
+ b.append(" <my:MyConstructedDateLabel format='{someDateTimeFormat}' timezone='{someTimeZone}' /> ");
+ b.append("</ui:UiBinder>");
+
+ parser.parse(tester.getElem(b.toString(), "my:MyConstructedDateLabel"),
+ "fieldName", tester.parsedType, tester.writer);
+ FieldWriter w = tester.fieldManager.lookup("fieldName");
+ assertEquals("new my.MyConstructedDateLabel(someDateTimeFormat)",
+ w.getInitializer());
+
+ assertTrue(tester.writer.statements.isEmpty());
+ assertNull(tester.logger.died);
+ }
+
+ public void testHappyWithSubclassWithDateTimeFormatAndTimeZoneConstructor()
+ throws UnableToCompleteException, SAXException {
+ DateLabelParser parser = new DateLabelParser();
+ tester = new ElementParserTester("my.MyConstructedDateLabel2",
+ new DateLabelParser(), DATELABEL_SUBCLASS_FORMAT_AND_TZ_CONSTRUCTOR);
+
+ StringBuffer b = new StringBuffer();
+
+ b.append("<ui:UiBinder xmlns:ui='" + ElementParserTester.BINDER_URI + "'");
+ b.append(" xmlns:my='urn:import:my'");
+ b.append(" xmlns:g='urn:import:com.google.gwt.user.client.ui'>");
+ b.append(" <my:MyConstructedDateLabel2 format='{someDateTimeFormat}' timezone='{someTimeZone}' /> ");
+ b.append("</ui:UiBinder>");
+
+ parser.parse(tester.getElem(b.toString(), "my:MyConstructedDateLabel2"),
+ "fieldName", tester.parsedType, tester.writer);
+ FieldWriter w = tester.fieldManager.lookup("fieldName");
+ assertEquals(
+ "new my.MyConstructedDateLabel2(someDateTimeFormat, someTimeZone)",
+ w.getInitializer());
+
+ assertTrue(tester.writer.statements.isEmpty());
+ assertNull(tester.logger.died);
+ }
+
+ public void testHappyWithSubclassWithTimeZoneFormatConstructor()
+ throws UnableToCompleteException, SAXException {
+ DateLabelParser parser = new DateLabelParser();
+ tester = new ElementParserTester("my.MyConstructedDateLabel3",
+ new DateLabelParser(), DATELABEL_SUBCLASS_TZ_CONSTRUCTOR);
+
+ StringBuffer b = new StringBuffer();
+
+ b.append("<ui:UiBinder xmlns:ui='" + ElementParserTester.BINDER_URI + "'");
+ b.append(" xmlns:my='urn:import:my'");
+ b.append(" xmlns:g='urn:import:com.google.gwt.user.client.ui'>");
+ b.append(" <my:MyConstructedDateLabel3 format='{someDateTimeFormat}' timezone='{someTimeZone}' /> ");
+ b.append("</ui:UiBinder>");
+
+ parser.parse(tester.getElem(b.toString(), "my:MyConstructedDateLabel3"),
+ "fieldName", tester.parsedType, tester.writer);
+ FieldWriter w = tester.fieldManager.lookup("fieldName");
+ assertNull(w.getInitializer());
+
+ assertTrue(tester.writer.statements.isEmpty());
+ assertNull(tester.logger.died);
+ }
+
+ public void testHappyWithNoFormat() throws UnableToCompleteException,
+ SAXException {
+ StringBuffer b = new StringBuffer();
+ b.append("<g:DateLabel>");
+ b.append("</g:DateLabel>");
+
+ FieldWriter w = tester.parse(b.toString());
+ assertNull(w.getInitializer());
+
+ assertTrue(tester.writer.statements.isEmpty());
+ assertNull(tester.logger.died);
+ }
+
+ public void testHappyWithPredefinedFormat() throws UnableToCompleteException,
+ SAXException {
+ StringBuffer b = new StringBuffer();
+ b.append("<g:DateLabel predefinedFormat='DATE_MEDIUM'>");
+ b.append("</g:DateLabel>");
+
+ FieldWriter w = tester.parse(b.toString());
+ assertEquals("new " + DateLabel.class.getCanonicalName() + "("
+ + DateTimeFormat.class.getCanonicalName() + ".getFormat("
+ + PredefinedFormat.class.getCanonicalName() + ".DATE_MEDIUM))",
+ w.getInitializer());
+
+ assertTrue(tester.writer.statements.isEmpty());
+ assertNull(tester.logger.died);
+ }
+
+ public void testHappyWithTimezoneOffset() throws UnableToCompleteException,
+ SAXException {
+ StringBuffer b = new StringBuffer();
+ b.append("<g:DateLabel customFormat='zzzz' timezoneOffset='-7200'>");
+ b.append("</g:DateLabel>");
+
+ FieldWriter w = tester.parse(b.toString());
+ assertEquals("new " + DateLabel.class.getCanonicalName() + "("
+ + DateTimeFormat.class.getCanonicalName() + ".getFormat(\"zzzz\"), "
+ + TimeZone.class.getCanonicalName() + ".createTimeZone(-7200))",
+ w.getInitializer());
+
+ assertTrue(tester.writer.statements.isEmpty());
+ assertNull(tester.logger.died);
+ }
+
+ public void testChokeOnNonDateTimeFormat() throws SAXException {
+ StringBuffer b = new StringBuffer();
+ b.append("<g:DateLabel format='someString' >");
+ b.append("</g:DateLabel>");
+
+ try {
+ tester.parse(b.toString());
+ fail();
+ } catch (UnableToCompleteException e) {
+ assertTrue("Expect to hear about DateTimeFormat",
+ tester.logger.died.contains("DateTimeFormat"));
+ }
+ }
+
+ public void testChokeOnNonTimeZone() throws SAXException {
+ StringBuffer b = new StringBuffer();
+ b.append("<g:DateLabel format='{someDateTimeFormat}' timezone='someString' >");
+ b.append("</g:DateLabel>");
+
+ try {
+ tester.parse(b.toString());
+ fail();
+ } catch (UnableToCompleteException e) {
+ assertTrue("Expect to hear about TimeZone",
+ tester.logger.died.contains("TimeZone"));
+ }
+ }
+
+ public void testChokeOnUnknownPredefinedFormat() throws SAXException {
+ StringBuffer b = new StringBuffer();
+ b.append("<g:DateLabel predefinedFormat='someString' >");
+ b.append("</g:DateLabel>");
+
+ try {
+ tester.parse(b.toString());
+ fail();
+ } catch (UnableToCompleteException e) {
+ assertTrue("Expect to hear about PredefinedFormat",
+ tester.logger.died.contains("PredefinedFormat"));
+ }
+ }
+
+ public void testChokeOnMultipleFormats() throws SAXException {
+ StringBuffer b = new StringBuffer();
+ b.append("<g:DateLabel predefinedFormat='DATE_FULL' customFormat='MM/dd'>");
+ b.append("</g:DateLabel>");
+
+ try {
+ tester.parse(b.toString());
+ fail();
+ } catch (UnableToCompleteException e) {
+ assertTrue(
+ tester.logger.died,
+ tester.logger.died.contains(DateLabelParser.AT_MOST_ONE_SPECIFIED_FORMAT));
+ }
+ }
+
+ public void testChokeOnMultipleTimeZones() throws SAXException {
+ StringBuffer b = new StringBuffer();
+ b.append("<g:DateLabel format='{someDateTimeFormat}' timezone='{someTimeZone}' timezoneOffset='-7200'>");
+ b.append("</g:DateLabel>");
+
+ try {
+ tester.parse(b.toString());
+ fail();
+ } catch (UnableToCompleteException e) {
+ assertTrue(
+ tester.logger.died,
+ tester.logger.died.contains(DateLabelParser.AT_MOST_ONE_SPECIFIED_TIME_ZONE));
+ }
+ }
+
+ public void testChokeOnTimeZoneWithoutSpecifiedFormat() throws SAXException {
+ StringBuffer b = new StringBuffer();
+ b.append("<g:DateLabel timezoneOffset='-7200'>");
+ b.append("</g:DateLabel>");
+
+ try {
+ tester.parse(b.toString());
+ fail();
+ } catch (UnableToCompleteException e) {
+ assertTrue(
+ tester.logger.died,
+ tester.logger.died.contains(DateLabelParser.NO_TIMEZONE_WITHOUT_SPECIFIED_FORMAT));
+ }
+ }
+}
diff --git a/user/test/com/google/gwt/uibinder/elementparsers/NumberLabelParserTest.java b/user/test/com/google/gwt/uibinder/elementparsers/NumberLabelParserTest.java
new file mode 100644
index 0000000..41fff15
--- /dev/null
+++ b/user/test/com/google/gwt/uibinder/elementparsers/NumberLabelParserTest.java
@@ -0,0 +1,273 @@
+/*
+ * Copyright 2010 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.uibinder.elementparsers;
+
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.dev.javac.impl.MockJavaResource;
+import com.google.gwt.i18n.client.NumberFormat;
+import com.google.gwt.uibinder.rebind.FieldWriter;
+import com.google.gwt.user.client.ui.NumberLabel;
+
+import junit.framework.TestCase;
+
+import org.xml.sax.SAXException;
+
+/**
+ * Eponymous unit test.
+ */
+public class NumberLabelParserTest extends TestCase {
+ private static final String PARSED_TYPE = "com.google.gwt.user.client.ui.NumberLabel";
+
+ private static final MockJavaResource NUMBERLABEL_SUBCLASS_NO_CONSTRUCTOR = new MockJavaResource(
+ "my.MyNumberLabel") {
+ @Override
+ protected CharSequence getContent() {
+ StringBuffer code = new StringBuffer();
+ code.append("package my;\n");
+ code.append("import com.google.gwt.user.client.ui.NumberLabel;\n");
+ code.append("public class MyNumberLabel extends NumberLabel {\n");
+ code.append("}\n");
+ return code;
+ }
+ };
+ private static final MockJavaResource NUMBERLABEL_SUBCLASS_FORMAT_CONSTRUCTOR = new MockJavaResource(
+ "my.MyConstructedNumberLabel") {
+ @Override
+ protected CharSequence getContent() {
+ StringBuffer code = new StringBuffer();
+ code.append("package my;\n");
+ code.append("import com.google.gwt.user.client.ui.NumberLabel;\n");
+ code.append("import com.google.gwt.i18n.client.NumberFormat;\n");
+ code.append("public class MyConstructedNumberLabel extends NumberLabel {\n");
+ code.append(" public MyConstructedNumberLabel(NumberFormat f) { super(f); }");
+ code.append("}\n");
+ return code;
+ }
+ };
+ private ElementParserTester tester;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ tester = new ElementParserTester(PARSED_TYPE, new NumberLabelParser());
+ }
+
+ public void testHappyWithDefaultInstantiableSubclass()
+ throws UnableToCompleteException, SAXException {
+ tester = new ElementParserTester("my.MyNumberLabel",
+ new NumberLabelParser(), NUMBERLABEL_SUBCLASS_NO_CONSTRUCTOR);
+ NumberLabelParser parser = new NumberLabelParser();
+ StringBuffer b = new StringBuffer();
+
+ b.append("<ui:UiBinder xmlns:ui='" + ElementParserTester.BINDER_URI + "'");
+ b.append(" xmlns:my='urn:import:my'");
+ b.append(" xmlns:g='urn:import:com.google.gwt.user.client.ui'>");
+ b.append(" <my:MyNumberLabel format='{someDateTimeFormat}' currencyData='{someCurrencyData}' /> ");
+ b.append("</ui:UiBinder>");
+
+ parser.parse(tester.getElem(b.toString(), "my:MyNumberLabel"), "fieldName",
+ tester.parsedType, tester.writer);
+ FieldWriter w = tester.fieldManager.lookup("fieldName");
+ assertNull(w.getInitializer());
+
+ assertTrue(tester.writer.statements.isEmpty());
+ assertNull(tester.logger.died);
+ }
+
+ public void testHappyWithSubclassWithNumberFormatConstructor()
+ throws UnableToCompleteException, SAXException {
+ NumberLabelParser parser = new NumberLabelParser();
+ tester = new ElementParserTester("my.MyConstructedNumberLabel",
+ new NumberLabelParser(), NUMBERLABEL_SUBCLASS_FORMAT_CONSTRUCTOR);
+
+ StringBuffer b = new StringBuffer();
+
+ b.append("<ui:UiBinder xmlns:ui='" + ElementParserTester.BINDER_URI + "'");
+ b.append(" xmlns:my='urn:import:my'");
+ b.append(" xmlns:g='urn:import:com.google.gwt.user.client.ui'>");
+ b.append(" <my:MyConstructedNumberLabel format='{someDateTimeFormat}' /> ");
+ b.append("</ui:UiBinder>");
+
+ parser.parse(tester.getElem(b.toString(), "my:MyConstructedNumberLabel"),
+ "fieldName", tester.parsedType, tester.writer);
+ FieldWriter w = tester.fieldManager.lookup("fieldName");
+ assertEquals("new my.MyConstructedNumberLabel(someDateTimeFormat)",
+ w.getInitializer());
+
+ assertTrue(tester.writer.statements.isEmpty());
+ assertNull(tester.logger.died);
+ }
+
+ public void testHappyWithNoFormat() throws UnableToCompleteException,
+ SAXException {
+ StringBuffer b = new StringBuffer();
+ b.append("<g:NumberLabel>");
+ b.append("</g:NumberLabel>");
+
+ FieldWriter w = tester.parse(b.toString());
+ assertNull(w.getInitializer());
+
+ assertTrue(tester.writer.statements.isEmpty());
+ assertNull(tester.logger.died);
+ }
+
+ public void testHappyWithCustomFormatAndCurrency()
+ throws UnableToCompleteException, SAXException {
+ StringBuffer b = new StringBuffer();
+ b.append("<g:NumberLabel customFormat='#\u00A0\u00A4' currencyCode='EUR'>");
+ b.append("</g:NumberLabel>");
+
+ FieldWriter w = tester.parse(b.toString());
+ assertEquals("new " + NumberLabel.class.getCanonicalName() + "("
+ + NumberFormat.class.getCanonicalName() + ".getFormat(\"#\u00A0\u00A4\", \"EUR\"))",
+ w.getInitializer());
+
+ assertTrue(tester.writer.statements.isEmpty());
+ assertNull(tester.logger.died);
+ }
+
+ public void testHappyWithCurrencyPredefinedFormat()
+ throws UnableToCompleteException, SAXException {
+ StringBuffer b = new StringBuffer();
+ b.append("<g:NumberLabel predefinedFormat='CURRENCY'>");
+ b.append("</g:NumberLabel>");
+
+ FieldWriter w = tester.parse(b.toString());
+ assertEquals("new " + NumberLabel.class.getCanonicalName() + "("
+ + NumberFormat.class.getCanonicalName() + ".getCurrencyFormat())",
+ w.getInitializer());
+
+ assertTrue(tester.writer.statements.isEmpty());
+ assertNull(tester.logger.died);
+ }
+
+ public void testHappyWithCurrencyPredefinedFormatAndCurrencCode()
+ throws UnableToCompleteException, SAXException {
+ StringBuffer b = new StringBuffer();
+ b.append("<g:NumberLabel predefinedFormat='CURRENCY' currencyCode='EUR'>");
+ b.append("</g:NumberLabel>");
+
+ FieldWriter w = tester.parse(b.toString());
+ assertEquals("new " + NumberLabel.class.getCanonicalName() + "("
+ + NumberFormat.class.getCanonicalName() + ".getCurrencyFormat(\"EUR\"))",
+ w.getInitializer());
+
+ assertTrue(tester.writer.statements.isEmpty());
+ assertNull(tester.logger.died);
+ }
+
+ public void testChokeOnNonDateTimeFormat() throws SAXException {
+ StringBuffer b = new StringBuffer();
+ b.append("<g:NumberLabel format='someString' >");
+ b.append("</g:NumberLabel>");
+
+ try {
+ tester.parse(b.toString());
+ fail();
+ } catch (UnableToCompleteException e) {
+ assertTrue("Expect to hear about DateTimeFormat",
+ tester.logger.died.contains("DateTimeFormat"));
+ }
+ }
+
+ public void testChokeOnNonCurrencyData() throws SAXException {
+ StringBuffer b = new StringBuffer();
+ b.append("<g:NumberLabel predefinedFormat='CURRENCY' currencyData='someString' >");
+ b.append("</g:NumberLabel>");
+
+ try {
+ tester.parse(b.toString());
+ fail();
+ } catch (UnableToCompleteException e) {
+ assertTrue("Expect to hear about CurrencyData",
+ tester.logger.died.contains("CurrencyData"));
+ }
+ }
+
+ public void testChokeOnUnknownPredefinedFormat() throws SAXException {
+ StringBuffer b = new StringBuffer();
+ b.append("<g:NumberLabel predefinedFormat='someString' >");
+ b.append("</g:NumberLabel>");
+
+ try {
+ tester.parse(b.toString());
+ fail();
+ } catch (UnableToCompleteException e) {
+ assertTrue(tester.logger.died, tester.logger.died.contains(String.format(
+ NumberLabelParser.UNKNOWN_PREDEFINED_FORMAT, "someString")));
+ }
+ }
+
+ public void testChokeOnMultipleFormats() throws SAXException {
+ StringBuffer b = new StringBuffer();
+ b.append("<g:NumberLabel predefinedFormat='SCIENTIFIC' customFormat='#'>");
+ b.append("</g:NumberLabel>");
+
+ try {
+ tester.parse(b.toString());
+ fail();
+ } catch (UnableToCompleteException e) {
+ assertTrue(
+ tester.logger.died,
+ tester.logger.died.contains(NumberLabelParser.AT_MOST_ONE_SPECIFIED_FORMAT));
+ }
+ }
+
+ public void testChokeOnMultipleCurrencies() throws SAXException {
+ StringBuffer b = new StringBuffer();
+ b.append("<g:NumberLabel predefinedFormat='CURRENCY' currencyData='{someCurrencyData}' currencyCode='EUR'>");
+ b.append("</g:NumberLabel>");
+
+ try {
+ tester.parse(b.toString());
+ fail();
+ } catch (UnableToCompleteException e) {
+ assertTrue(
+ tester.logger.died,
+ tester.logger.died.contains(NumberLabelParser.AT_MOST_ONE_SPECIFIED_CURRENCY));
+ }
+ }
+
+ public void testChokeOnCurrencyWithoutSpecifiedFormat() throws SAXException {
+ StringBuffer b = new StringBuffer();
+ b.append("<g:NumberLabel currencyCode='EUR'>");
+ b.append("</g:NumberLabel>");
+
+ try {
+ tester.parse(b.toString());
+ fail();
+ } catch (UnableToCompleteException e) {
+ assertTrue(
+ tester.logger.died,
+ tester.logger.died.contains(NumberLabelParser.NO_CURRENCY_WITHOUT_SPECIFIED_FORMAT));
+ }
+ }
+
+ public void testChokeOnCurrencyWithPredefinedFormat() throws SAXException {
+ StringBuffer b = new StringBuffer();
+ b.append("<g:NumberLabel predefinedFormat='PERCENT' currencyCode='EUR'>");
+ b.append("</g:NumberLabel>");
+
+ try {
+ tester.parse(b.toString());
+ fail();
+ } catch (UnableToCompleteException e) {
+ assertTrue(
+ tester.logger.died,
+ tester.logger.died.contains(NumberLabelParser.NO_CURRENCY_WITH_PREDEFINED_FORMAT));
+ }
+ }
+}
diff --git a/user/test/com/google/gwt/uibinder/test/UiJavaResources.java b/user/test/com/google/gwt/uibinder/test/UiJavaResources.java
index 91852ee..ad1280a 100644
--- a/user/test/com/google/gwt/uibinder/test/UiJavaResources.java
+++ b/user/test/com/google/gwt/uibinder/test/UiJavaResources.java
@@ -1,12 +1,12 @@
/*
* Copyright 2009 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
@@ -19,6 +19,7 @@
import com.google.gwt.dev.javac.impl.MockJavaResource;
import com.google.gwt.dev.resource.Resource;
import com.google.gwt.dev.util.collect.HashSet;
+import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat;
import java.util.Arrays;
import java.util.Set;
@@ -95,6 +96,53 @@
return code;
}
};
+ public static final MockJavaResource CURRENCY_DATA = new MockJavaResource(
+ "com.google.gwt.i18n.client.CurrencyData") {
+ @Override
+ protected CharSequence getContent() {
+ StringBuffer code = new StringBuffer();
+ code.append("package com.google.gwt.i18n.client;\n");
+ code.append("public class CurrencyData {\n");
+ code.append("}\n");
+ return code;
+ }
+ };
+ public static final MockJavaResource DATE_LABEL = new MockJavaResource(
+ "com.google.gwt.user.client.ui.DateLabel") {
+ @Override
+ protected CharSequence getContent() {
+ StringBuffer code = new StringBuffer();
+ code.append("package com.google.gwt.user.client.ui;\n");
+ code.append("import com.google.gwt.i18n.client.DateTimeFormat;\n");
+ code.append("import com.google.gwt.i18n.client.TimeZone;\n");
+ code.append("public class DateLabel extends ValueLabel {\n");
+ code.append(" public DateLabel() { super(null); } ");
+ code.append(" public DateLabel(DateTimeFormat format) { super(null); } ");
+ code.append(" public DateLabel(DateTimeFormat format, TimeZone timeZone) { super(null); } ");
+ code.append("}\n");
+ return code;
+ }
+ };
+ public static final MockJavaResource DATE_TIME_FORMAT = new MockJavaResource(
+ "com.google.gwt.i18n.client.DateTimeFormat") {
+ @Override
+ protected CharSequence getContent() {
+ StringBuffer code = new StringBuffer();
+ code.append("package com.google.gwt.i18n.client;\n");
+ code.append("public class DateTimeFormat {\n");
+ code.append(" public static enum PredefinedFormat {\n");
+ PredefinedFormat[] values = PredefinedFormat.values();
+ for (int i = 0; i < values.length; i++) {
+ code.append(" ").append(values[i].name());
+ if (i < values.length - 1) {
+ code.append(",\n");
+ }
+ }
+ code.append(" }\n");
+ code.append("}\n");
+ return code;
+ }
+ };
public static final MockJavaResource DIALOG_BOX = new MockJavaResource(
"com.google.gwt.user.client.ui.DialogBox") {
@Override
@@ -352,6 +400,42 @@
return code;
}
};
+ public static final MockJavaResource NUMBER_LABEL = new MockJavaResource(
+ "com.google.gwt.user.client.ui.NumberLabel") {
+ @Override
+ protected CharSequence getContent() {
+ StringBuffer code = new StringBuffer();
+ code.append("package com.google.gwt.user.client.ui;\n");
+ code.append("import com.google.gwt.i18n.client.NumberFormat;\n");
+ code.append("public class NumberLabel extends ValueLabel {\n");
+ code.append(" public NumberLabel() { super(null); } ");
+ code.append(" public NumberLabel(NumberFormat format) { super(null); } ");
+ code.append("}\n");
+ return code;
+ }
+ };
+ public static final MockJavaResource NUMBER_FORMAT = new MockJavaResource(
+ "com.google.gwt.i18n.client.NumberFormat") {
+ @Override
+ protected CharSequence getContent() {
+ StringBuffer code = new StringBuffer();
+ code.append("package com.google.gwt.i18n.client;\n");
+ code.append("public class NumberFormat {\n");
+ code.append("}\n");
+ return code;
+ }
+ };
+ public static final MockJavaResource RENDERER = new MockJavaResource(
+ "com.google.gwt.text.shared.Renderer") {
+ @Override
+ protected CharSequence getContent() {
+ StringBuffer code = new StringBuffer();
+ code.append("package com.google.gwt.text.shared;\n");
+ code.append("public class Renderer<T> {\n");
+ code.append("}\n");
+ return code;
+ }
+ };
public static final MockJavaResource SPLIT_LAYOUT_PANEL = new MockJavaResource(
"com.google.gwt.user.client.ui.SplitLayoutPanel") {
@Override
@@ -432,6 +516,17 @@
return code;
}
};
+ public static final MockJavaResource TIME_ZONE = new MockJavaResource(
+ "com.google.gwt.i18n.client.TimeZone") {
+ @Override
+ protected CharSequence getContent() {
+ StringBuffer code = new StringBuffer();
+ code.append("package com.google.gwt.i18n.client;\n");
+ code.append("public class TimeZone {\n");
+ code.append("}\n");
+ return code;
+ }
+ };
public static final MockJavaResource UI_BINDER = new MockJavaResource(
"com.google.gwt.uibinder.client.UiBinder") {
@Override
@@ -467,6 +562,19 @@
return code;
}
};
+ public static final MockJavaResource VALUE_LABEL = new MockJavaResource(
+ "com.google.gwt.user.client.ui.ValueLabel") {
+ @Override
+ protected CharSequence getContent() {
+ StringBuffer code = new StringBuffer();
+ code.append("package com.google.gwt.user.client.ui;\n");
+ code.append("import com.google.gwt.text.shared.Renderer;\n");
+ code.append("public class ValueLabel extends Widget {\n");
+ code.append(" public ValueLabel(Renderer renderer) {} ");
+ code.append("}\n");
+ return code;
+ }
+ };
public static final MockJavaResource WIDGET = new MockJavaResource(
"com.google.gwt.user.client.ui.Widget") {
@Override
@@ -491,6 +599,9 @@
rtn.add(CLICK_EVENT);
rtn.add(CLICK_HANDLER);
rtn.add(COMMAND);
+ rtn.add(CURRENCY_DATA);
+ rtn.add(DATE_LABEL);
+ rtn.add(DATE_TIME_FORMAT);
rtn.add(DIALOG_BOX);
rtn.add(DISCLOSURE_PANEL);
rtn.add(DOCK_LAYOUT_PANEL);
@@ -512,6 +623,9 @@
rtn.add(MENU_ITEM_SEPARATOR);
rtn.add(MOUSE_OVER_EVENT);
rtn.add(MOUSE_OVER_HANDLER);
+ rtn.add(NUMBER_LABEL);
+ rtn.add(NUMBER_FORMAT);
+ rtn.add(RENDERER);
rtn.add(SPLIT_LAYOUT_PANEL);
rtn.add(STACK_LAYOUT_PANEL);
rtn.add(STACK_PANEL);
@@ -519,9 +633,11 @@
rtn.add(TAB_LAYOUT_PANEL);
rtn.add(TAB_PANEL);
rtn.add(TEXT_BOX_BASE);
+ rtn.add(TIME_ZONE);
rtn.add(UI_OBJECT);
rtn.add(UI_BINDER);
rtn.add(UI_FACTORY);
+ rtn.add(VALUE_LABEL);
rtn.add(WIDGET);
return rtn;
}
diff --git a/user/test/com/google/gwt/uibinder/test/client/UiBinderTest.java b/user/test/com/google/gwt/uibinder/test/client/UiBinderTest.java
index 7201ea0..74426a9 100644
--- a/user/test/com/google/gwt/uibinder/test/client/UiBinderTest.java
+++ b/user/test/com/google/gwt/uibinder/test/client/UiBinderTest.java
@@ -28,14 +28,17 @@
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.DateLabel;
import com.google.gwt.user.client.ui.DisclosurePanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.NamedFrame;
+import com.google.gwt.user.client.ui.NumberLabel;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.StackPanel;
+import com.google.gwt.user.client.ui.ValueLabel;
import com.google.gwt.user.client.ui.Widget;
/**
@@ -469,6 +472,21 @@
assertNotNull("NamedFrame exists", p);
}
+ public void testDateLabel() {
+ DateLabel p = widgetUi.myDateLabel;
+ assertNotNull("DateLabel exists", p);
+ }
+
+ public void testNumberLabel() {
+ NumberLabel<Float> p = widgetUi.myNumberLabel;
+ assertNotNull("NumberLabel exists", p);
+ }
+
+ public void testValueLabel() {
+ ValueLabel<Double> p = widgetUi.myValueLabel;
+ assertNotNull("ValueLabel exists", p);
+ }
+
public void testStringAttributeIgnoresStaticSetter() {
// Assumes setPopupText() is overloaded such that there is a static
// setPopupText(Foo, String) method.
diff --git a/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.java b/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.java
index 766ce98..9cd127e 100644
--- a/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.java
+++ b/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.java
@@ -27,12 +27,15 @@
import com.google.gwt.resources.client.DataResource;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.resources.client.CssResource.Shared;
+import com.google.gwt.text.client.DoubleRenderer;
+import com.google.gwt.text.shared.Renderer;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiFactory;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.DateLabel;
import com.google.gwt.user.client.ui.DisclosurePanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
@@ -45,11 +48,13 @@
import com.google.gwt.user.client.ui.MenuBar;
import com.google.gwt.user.client.ui.MenuItem;
import com.google.gwt.user.client.ui.NamedFrame;
+import com.google.gwt.user.client.ui.NumberLabel;
import com.google.gwt.user.client.ui.PushButton;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.StackPanel;
import com.google.gwt.user.client.ui.ToggleButton;
import com.google.gwt.user.client.ui.Tree;
+import com.google.gwt.user.client.ui.ValueLabel;
import com.google.gwt.user.client.ui.Widget;
/**
@@ -171,6 +176,11 @@
@UiField Widget myAbsolutePanelItemB;
@UiField Widget myAbsolutePanelItemC;
@UiField NamedFrame myNamedFrame;
+ @UiField DateLabel myDateLabel;
+ @UiField NumberLabel<Float> myNumberLabel;
+ @UiField(provided = true) @SuppressWarnings("unchecked")
+ Renderer doubleRenderer = DoubleRenderer.instance();
+ @UiField ValueLabel<Double> myValueLabel;
public WidgetBasedUi() {
external.style().ensureInjected();
diff --git a/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.ui.xml b/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.ui.xml
index b4d3710..08a6b83 100644
--- a/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.ui.xml
+++ b/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.ui.xml
@@ -72,6 +72,10 @@
for a resource to provide arbitrary objects to arbitrary attributes (look for FooLabel)
</ui:with>
+<ui:with field='doubleRenderer' type='com.google.gwt.text.shared.Renderer'>
+ Used to test ValueLabel's @UiConstructor
+</ui:with>
+
<ui:import field='com.google.gwt.uibinder.test.client.Constants.CONST_FOO'>
Tests the static import of a single constant into the local namespace.
</ui:import>
@@ -83,6 +87,7 @@
<ui:import field='com.google.gwt.uibinder.test.client.Constants.MyEnum.*'>
Tests the static import of an enum into the local namespace.
</ui:import>
+
<!--
Tests creating a CssResource from an external file.
-->
@@ -303,7 +308,8 @@
<ui:attribute name="text" description="radio button name"/>
</demo:PointlessRadioButtonSubclass>
- <gwt:HorizontalPanel ui:field="myHorizontalPanel" horizontalAlignment="ALIGN_LEFT" verticalAlignment="ALIGN_MIDDLE">
+ <gwt:HorizontalPanel ui:field="myHorizontalPanel"
+ horizontalAlignment="ALIGN_LEFT" verticalAlignment="ALIGN_MIDDLE">
<gwt:Cell><gwt:HTMLPanel>
<p> ... a StackPanel ... </p>
@@ -640,6 +646,12 @@
<gwt:NamedFrame ui:field='myNamedFrame' name='myName'/>
+ <gwt:DateLabel ui:field='myDateLabel' predefinedFormat='DATE_FULL' />
+
+ <gwt:NumberLabel ui:field='myNumberLabel' predefinedFormat='SCIENTIFIC' />
+
+ <gwt:ValueLabel ui:field='myValueLabel' renderer='{doubleRenderer}' />
+
</gwt:HTMLPanel>
</gwt:Dock>
</gwt:DockPanel>