From: Shane Carr Date: Wed, 29 Aug 2018 05:36:09 +0000 (-0700) Subject: ICU-11276 Assorted Java NumberRangeFormatter API improvements. X-Git-Tag: release-63-rc~63^2~32 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cc842512fa8c5d964c5d60a68f80236a1fbc7711;p=icu ICU-11276 Assorted Java NumberRangeFormatter API improvements. --- diff --git a/icu4j/main/classes/core/src/com/ibm/icu/number/FormattedNumberRange.java b/icu4j/main/classes/core/src/com/ibm/icu/number/FormattedNumberRange.java index f3add3297ea..132420e154c 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/number/FormattedNumberRange.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/number/FormattedNumberRange.java @@ -10,6 +10,7 @@ import java.util.Arrays; import com.ibm.icu.impl.number.DecimalQuantity; import com.ibm.icu.impl.number.NumberStringBuilder; +import com.ibm.icu.number.NumberRangeFormatter.RangeIdentityType; import com.ibm.icu.util.ICUUncheckedIOException; /** @@ -17,7 +18,7 @@ import com.ibm.icu.util.ICUUncheckedIOException; * including a String, an AttributedCharacterIterator, and a BigDecimal. * * @author sffc - * @draft ICU 62 + * @draft ICU 63 * @provisional This API might change or be removed in a future release. * @see NumberRangeFormatter */ @@ -27,10 +28,6 @@ public class FormattedNumberRange { final DecimalQuantity second; final RangeIdentityType identityType; - public static enum RangeIdentityType { - EQUAL_BEFORE_ROUNDING, EQUAL_AFTER_ROUNDING, NOT_EQUAL - } - FormattedNumberRange(NumberStringBuilder nsb, DecimalQuantity first, DecimalQuantity second, RangeIdentityType identityType) { this.nsb = nsb; @@ -89,8 +86,8 @@ public class FormattedNumberRange { * multiple times, this method may be called repeatedly with the following pattern: * *
-     * FieldPosition fpos = new FieldPosition(NumberFormat.Field.GROUPING_SEPARATOR);
-     * while (formattedNumber.nextFieldPosition(fpos, status)) {
+     * FieldPosition fpos = new FieldPosition(NumberFormat.Field.INTEGER);
+     * while (formattedNumberRange.nextFieldPosition(fpos, status)) {
      *     // do something with fpos.
      * }
      * 
@@ -162,7 +159,7 @@ public class FormattedNumberRange { * used. For example, if the first and second number were the same either before or after rounding occurred, an * identity fallback was used. * - * @return A IdentityType indicating the resulting identity situation in the formatted number range. + * @return A RangeIdentityType indicating the resulting identity situation in the formatted number range. * @draft ICU 63 * @provisional This API might change or be removed in a future release. * @see NumberRangeFormatter diff --git a/icu4j/main/classes/core/src/com/ibm/icu/number/LocalizedNumberRangeFormatter.java b/icu4j/main/classes/core/src/com/ibm/icu/number/LocalizedNumberRangeFormatter.java index 193706b3a96..33aa65be7fe 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/number/LocalizedNumberRangeFormatter.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/number/LocalizedNumberRangeFormatter.java @@ -6,7 +6,7 @@ import com.ibm.icu.impl.number.DecimalQuantity; import com.ibm.icu.impl.number.DecimalQuantity_DualStorageBCD; import com.ibm.icu.impl.number.NumberStringBuilder; import com.ibm.icu.impl.number.range.RangeMacroProps; -import com.ibm.icu.number.FormattedNumberRange.RangeIdentityType; +import com.ibm.icu.number.NumberRangeFormatter.RangeIdentityType; /** * A NumberRangeFormatter that has a locale associated with it; this means .formatRange() methods are available. @@ -30,7 +30,7 @@ public class LocalizedNumberRangeFormatter extends NumberRangeFormatterSettings< * The first number in the range, usually to the left in LTR locales. * @param second * The second number in the range, usually to the right in LTR locales. - * @return A FormattedNumber object; call .toString() to get the string. + * @return A FormattedNumberRange object; call .toString() to get the string. * @draft ICU 63 * @provisional This API might change or be removed in a future release. * @see NumberRangeFormatter @@ -49,7 +49,7 @@ public class LocalizedNumberRangeFormatter extends NumberRangeFormatterSettings< * The first number in the range, usually to the left in LTR locales. * @param second * The second number in the range, usually to the right in LTR locales. - * @return A FormattedNumber object; call .toString() to get the string. + * @return A FormattedNumberRange object; call .toString() to get the string. * @draft ICU 63 * @provisional This API might change or be removed in a future release. * @see NumberRangeFormatter @@ -70,7 +70,7 @@ public class LocalizedNumberRangeFormatter extends NumberRangeFormatterSettings< * The first number in the range, usually to the left in LTR locales. * @param second * The second number in the range, usually to the right in LTR locales. - * @return A FormattedNumber object; call .toString() to get the string. + * @return A FormattedNumberRange object; call .toString() to get the string. * @draft ICU 63 * @provisional This API might change or be removed in a future release. * @see NumberRangeFormatter diff --git a/icu4j/main/classes/core/src/com/ibm/icu/number/NumberRangeFormatter.java b/icu4j/main/classes/core/src/com/ibm/icu/number/NumberRangeFormatter.java index a138a6d2daf..437d1b86978 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/number/NumberRangeFormatter.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/number/NumberRangeFormatter.java @@ -8,6 +8,20 @@ import com.ibm.icu.util.ULocale; /** * The main entrypoint to the formatting of ranges of numbers, including currencies and other units of measurement. + *

+ * Usage example: + *

+ * + *

+ * NumberRangeFormatter.with().identityFallback(RangeIdentityFallback.APPROXIMATELY_OR_SINGLE_VALUE)
+ *         .numberFormatterFirst(NumberFormatter.with().unit(MeasureUnit.METER))
+ *         .numberFormatterSecond(NumberFormatter.with().unit(MeasureUnit.KILOMETER)).locale(ULocale.UK)
+ *         .formatRange(750, 1.2).toString();
+ * // => "750 m - 1.2 km"
+ * 
+ *

+ * Like NumberFormatter, NumberRangeFormatter instances are immutable and thread-safe. This API is based on the + * fluent design pattern popularized by libraries such as Google's Guava. * * @author sffc * @draft ICU 63 @@ -72,7 +86,7 @@ public abstract class NumberRangeFormatter { * @provisional This API might change or be removed in a future release. * @see NumberRangeFormatter */ - public enum IdentityFallback { + public static enum RangeIdentityFallback { /** * Show the number as a single value rather than a range. Example: "$5" * @@ -114,41 +128,64 @@ public abstract class NumberRangeFormatter { } /** - * Defines the behavior when the two numbers in the range are identical after rounding. To programmatically detect - * when the identity fallback is used, compare the lower and upper BigDecimals via FormattedNumber. + * Used in the result class FormattedNumberRange to indicate to the user whether the numbers formatted in the range + * were equal or not, and whether or not the identity fallback was applied. + * + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + * @see NumberRangeFormatter */ - - public static enum RangeIdentityFallback { - /** - * Show the number as a single value rather than a range. Example: "$5" - */ - SINGLE_VALUE, - + public static enum RangeIdentityType { /** - * Show the number using a locale-sensitive approximation pattern. If the numbers were the same before rounding, - * show the single value. Example: "~$5" or "$5" + * Used to indicate that the two numbers in the range were equal, even before any rounding rules were applied. + * + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + * @see NumberRangeFormatter */ - APPROXIMATELY_OR_SINGLE_VALUE, + EQUAL_BEFORE_ROUNDING, /** - * Show the number using a locale-sensitive approximation pattern. Use the range pattern always, even if the - * inputs are the same. Example: "~$5" + * Used to indicate that the two numbers in the range were equal, but only after rounding rules were applied. + * + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + * @see NumberRangeFormatter */ - APPROXIMATELY, + EQUAL_AFTER_ROUNDING, /** - * Show the number as the range of two equal values. Use the range pattern always, even if the inputs are the - * same. Example (with RangeCollapse.NONE): "$5 – $5" + * Used to indicate that the two numbers in the range were not equal, even after rounding rules were applied. + * + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + * @see NumberRangeFormatter */ - RANGE + NOT_EQUAL } private static final UnlocalizedNumberRangeFormatter BASE = new UnlocalizedNumberRangeFormatter(); + /** + * Call this method at the beginning of a NumberRangeFormatter fluent chain in which the locale is not currently + * known at the call site. + * + * @return An {@link UnlocalizedNumberRangeFormatter}, to be used for chaining. + * @draft ICU 63 + */ public static UnlocalizedNumberRangeFormatter with() { return BASE; } + /** + * Call this method at the beginning of a NumberRangeFormatter fluent chain in which the locale is known at the call + * site. + * + * @param locale + * The locale from which to load formats and symbols for number range formatting. + * @return A {@link LocalizedNumberRangeFormatter}, to be used for chaining. + * @draft ICU 63 + */ public static LocalizedNumberRangeFormatter withLocale(Locale locale) { return BASE.locale(locale); } diff --git a/icu4j/main/classes/core/src/com/ibm/icu/number/NumberRangeFormatterSettings.java b/icu4j/main/classes/core/src/com/ibm/icu/number/NumberRangeFormatterSettings.java index 7c9a70fb23b..4971a9e6c1f 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/number/NumberRangeFormatterSettings.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/number/NumberRangeFormatterSettings.java @@ -53,19 +53,35 @@ public abstract class NumberRangeFormatterSettings - * The NumberFormatter instances must not have a locale applied yet; the locale specified on the + * The NumberFormatter instance must not have a locale applied yet; the locale specified on the * NumberRangeFormatter will be used. * * @param formatterFirst * The formatter to use for the first number in the range. + * @return The fluent chain. + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + * @see NumberFormatter + * @see NumberRangeFormatter + */ + public T numberFormatterFirst(UnlocalizedNumberFormatter formatterFirst) { + return create(KEY_FORMATTER_1, formatterFirst); + } + + /** + * Sets the NumberFormatter instances to use for the numbers in the range. This method allows you to set a different + * formatter for the first and second numbers. + *

+ * The NumberFormatter instance must not have a locale applied yet; the locale specified on the + * NumberRangeFormatter will be used. + * * @param formatterSecond * The formatter to use for the second number in the range. * @return The fluent chain. @@ -74,9 +90,8 @@ public abstract class NumberRangeFormatterSettingsAPPROXIMATELY: "~5 miles" *

  • RANGE: "5-5 miles" (with collapse=UNIT)
  • *

    - * The default value is AUTO. + * The default value is APPROXIMATELY. * * @param identityFallback * The strategy to use when formatting two numbers that end up being the same. diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberRangeFormatterTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberRangeFormatterTest.java index c0cfce5c1f5..1e150d3fe4c 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberRangeFormatterTest.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberRangeFormatterTest.java @@ -61,7 +61,7 @@ public class NumberRangeFormatterTest { public void testNullBehavior() { assertFormatRange( "Basic", - NumberRangeFormatter.with().numberFormatter(null), + NumberRangeFormatter.with().numberFormatterBoth(null), ULocale.US, "1 --- 5", "5 --- 5", @@ -76,7 +76,7 @@ public class NumberRangeFormatterTest { assertFormatRange( "Basic", - NumberRangeFormatter.with().numberFormatters(null, null), + NumberRangeFormatter.with().numberFormatterFirst(null), ULocale.US, "1 --- 5", "5 --- 5", @@ -91,10 +91,9 @@ public class NumberRangeFormatterTest { assertFormatRange( "Basic", - NumberRangeFormatter.with().numberFormatters( - NumberFormatter.with().grouping(GroupingStrategy.OFF), - null - ), + NumberRangeFormatter.with() + .numberFormatterFirst(NumberFormatter.with().grouping(GroupingStrategy.OFF)) + .numberFormatterSecond(null), ULocale.US, "1 --- 5", "5 --- 5", @@ -109,10 +108,9 @@ public class NumberRangeFormatterTest { assertFormatRange( "Basic", - NumberRangeFormatter.with().numberFormatters( - null, - NumberFormatter.with().grouping(GroupingStrategy.OFF) - ), + NumberRangeFormatter.with() + .numberFormatterFirst(null) + .numberFormatterSecond(NumberFormatter.with().grouping(GroupingStrategy.OFF)), ULocale.US, "1 --- 5", "5 --- 5",