Package limn.i18n

Class NumberFormats

java.lang.Object
limn.i18n.NumberFormats

public final class NumberFormats extends Object
Ready-made number formats: what a chart puts on an axis tick or a tooltip, what a table puts in a numeric column and its footer, and what any caption that shows a number can use.

Every format here follows the language in effect where it formats, read at that moment: a locale switch reaches widgets already on screen, and a widget inside a subtree that declares its own locale formats in that subtree's language — separators, digits and a currency's symbol and position alike — because the widget's passes hold its effective locale in scope. A format is a plain DoubleFunction<String>: anything else you write is equally acceptable, and reads the same scope for free by asking I18n.locale() when it formats.

The separators are always the ones that go with the digits a number is written in, which are the numbering system's and not necessarily the ones the platform would pick for the language: a bare ar, which the toolkit writes in Latin digits, reads 1,234.5 rather than putting the Arabic separators between Latin digits, ar-EG reads ١٬٢٣٤٫٥, and a declared system brings its own separators along with its digits.


 chart.setValueFormat(NumberFormats.compact());                      // 12500 -> "12.5k"
 chart.valueAxis().setFormat(NumberFormats.unit(" ms"));             // 16 -> "16 ms"
 Column.numeric("Price", Item::price, NumberFormats.prefix("R$ "));  // 1234.5 -> "R$ 1.234,5"
 Column.currency("Total", Order::total, Currency.getInstance("BRL")); // -> "R$ 1.234,50"
 

DateFormats is its counterpart for dates and times, and I18n.numberLocale() the locale these formats write in, for a format of an application's own.

This class was once limn.components.chart.ChartFormats; the table gave it a second caller and the name moved with it.

  • Method Details

    • number

      public static DoubleFunction<String> number()
      Grouped, with up to two decimals and no trailing zeros: 1234.5 reads "1,234.5" in English and "1.234,5" in German.
    • number

      public static DoubleFunction<String> number(int maxDecimals)
      number() with up to maxDecimals decimals instead of two: grouped, and with no trailing zeros, so number(3) writes 0.105 as "0.105" and 0.11 as "0.11". The precision a caller wants for values that sit closer together than a hundredth, which is what a chart's axis asks for when its ticks do.
      Parameters:
      maxDecimals - the most decimals written; a negative count writes none
      Returns:
      the format
    • decimals

      public static DoubleFunction<String> decimals(int digits)
      Grouped with exactly digits decimals.
    • compact

      public static DoubleFunction<String> compact()
      Thousands folded into a suffix: 27600 reads "27.6k", 1_200_000 reads "1.2M", 1.5e12 reads "1.5T". Values below 1000 are left alone. The suffix is chosen after the one decimal is rounded, so a value that rounds up to a thousand of one unit is written in the next: 999950 reads "1M", never "1000k".
    • scientific

      public static DoubleFunction<String> scientific(int maxDecimals)
      Scientific notation: a mantissa from 1 up to 10 with up to maxDecimals decimals and no trailing zeros, then the language's exponent sign and the power of ten. 1.2e25 reads "1.2E25" in English, "1,2E25" in German and "1,2×10^25" in Swedish, 0.00042 reads "4.2E-4", and zero reads "0". It is what a number too large to write out wants: past about 1015 a double no longer holds every whole number, so the digits a written-out value shows past there are noise, and there are hundreds of them by 1e300.
      Parameters:
      maxDecimals - the most decimals the mantissa is written with; a negative count writes none
      Returns:
      the format
    • percent

      public static DoubleFunction<String> percent(int digits)
      A fraction as a percentage: 0.42 reads "42%". Values that are already scaled to 0–100 want unit(String) with "%" instead.
    • unit

      public static DoubleFunction<String> unit(String suffix)
      number() with a fixed suffix: unit(" ms"), unit("%").
    • prefix

      public static DoubleFunction<String> prefix(String text)
      number() with a fixed prefix: prefix("$"), prefix("R$ "). The prefix sits before the number in every language; money whose symbol should follow the language's own rules wants currency(Currency) instead.
    • currency

      public static DoubleFunction<String> currency(Currency currency)
      An amount of money in a named currency, written as the language in effect writes it: 1234.5 in Brazilian reais reads "R$ 1.234,50" under pt-BR, "R$ 1,234.50" under en, and "1 234,50 R$" under fr. The symbol, its position, the decimals and the separators are the locale's; the digits follow the active numbering system as every format here does.
      Parameters:
      currency - the currency the amounts are in; never null
      Returns:
      the format
    • currency

      public static DoubleFunction<String> currency(Currency currency, int decimals)
      currency(Currency) with exactly decimals decimals instead of the currency's own: what a chart's axis wants, whose ticks are whole amounts, or a price list kept to the tenth of a cent. currency(dollars, 0) writes 815800 as "US$ 815.800" under pt-BR and "$815,800" under en.

      Money with other decimals than the currency's is written here rather than with the platform's currency format asked for the language in effect, because that format writes the separators of the language's default digits, which are not always the digits shown: under a bare ar, whose numbers the toolkit writes in Latin digits, it puts the Arabic grouping sign between them (815٬800), where this writes 815,800.

      Parameters:
      currency - the currency the amounts are in; never null
      decimals - the decimals every amount is written with; a negative count writes none
      Returns:
      the format
    • currency

      public static DoubleFunction<String> currency()
      currency(Currency) in the currency of the language in effect: reais under pt-BR, euros under de-DE. A locale that names no country — ja, ar — has no currency of its own, and the platform then writes a generic sign; an application that knows which currency its amounts are in names it.
      Returns:
      the format