From b92652d690cec9b1a9c95fffea1422c2627cc13c Mon Sep 17 00:00:00 2001 From: Elango Cheran Date: Wed, 4 Jun 2025 18:34:36 -0700 Subject: [PATCH 1/2] ICU-23091 Add Java source formatting configs and automated checks --- .github/workflows/icu4j.yml | 27 +++++++++++++++++++++++ docs/userguide/dev/codingguidelines.md | 14 ++++++++++++ icu4j/pom.xml | 30 ++++++++++++++++++++++++++ 3 files changed, 71 insertions(+) diff --git a/.github/workflows/icu4j.yml b/.github/workflows/icu4j.yml index 16b8fdbd0bf0..249add702553 100644 --- a/.github/workflows/icu4j.yml +++ b/.github/workflows/icu4j.yml @@ -64,6 +64,33 @@ jobs: cd icu4j; mvn ${SHARED_MVN_ARGS} dependency:go-offline -P '!old_jdk_taglet' + # Using the Java style formatter google-java-style provided by the Spotless + # plugin configured in the root pom.xml using 4-space indents (AOSP style). + # Spotless is configured to run only on files in this branch (PR) that differ + # from origin/main + formatter: + name: Formatter + Style checker + needs: icu4j-mvn-init-cache + runs-on: ubuntu-latest + steps: + - name: Checkout and setup + uses: actions/checkout@v4 + with: + fetch-depth: 0 # fetch all branches so that Spotless can resolve `origin/main` + - name: Restore read-only cache of local Maven repository + uses: actions/cache/restore@v4 + id: cache + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- + lookup-only: true + - name: Check Java style + run: | + cd icu4j; + mvn spotless:check || (echo "Style checker failed. Formatting changes can be applied by 'mvn spotless:apply'" && exit 1) + # ICU4J build and unit test using Maven # https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven icu4j-mvn-build-and-test: diff --git a/docs/userguide/dev/codingguidelines.md b/docs/userguide/dev/codingguidelines.md index b572a0951833..e358b5c60579 100644 --- a/docs/userguide/dev/codingguidelines.md +++ b/docs/userguide/dev/codingguidelines.md @@ -1449,6 +1449,20 @@ ICU Java classes and methods. ### Code style +ICU uses a source formatter to ensure a consistent code style automatically, +and it uses a single common formatter to avoid spurious diff noise in code reviews. +This is now enforced via a +[formatter](https://github.com/google/google-java-format) +that is configured in the Maven build +via a [Maven plugin](https://github.com/diffplug/spotless/tree/main/plugin-maven) +and checked by continuous integration on pull requests. + +When creating pull requests, you can check the formatting locally using the command `mvn spotless:check`. You can apply the formatter's changes using the command `mvn spotless:apply`. Continuous integration errors for formatting can be fixed by committing the changes resulting from applying the formatter locally and pushing the new commit. + +The following are further guidelines for code style, +but they will be superceded by the automated formatter in CI that is mentioned above +if the guidelines differ in style. + The standard order for modifier keywords on APIs is: * `public static final synchronized strictfp` diff --git a/icu4j/pom.xml b/icu4j/pom.xml index 27ef3c6ac46a..ba5f7850a718 100644 --- a/icu4j/pom.xml +++ b/icu4j/pom.xml @@ -116,6 +116,9 @@ 1.0 2 © 2016 and later: Unicode, Inc. and others. License & terms of use: http://www.unicode.org/copyright.html + + 2.43.0 + 1.22.0 @@ -466,6 +469,33 @@ exec-maven-plugin 3.4.1 + + + com.diffplug.spotless + spotless-maven-plugin + ${formatter.plugin.spotless.version} + + + + NONE + + + + + + + + ${google-java-style.version} + + false + + + + From e834af42057d243e593d6b56103f0894c74c41a4 Mon Sep 17 00:00:00 2001 From: Elango Cheran Date: Thu, 5 Jun 2025 10:15:52 -0700 Subject: [PATCH 2/2] ICU-23091 Apply source formatter to all Java files in codebase --- .../java/com/ibm/icu/dev/demo/Launcher.java | 101 +- .../icu/dev/demo/calendar/CalendarApp.java | 18 +- .../icu/dev/demo/calendar/CalendarCalc.java | 390 +- .../icu/dev/demo/calendar/CalendarFrame.java | 298 +- .../icu/dev/demo/calendar/CalendarPanel.java | 140 +- .../dev/demo/charsetdet/DetectingViewer.java | 297 +- .../dev/demo/holiday/HolidayBorderPanel.java | 312 +- .../dev/demo/holiday/HolidayCalendarDemo.java | 406 +- .../ibm/icu/dev/demo/impl/AppletFrame.java | 48 +- .../com/ibm/icu/dev/demo/impl/DemoApplet.java | 51 +- .../ibm/icu/dev/demo/impl/DemoTextBox.java | 42 +- .../ibm/icu/dev/demo/impl/DemoUtility.java | 91 +- .../icu/dev/demo/impl/DumbTextComponent.java | 487 +- .../com/ibm/icu/dev/demo/impl/Selection.java | 53 +- .../ibm/icu/dev/demo/number/CurrencyDemo.java | 60 +- .../com/ibm/icu/dev/demo/rbnf/RbnfDemo.java | 561 +- .../icu/dev/demo/rbnf/RbnfSampleRuleSets.java | 3379 ++- .../dev/demo/translit/AnyTransliterator.java | 210 +- .../icu/dev/demo/translit/CaseIterator.java | 821 +- .../com/ibm/icu/dev/demo/translit/Demo.java | 1228 +- .../ibm/icu/dev/demo/translit/DemoApplet.java | 48 +- .../ibm/icu/dev/demo/translit/InfoDialog.java | 46 +- .../ibm/icu/dev/demo/translit/IntDiffer.java | 46 +- .../TransliteratingTextComponent.java | 165 +- .../demo/translit/TransliterationChart.java | 148 +- .../com/ibm/icu/charset/Charset88591.java | 44 +- .../com/ibm/icu/charset/CharsetASCII.java | 99 +- .../com/ibm/icu/charset/CharsetBOCU1.java | 738 +- .../com/ibm/icu/charset/CharsetCESU8.java | 17 +- .../com/ibm/icu/charset/CharsetCallback.java | 789 +- .../ibm/icu/charset/CharsetCompoundText.java | 327 +- .../ibm/icu/charset/CharsetDecoderICU.java | 461 +- .../ibm/icu/charset/CharsetEncoderICU.java | 320 +- .../java/com/ibm/icu/charset/CharsetHZ.java | 194 +- .../java/com/ibm/icu/charset/CharsetICU.java | 718 +- .../com/ibm/icu/charset/CharsetISCII.java | 2360 ++- .../com/ibm/icu/charset/CharsetISO2022.java | 2919 ++- .../com/ibm/icu/charset/CharsetLMBCS.java | 426 +- .../java/com/ibm/icu/charset/CharsetMBCS.java | 2472 ++- .../ibm/icu/charset/CharsetProviderICU.java | 187 +- .../java/com/ibm/icu/charset/CharsetSCSU.java | 1140 +- .../com/ibm/icu/charset/CharsetSelector.java | 95 +- .../com/ibm/icu/charset/CharsetUTF16.java | 121 +- .../com/ibm/icu/charset/CharsetUTF16BE.java | 12 +- .../com/ibm/icu/charset/CharsetUTF16LE.java | 12 +- .../com/ibm/icu/charset/CharsetUTF32.java | 81 +- .../com/ibm/icu/charset/CharsetUTF32BE.java | 12 +- .../com/ibm/icu/charset/CharsetUTF32LE.java | 12 +- .../java/com/ibm/icu/charset/CharsetUTF7.java | 977 +- .../java/com/ibm/icu/charset/CharsetUTF8.java | 121 +- .../com/ibm/icu/charset/UConverterAlias.java | 384 +- .../charset/UConverterAliasDataReader.java | 57 +- .../ibm/icu/charset/UConverterConstants.java | 177 +- .../ibm/icu/charset/UConverterDataReader.java | 283 +- .../ibm/icu/charset/UConverterSharedData.java | 533 +- .../ibm/icu/charset/UConverterStaticData.java | 54 +- .../main/java/com/ibm/icu/charset/UTF8.java | 56 +- .../ibm/icu/dev/test/charset/TestCharset.java | 5172 +++-- .../icu/dev/test/charset/TestConversion.java | 585 +- .../icu/dev/test/charset/TestSelection.java | 1633 +- .../java/com/ibm/icu/impl/coll/BOCSU.java | 359 +- .../java/com/ibm/icu/impl/coll/Collation.java | 407 +- .../ibm/icu/impl/coll/CollationBuilder.java | 1161 +- .../ibm/icu/impl/coll/CollationCompare.java | 45 +- .../com/ibm/icu/impl/coll/CollationData.java | 424 +- .../icu/impl/coll/CollationDataBuilder.java | 878 +- .../icu/impl/coll/CollationDataReader.java | 258 +- .../com/ibm/icu/impl/coll/CollationFCD.java | 662 +- .../ibm/icu/impl/coll/CollationFastLatin.java | 627 +- .../impl/coll/CollationFastLatinBuilder.java | 501 +- .../ibm/icu/impl/coll/CollationIterator.java | 843 +- .../com/ibm/icu/impl/coll/CollationKeys.java | 123 +- .../ibm/icu/impl/coll/CollationLoader.java | 102 +- .../com/ibm/icu/impl/coll/CollationRoot.java | 47 +- .../icu/impl/coll/CollationRootElements.java | 379 +- .../icu/impl/coll/CollationRuleParser.java | 523 +- .../ibm/icu/impl/coll/CollationSettings.java | 316 +- .../ibm/icu/impl/coll/CollationTailoring.java | 55 +- .../ibm/icu/impl/coll/CollationWeights.java | 356 +- .../impl/coll/ContractionsAndExpansions.java | 225 +- .../impl/coll/FCDIterCollationIterator.java | 272 +- .../impl/coll/FCDUTF16CollationIterator.java | 193 +- .../icu/impl/coll/IterCollationIterator.java | 33 +- .../com/ibm/icu/impl/coll/SharedObject.java | 93 +- .../com/ibm/icu/impl/coll/TailoredSet.java | 55 +- .../icu/impl/coll/UTF16CollationIterator.java | 71 +- .../java/com/ibm/icu/impl/coll/UVector32.java | 31 +- .../java/com/ibm/icu/impl/coll/UVector64.java | 31 +- .../impl/text/RbnfScannerProviderImpl.java | 119 +- .../com/ibm/icu/text/AlphabeticIndex.java | 404 +- .../icu/text/CollationElementIterator.java | 346 +- .../java/com/ibm/icu/text/CollationKey.java | 440 +- .../main/java/com/ibm/icu/text/Collator.java | 1149 +- .../com/ibm/icu/text/CollatorServiceShim.java | 73 +- .../com/ibm/icu/text/RawCollationKey.java | 77 +- .../com/ibm/icu/text/RuleBasedCollator.java | 1078 +- .../java/com/ibm/icu/text/SearchIterator.java | 578 +- .../java/com/ibm/icu/text/StringSearch.java | 647 +- .../icu/util/GlobalizationPreferences.java | 617 +- .../test/collator/AlphabeticIndexTest.java | 2119 +- .../dev/test/collator/CollationAPITest.java | 1120 +- .../test/collator/CollationChineseTest.java | 36 +- .../collator/CollationCreationMethodTest.java | 92 +- .../test/collator/CollationCurrencyTest.java | 110 +- .../dev/test/collator/CollationDummyTest.java | 197 +- .../test/collator/CollationEnglishTest.java | 333 +- .../test/collator/CollationFinnishTest.java | 47 +- .../test/collator/CollationFrenchTest.java | 170 +- .../collator/CollationFrozenMonkeyTest.java | 128 +- .../test/collator/CollationGermanTest.java | 104 +- .../test/collator/CollationIteratorTest.java | 500 +- .../dev/test/collator/CollationKanaTest.java | 113 +- .../dev/test/collator/CollationMiscTest.java | 2340 +- .../test/collator/CollationMonkeyTest.java | 130 +- .../collator/CollationRegressionTest.java | 479 +- .../test/collator/CollationServiceTest.java | 287 +- .../test/collator/CollationSpanishTest.java | 49 +- .../icu/dev/test/collator/CollationTest.java | 816 +- .../dev/test/collator/CollationThaiTest.java | 193 +- .../test/collator/CollationThreadTest.java | 238 +- .../test/collator/CollationTurkishTest.java | 48 +- .../ibm/icu/dev/test/collator/Counter.java | 420 +- .../dev/test/collator/G7CollationTest.java | 226 +- .../collator/LotusCollationKoreanTest.java | 59 +- .../dev/test/collator/UCAConformanceTest.java | 66 +- .../format/GlobalizationPreferencesTest.java | 186 +- .../test/format/RbnfLenientScannerTest.java | 123 +- .../ibm/icu/dev/test/search/SearchTest.java | 2382 ++- .../util/ICUResourceBundleCollationTest.java | 330 +- .../dev/test/util/ULocaleCollationTest.java | 338 +- .../icu/dev/test/TestLocaleNamePackaging.java | 77 +- .../test/calendar/DataDrivenCalendarTest.java | 221 +- .../test/format/CompactDecimalFormatTest.java | 763 +- .../dev/test/format/DataDrivenFormatTest.java | 122 +- .../icu/dev/test/format/DateFormatTest.java | 8420 +++++--- .../format/IntlTestDecimalFormatAPIC.java | 193 +- .../format/IntlTestDecimalFormatSymbolsC.java | 36 +- .../format/MeasureUnitCompatibilityTest.java | 6137 +++--- .../test/format/MeasureUnitGeneratorTest.java | 179 +- .../icu/dev/test/format/MeasureUnitTest.java | 1765 +- .../format/NumberFormatDataDrivenTest.java | 1002 +- .../format/NumberFormatRegressionTest.java | 315 +- .../format/NumberFormatSpecificationTest.java | 11 +- .../icu/dev/test/format/NumberFormatTest.java | 5331 +++-- .../test/format/NumberRegressionTests.java | 1304 +- .../icu/dev/test/format/PluralRangesTest.java | 167 +- .../icu/dev/test/format/PluralRulesTest.java | 1611 +- .../com/ibm/icu/dev/test/format/RbnfTest.java | 2402 ++- .../dev/test/format/TestMessageFormat.java | 1442 +- .../dev/test/format/TimeZoneFormatTest.java | 1126 +- .../dev/test/message2/Mf2FeaturesTest.java | 821 +- .../icu/dev/test/normalizer/BasicTest.java | 3277 +-- .../ibm/icu/dev/test/number/ModifierTest.java | 98 +- .../test/number/NumberFormatterApiTest.java | 3555 ++-- .../icu/dev/test/number/NumberParserTest.java | 395 +- .../test/number/NumberPermutationTest.java | 38 +- .../test/number/NumberRangeFormatterTest.java | 1531 +- .../dev/test/number/PatternStringTest.java | 133 +- .../icu/dev/test/number/PropertiesTest.java | 191 +- .../dev/test/rbbi/LSTMBreakEngineTest.java | 37 +- .../test/serializable/CalendarHandler.java | 79 +- .../test/serializable/CompatibilityTest.java | 132 +- .../dev/test/serializable/CoverageTest.java | 19 +- .../test/serializable/ExceptionHandler.java | 95 +- .../dev/test/serializable/FormatHandler.java | 1920 +- .../serializable/SerializableChecker.java | 66 +- .../serializable/SerializableTestUtility.java | 642 +- .../test/serializable/SerializableWriter.java | 26 +- .../icu/dev/test/stringprep/TestIDNARef.java | 1102 +- .../dev/test/stringprep/TestStringPrep.java | 242 +- .../ibm/icu/dev/test/util/CurrencyTest.java | 511 +- .../dev/test/util/ICUResourceBundleTest.java | 1257 +- .../ibm/icu/dev/test/util/ICUServiceTest.java | 1276 +- .../ibm/icu/dev/test/util/LocaleDataTest.java | 357 +- .../ibm/icu/dev/test/util/ULocaleTest.java | 6477 +++--- .../main/java/com/ibm/icu/impl/Assert.java | 13 +- .../main/java/com/ibm/icu/impl/BMPSet.java | 153 +- .../com/ibm/icu/impl/CSCharacterIterator.java | 46 +- .../main/java/com/ibm/icu/impl/CacheBase.java | 29 +- .../java/com/ibm/icu/impl/CacheValue.java | 105 +- .../com/ibm/icu/impl/CalendarAstronomer.java | 743 +- .../java/com/ibm/icu/impl/CalendarCache.java | 78 +- .../java/com/ibm/icu/impl/CalendarUtil.java | 29 +- .../java/com/ibm/icu/impl/CaseMapImpl.java | 1396 +- .../main/java/com/ibm/icu/impl/CharTrie.java | 262 +- .../com/ibm/icu/impl/CharacterIteration.java | 60 +- .../icu/impl/CharacterIteratorWrapper.java | 55 +- .../ibm/icu/impl/CharacterPropertiesImpl.java | 138 +- .../com/ibm/icu/impl/ClassLoaderUtil.java | 31 +- .../java/com/ibm/icu/impl/CollectionSet.java | 8 +- .../java/com/ibm/icu/impl/CurrencyData.java | 69 +- .../com/ibm/icu/impl/DateNumberFormat.java | 97 +- .../java/com/ibm/icu/impl/DayPeriodRules.java | 155 +- .../ibm/icu/impl/DontCareFieldPosition.java | 34 +- .../java/com/ibm/icu/impl/EmojiProps.java | 63 +- .../main/java/com/ibm/icu/impl/EraRules.java | 128 +- .../ibm/icu/impl/FormattedStringBuilder.java | 132 +- ...rmattedValueFieldPositionIteratorImpl.java | 22 +- .../impl/FormattedValueStringBuilderImpl.java | 60 +- .../src/main/java/com/ibm/icu/impl/Grego.java | 133 +- .../main/java/com/ibm/icu/impl/ICUBinary.java | 298 +- .../main/java/com/ibm/icu/impl/ICUCache.java | 4 +- .../main/java/com/ibm/icu/impl/ICUConfig.java | 24 +- .../main/java/com/ibm/icu/impl/ICUData.java | 157 +- .../java/com/ibm/icu/impl/ICUDataVersion.java | 33 +- .../main/java/com/ibm/icu/impl/ICUDebug.java | 12 +- .../com/ibm/icu/impl/ICULocaleService.java | 275 +- .../java/com/ibm/icu/impl/ICUNotifier.java | 72 +- .../main/java/com/ibm/icu/impl/ICURWLock.java | 135 +- .../com/ibm/icu/impl/ICUResourceBundle.java | 982 +- .../ibm/icu/impl/ICUResourceBundleImpl.java | 154 +- .../ibm/icu/impl/ICUResourceBundleReader.java | 567 +- .../ibm/icu/impl/ICUResourceTableAccess.java | 40 +- .../java/com/ibm/icu/impl/ICUService.java | 549 +- .../main/java/com/ibm/icu/impl/IDNA2003.java | 445 +- .../icu/impl/IllegalIcuArgumentException.java | 2 - .../java/com/ibm/icu/impl/ImmutableEntry.java | 17 +- .../main/java/com/ibm/icu/impl/IntTrie.java | 283 +- .../java/com/ibm/icu/impl/IntTrieBuilder.java | 670 +- .../ibm/icu/impl/InvalidFormatException.java | 19 +- .../com/ibm/icu/impl/IterableComparator.java | 9 +- .../com/ibm/icu/impl/JavaTimeConverters.java | 149 +- .../java/com/ibm/icu/impl/JavaTimeZone.java | 63 +- .../ibm/icu/impl/LocaleDisplayNamesImpl.java | 407 +- .../com/ibm/icu/impl/LocaleFallbackData.java | 7 +- .../java/com/ibm/icu/impl/LocaleIDParser.java | 287 +- .../main/java/com/ibm/icu/impl/LocaleIDs.java | 764 +- .../java/com/ibm/icu/impl/LocaleUtility.java | 44 +- .../java/com/ibm/icu/impl/Norm2AllModes.java | 256 +- .../com/ibm/icu/impl/Normalizer2Impl.java | 1857 +- .../java/com/ibm/icu/impl/OlsonTimeZone.java | 523 +- .../icu/impl/PVecToTrieCompactHandler.java | 6 +- .../src/main/java/com/ibm/icu/impl/Pair.java | 9 +- .../java/com/ibm/icu/impl/PatternProps.java | 296 +- .../com/ibm/icu/impl/PatternTokenizer.java | 287 +- .../com/ibm/icu/impl/PluralRulesLoader.java | 75 +- .../java/com/ibm/icu/impl/PropsVectors.java | 148 +- .../main/java/com/ibm/icu/impl/Punycode.java | 375 +- .../com/ibm/icu/impl/RBBIDataWrapper.java | 446 +- .../main/java/com/ibm/icu/impl/Relation.java | 44 +- .../com/ibm/icu/impl/RelativeDateFormat.java | 138 +- .../impl/ReplaceableUCharacterIterator.java | 118 +- .../ibm/icu/impl/ResourceBundleWrapper.java | 298 +- .../src/main/java/com/ibm/icu/impl/Row.java | 63 +- .../ibm/icu/impl/RuleCharacterIterator.java | 218 +- .../java/com/ibm/icu/impl/SimpleCache.java | 4 +- .../SimpleFilteredSentenceBreakIterator.java | 107 +- .../com/ibm/icu/impl/SimpleFormatterImpl.java | 183 +- .../main/java/com/ibm/icu/impl/SoftCache.java | 59 +- .../com/ibm/icu/impl/SortedSetRelation.java | 154 +- .../java/com/ibm/icu/impl/StandardPlural.java | 89 +- .../com/ibm/icu/impl/StaticUnicodeSets.java | 70 +- .../ibm/icu/impl/StringPrepDataReader.java | 70 +- .../java/com/ibm/icu/impl/StringRange.java | 144 +- .../java/com/ibm/icu/impl/StringSegment.java | 64 +- .../com/ibm/icu/impl/TZDBTimeZoneNames.java | 99 +- .../java/com/ibm/icu/impl/TextTrieMap.java | 47 +- .../com/ibm/icu/impl/TimeZoneAdapter.java | 82 +- .../ibm/icu/impl/TimeZoneGenericNames.java | 344 +- .../icu/impl/TimeZoneNamesFactoryImpl.java | 5 +- .../com/ibm/icu/impl/TimeZoneNamesImpl.java | 253 +- .../src/main/java/com/ibm/icu/impl/Trie.java | 458 +- .../src/main/java/com/ibm/icu/impl/Trie2.java | 783 +- .../java/com/ibm/icu/impl/Trie2Writable.java | 1182 +- .../main/java/com/ibm/icu/impl/Trie2_16.java | 146 +- .../main/java/com/ibm/icu/impl/Trie2_32.java | 147 +- .../java/com/ibm/icu/impl/TrieBuilder.java | 261 +- .../java/com/ibm/icu/impl/TrieIterator.java | 454 +- .../java/com/ibm/icu/impl/UBiDiProps.java | 244 +- .../java/com/ibm/icu/impl/UCaseProps.java | 1348 +- .../com/ibm/icu/impl/UCharArrayIterator.java | 37 +- .../icu/impl/UCharacterIteratorWrapper.java | 105 +- .../java/com/ibm/icu/impl/UCharacterName.java | 1270 +- .../ibm/icu/impl/UCharacterNameChoice.java | 46 +- .../ibm/icu/impl/UCharacterNameReader.java | 150 +- .../com/ibm/icu/impl/UCharacterProperty.java | 1317 +- .../com/ibm/icu/impl/UCharacterUtility.java | 237 +- .../com/ibm/icu/impl/UPropertyAliases.java | 325 +- .../java/com/ibm/icu/impl/URLHandler.java | 46 +- .../main/java/com/ibm/icu/impl/UResource.java | 205 +- .../java/com/ibm/icu/impl/USerializedSet.java | 187 +- .../src/main/java/com/ibm/icu/impl/UTS46.java | 833 +- .../java/com/ibm/icu/impl/UnicodeMap.java | 479 +- .../com/ibm/icu/impl/UnicodeMapIterator.java | 103 +- .../java/com/ibm/icu/impl/UnicodeRegex.java | 221 +- .../ibm/icu/impl/UnicodeSetStringSpan.java | 264 +- .../main/java/com/ibm/icu/impl/Utility.java | 1094 +- .../com/ibm/icu/impl/ValidIdentifiers.java | 75 +- .../main/java/com/ibm/icu/impl/ZoneMeta.java | 322 +- .../impl/breakiter/BurmeseBreakEngine.java | 64 +- .../breakiter/BytesDictionaryMatcher.java | 19 +- .../breakiter/CharsDictionaryMatcher.java | 14 +- .../icu/impl/breakiter/CjkBreakEngine.java | 67 +- .../impl/breakiter/DictionaryBreakEngine.java | 78 +- .../icu/impl/breakiter/DictionaryData.java | 10 +- .../icu/impl/breakiter/DictionaryMatcher.java | 28 +- .../icu/impl/breakiter/KhmerBreakEngine.java | 59 +- .../icu/impl/breakiter/LSTMBreakEngine.java | 207 +- .../impl/breakiter/LanguageBreakEngine.java | 24 +- .../icu/impl/breakiter/LaoBreakEngine.java | 70 +- .../ibm/icu/impl/breakiter/MlBreakEngine.java | 103 +- .../icu/impl/breakiter/ThaiBreakEngine.java | 72 +- .../impl/breakiter/UnhandledBreakEngine.java | 22 +- .../com/ibm/icu/impl/data/HolidayBundle.java | 4 +- .../ibm/icu/impl/data/HolidayBundle_da.java | 35 +- .../icu/impl/data/HolidayBundle_da_DK.java | 32 +- .../ibm/icu/impl/data/HolidayBundle_de.java | 106 +- .../icu/impl/data/HolidayBundle_de_AT.java | 25 +- .../icu/impl/data/HolidayBundle_de_DE.java | 22 +- .../ibm/icu/impl/data/HolidayBundle_el.java | 46 +- .../icu/impl/data/HolidayBundle_el_GR.java | 32 +- .../ibm/icu/impl/data/HolidayBundle_en.java | 9 +- .../icu/impl/data/HolidayBundle_en_CA.java | 39 +- .../icu/impl/data/HolidayBundle_en_GB.java | 28 +- .../icu/impl/data/HolidayBundle_en_US.java | 53 +- .../ibm/icu/impl/data/HolidayBundle_es.java | 72 +- .../icu/impl/data/HolidayBundle_es_MX.java | 34 +- .../ibm/icu/impl/data/HolidayBundle_fr.java | 58 +- .../icu/impl/data/HolidayBundle_fr_CA.java | 32 +- .../icu/impl/data/HolidayBundle_fr_FR.java | 24 +- .../ibm/icu/impl/data/HolidayBundle_it.java | 43 +- .../icu/impl/data/HolidayBundle_it_IT.java | 22 +- .../ibm/icu/impl/data/HolidayBundle_iw.java | 9 +- .../icu/impl/data/HolidayBundle_iw_IL.java | 14 +- .../icu/impl/data/HolidayBundle_ja_JP.java | 18 +- .../com/ibm/icu/impl/data/ResourceReader.java | 207 +- .../com/ibm/icu/impl/data/TokenIterator.java | 101 +- .../impl/duration/BasicDurationFormat.java | 112 +- .../impl/duration/BasicDurationFormatter.java | 193 +- .../BasicDurationFormatterFactory.java | 471 +- .../duration/BasicPeriodBuilderFactory.java | 924 +- .../impl/duration/BasicPeriodFormatter.java | 353 +- .../duration/BasicPeriodFormatterFactory.java | 430 +- .../duration/BasicPeriodFormatterService.java | 14 +- .../ibm/icu/impl/duration/DateFormatter.java | 70 +- .../icu/impl/duration/DurationFormatter.java | 119 +- .../duration/DurationFormatterFactory.java | 120 +- .../com/ibm/icu/impl/duration/Period.java | 683 +- .../ibm/icu/impl/duration/PeriodBuilder.java | 76 +- .../impl/duration/PeriodBuilderFactory.java | 235 +- .../icu/impl/duration/PeriodFormatter.java | 52 +- .../impl/duration/PeriodFormatterFactory.java | 116 +- .../impl/duration/PeriodFormatterService.java | 15 +- .../com/ibm/icu/impl/duration/TimeUnit.java | 160 +- .../icu/impl/duration/TimeUnitConstants.java | 46 +- .../icu/impl/duration/impl/DataRecord.java | 81 +- .../duration/impl/PeriodFormatterData.java | 1332 +- .../impl/PeriodFormatterDataService.java | 8 +- .../icu/impl/duration/impl/RecordReader.java | 43 +- .../icu/impl/duration/impl/RecordWriter.java | 43 +- ...sourceBasedPeriodFormatterDataService.java | 51 +- .../com/ibm/icu/impl/duration/impl/Utils.java | 401 +- .../impl/duration/impl/XMLRecordReader.java | 27 +- .../impl/duration/impl/XMLRecordWriter.java | 3 +- .../com/ibm/icu/impl/locale/AsciiUtil.java | 3 +- .../com/ibm/icu/impl/locale/BaseLocale.java | 53 +- .../com/ibm/icu/impl/locale/Extension.java | 1 - .../impl/locale/InternalLocaleBuilder.java | 71 +- .../com/ibm/icu/impl/locale/KeyTypeData.java | 152 +- .../java/com/ibm/icu/impl/locale/LSR.java | 96 +- .../com/ibm/icu/impl/locale/LanguageTag.java | 109 +- .../ibm/icu/impl/locale/LikelySubtags.java | 273 +- .../ibm/icu/impl/locale/LocaleDistance.java | 210 +- .../ibm/icu/impl/locale/LocaleExtensions.java | 30 +- .../icu/impl/locale/LocaleObjectCache.java | 6 +- .../impl/locale/LocaleValidityChecker.java | 188 +- .../icu/impl/locale/StringTokenIterator.java | 4 +- .../impl/locale/UnicodeLocaleExtension.java | 7 +- .../com/ibm/icu/impl/locale/XCldrStub.java | 146 +- .../impl/number/AdoptingModifierStore.java | 18 +- .../icu/impl/number/AffixPatternProvider.java | 10 +- .../com/ibm/icu/impl/number/AffixUtils.java | 606 +- .../com/ibm/icu/impl/number/CompactData.java | 33 +- .../impl/number/ConstantAffixModifier.java | 29 +- .../number/ConstantMultiFieldModifier.java | 27 +- .../CurrencyPluralInfoAffixProvider.java | 9 +- .../CurrencySpacingEnabledModifier.java | 31 +- .../icu/impl/number/CustomSymbolCurrency.java | 6 +- .../impl/number/DecimalFormatProperties.java | 559 +- .../ibm/icu/impl/number/DecimalQuantity.java | 184 +- .../number/DecimalQuantity_AbstractBCD.java | 375 +- .../DecimalQuantity_DualStorageBCD.java | 67 +- .../java/com/ibm/icu/impl/number/Grouper.java | 68 +- .../LocalizedNumberFormatterAsFormat.java | 36 +- .../ibm/icu/impl/number/LongNameHandler.java | 449 +- .../icu/impl/number/LongNameMultiplexer.java | 47 +- .../com/ibm/icu/impl/number/MacroProps.java | 77 +- .../com/ibm/icu/impl/number/MicroProps.java | 37 +- .../icu/impl/number/MicroPropsGenerator.java | 39 +- .../icu/impl/number/MicroPropsMutator.java | 2 - .../impl/number/MixedUnitLongNameHandler.java | 112 +- .../com/ibm/icu/impl/number/Modifier.java | 61 +- .../ibm/icu/impl/number/ModifierStore.java | 8 +- .../impl/number/MultiplierFormatHandler.java | 4 +- .../icu/impl/number/MultiplierProducer.java | 12 +- .../impl/number/MutablePatternModifier.java | 205 +- .../java/com/ibm/icu/impl/number/Padder.java | 58 +- .../icu/impl/number/PatternStringParser.java | 350 +- .../icu/impl/number/PatternStringUtils.java | 166 +- .../PropertiesAffixPatternProvider.java | 40 +- .../ibm/icu/impl/number/RoundingUtils.java | 234 +- .../ibm/icu/impl/number/SimpleModifier.java | 35 +- .../impl/number/UnitConversionHandler.java | 26 +- .../icu/impl/number/UsagePrefsHandler.java | 44 +- .../icu/impl/number/parse/AffixMatcher.java | 103 +- .../number/parse/AffixPatternMatcher.java | 72 +- .../impl/number/parse/CodePointMatcher.java | 1 - .../number/parse/CombinedCurrencyMatcher.java | 32 +- .../icu/impl/number/parse/DecimalMatcher.java | 31 +- .../impl/number/parse/IgnorablesMatcher.java | 13 +- .../impl/number/parse/InfinityMatcher.java | 1 - .../impl/number/parse/MinusSignMatcher.java | 4 +- .../number/parse/MultiplierParseHandler.java | 4 +- .../ibm/icu/impl/number/parse/NanMatcher.java | 2 - .../impl/number/parse/NumberParseMatcher.java | 62 +- .../impl/number/parse/NumberParserImpl.java | 89 +- .../icu/impl/number/parse/PaddingMatcher.java | 1 - .../icu/impl/number/parse/ParsedNumber.java | 85 +- .../icu/impl/number/parse/ParsingUtils.java | 4 +- .../icu/impl/number/parse/PercentMatcher.java | 1 - .../impl/number/parse/PermilleMatcher.java | 1 - .../impl/number/parse/PlusSignMatcher.java | 2 - .../number/parse/RequireAffixValidator.java | 2 - .../parse/RequireCurrencyValidator.java | 2 - .../RequireDecimalSeparatorValidator.java | 14 +- .../number/parse/RequireNumberValidator.java | 2 - .../impl/number/parse/ScientificMatcher.java | 19 +- .../icu/impl/number/parse/SeriesMatcher.java | 17 +- .../icu/impl/number/parse/SymbolMatcher.java | 3 +- .../impl/number/parse/ValidationMatcher.java | 5 +- .../range/PrefixInfixSuffixLengthHelper.java | 4 +- .../impl/number/range/RangeMacroProps.java | 19 +- .../number/range/StandardPluralRanges.java | 37 +- .../impl/personname/FieldModifierImpl.java | 115 +- .../personname/PersonNameFormatterImpl.java | 296 +- .../impl/personname/PersonNamePattern.java | 96 +- .../icu/impl/units/ComplexUnitsConverter.java | 196 +- .../ibm/icu/impl/units/ConversionRates.java | 98 +- .../ibm/icu/impl/units/MeasureUnitImpl.java | 215 +- .../ibm/icu/impl/units/SingleUnitImpl.java | 81 +- .../ibm/icu/impl/units/UnitPreferences.java | 79 +- .../ibm/icu/impl/units/UnitsConverter.java | 197 +- .../com/ibm/icu/impl/units/UnitsData.java | 74 +- .../com/ibm/icu/impl/units/UnitsRouter.java | 121 +- .../java/com/ibm/icu/lang/CharSequences.java | 145 +- .../com/ibm/icu/lang/CharacterProperties.java | 46 +- .../java/com/ibm/icu/lang/UCharacter.java | 6299 ++++-- .../com/ibm/icu/lang/UCharacterCategory.java | 170 +- .../com/ibm/icu/lang/UCharacterDirection.java | 80 +- .../com/ibm/icu/lang/UCharacterEnums.java | 370 +- .../ibm/icu/lang/UCharacterNameIterator.java | 292 +- .../main/java/com/ibm/icu/lang/UProperty.java | 842 +- .../main/java/com/ibm/icu/lang/UScript.java | 1499 +- .../java/com/ibm/icu/lang/UScriptRun.java | 326 +- .../java/com/ibm/icu/math/BigDecimal.java | 2504 ++- .../java/com/ibm/icu/math/MathContext.java | 1069 +- .../message2/DateTimeFormatterFactory.java | 41 +- .../com/ibm/icu/message2/Directionality.java | 9 +- .../ibm/icu/message2/FormattedMessage.java | 24 +- .../icu/message2/FormattedPlaceholder.java | 24 +- .../java/com/ibm/icu/message2/Formatter.java | 12 +- .../ibm/icu/message2/FormatterFactory.java | 10 +- .../message2/IdentityFormatterFactory.java | 21 +- .../com/ibm/icu/message2/MFDataModel.java | 15 +- .../icu/message2/MFDataModelFormatter.java | 74 +- .../icu/message2/MFDataModelValidator.java | 9 +- .../ibm/icu/message2/MFFunctionRegistry.java | 73 +- .../java/com/ibm/icu/message2/MFParser.java | 54 +- .../com/ibm/icu/message2/MFSerializer.java | 16 +- .../ibm/icu/message2/MessageFormatter.java | 205 +- .../icu/message2/NumberFormatterFactory.java | 51 +- .../java/com/ibm/icu/message2/OptUtils.java | 16 +- .../message2/PlainStringFormattedValue.java | 13 +- .../java/com/ibm/icu/message2/Selector.java | 15 +- .../com/ibm/icu/message2/SelectorFactory.java | 10 +- .../com/ibm/icu/message2/StringUtils.java | 4 +- .../ibm/icu/message2/TextSelectorFactory.java | 18 +- .../com/ibm/icu/number/CompactNotation.java | 30 +- .../com/ibm/icu/number/CurrencyPrecision.java | 25 +- .../com/ibm/icu/number/FormattedNumber.java | 28 +- .../ibm/icu/number/FormattedNumberRange.java | 54 +- .../com/ibm/icu/number/FractionPrecision.java | 92 +- .../java/com/ibm/icu/number/IntegerWidth.java | 33 +- .../icu/number/LocalizedNumberFormatter.java | 86 +- .../number/LocalizedNumberRangeFormatter.java | 42 +- .../java/com/ibm/icu/number/Notation.java | 86 +- .../com/ibm/icu/number/NumberFormatter.java | 322 +- .../ibm/icu/number/NumberFormatterImpl.java | 318 +- .../icu/number/NumberFormatterSettings.java | 474 +- .../ibm/icu/number/NumberPropertyMapper.java | 120 +- .../ibm/icu/number/NumberRangeFormatter.java | 109 +- .../icu/number/NumberRangeFormatterImpl.java | 257 +- .../number/NumberRangeFormatterSettings.java | 124 +- .../ibm/icu/number/NumberSkeletonImpl.java | 1024 +- .../java/com/ibm/icu/number/Precision.java | 350 +- .../main/java/com/ibm/icu/number/Scale.java | 27 +- .../ibm/icu/number/ScientificNotation.java | 72 +- .../com/ibm/icu/number/SimpleNotation.java | 11 +- .../icu/number/SkeletonSyntaxException.java | 6 +- .../number/UnlocalizedNumberFormatter.java | 21 +- .../UnlocalizedNumberRangeFormatter.java | 24 +- .../java/com/ibm/icu/text/ArabicShaping.java | 2223 +- .../ibm/icu/text/ArabicShapingException.java | 4 +- .../src/main/java/com/ibm/icu/text/Bidi.java | 5085 +++-- .../java/com/ibm/icu/text/BidiClassifier.java | 58 +- .../main/java/com/ibm/icu/text/BidiLine.java | 270 +- .../main/java/com/ibm/icu/text/BidiRun.java | 84 +- .../java/com/ibm/icu/text/BidiTransform.java | 482 +- .../java/com/ibm/icu/text/BidiWriter.java | 423 +- .../java/com/ibm/icu/text/BreakIterator.java | 777 +- .../ibm/icu/text/BreakIteratorFactory.java | 82 +- .../com/ibm/icu/text/CanonicalIterator.java | 168 +- .../main/java/com/ibm/icu/text/CaseMap.java | 373 +- .../com/ibm/icu/text/CharsetDetector.java | 465 +- .../java/com/ibm/icu/text/CharsetMatch.java | 139 +- .../com/ibm/icu/text/CharsetRecog_2022.java | 167 +- .../com/ibm/icu/text/CharsetRecog_UTF8.java | 48 +- .../ibm/icu/text/CharsetRecog_Unicode.java | 82 +- .../com/ibm/icu/text/CharsetRecog_mbcs.java | 894 +- .../com/ibm/icu/text/CharsetRecog_sbcs.java | 2701 ++- .../com/ibm/icu/text/CharsetRecognizer.java | 59 +- .../com/ibm/icu/text/ChineseDateFormat.java | 204 +- .../icu/text/ChineseDateFormatSymbols.java | 23 +- .../ibm/icu/text/CompactDecimalFormat.java | 166 +- .../com/ibm/icu/text/ComposedCharIter.java | 150 +- .../icu/text/ConstrainedFieldPosition.java | 140 +- .../ibm/icu/text/CurrencyDisplayNames.java | 133 +- .../java/com/ibm/icu/text/CurrencyFormat.java | 29 +- .../com/ibm/icu/text/CurrencyMetaInfo.java | 244 +- .../com/ibm/icu/text/CurrencyPluralInfo.java | 96 +- .../java/com/ibm/icu/text/DateFormat.java | 2044 +- .../com/ibm/icu/text/DateFormatSymbols.java | 1758 +- .../com/ibm/icu/text/DateIntervalFormat.java | 1611 +- .../com/ibm/icu/text/DateIntervalInfo.java | 688 +- .../icu/text/DateTimePatternGenerator.java | 1253 +- .../java/com/ibm/icu/text/DecimalFormat.java | 5017 ++--- .../ibm/icu/text/DecimalFormatSymbols.java | 813 +- .../java/com/ibm/icu/text/DisplayContext.java | 103 +- .../java/com/ibm/icu/text/DisplayOptions.java | 46 +- .../java/com/ibm/icu/text/DurationFormat.java | 68 +- .../src/main/java/com/ibm/icu/text/Edits.java | 473 +- .../text/FilteredBreakIteratorBuilder.java | 76 +- .../com/ibm/icu/text/FilteredNormalizer2.java | 192 +- .../java/com/ibm/icu/text/FormattedValue.java | 33 +- .../src/main/java/com/ibm/icu/text/IDNA.java | 954 +- .../java/com/ibm/icu/text/ListFormatter.java | 213 +- .../com/ibm/icu/text/LocaleDisplayNames.java | 227 +- .../java/com/ibm/icu/text/MeasureFormat.java | 402 +- .../java/com/ibm/icu/text/MessageFormat.java | 1890 +- .../java/com/ibm/icu/text/MessagePattern.java | 1241 +- .../com/ibm/icu/text/MessagePatternUtil.java | 228 +- .../main/java/com/ibm/icu/text/NFRule.java | 695 +- .../main/java/com/ibm/icu/text/NFRuleSet.java | 378 +- .../java/com/ibm/icu/text/NFSubstitution.java | 1225 +- .../java/com/ibm/icu/text/Normalizer.java | 1985 +- .../java/com/ibm/icu/text/Normalizer2.java | 428 +- .../java/com/ibm/icu/text/NumberFormat.java | 1465 +- .../ibm/icu/text/NumberFormatServiceShim.java | 43 +- .../com/ibm/icu/text/NumberingSystem.java | 215 +- .../java/com/ibm/icu/text/PersonName.java | 161 +- .../com/ibm/icu/text/PersonNameFormatter.java | 165 +- .../java/com/ibm/icu/text/PluralFormat.java | 582 +- .../java/com/ibm/icu/text/PluralRules.java | 1024 +- .../ibm/icu/text/PluralRulesSerialProxy.java | 4 +- .../java/com/ibm/icu/text/Quantifier.java | 37 +- .../com/ibm/icu/text/QuantityFormatter.java | 55 +- .../main/java/com/ibm/icu/text/RBBINode.java | 272 +- .../com/ibm/icu/text/RBBIRuleBuilder.java | 222 +- .../com/ibm/icu/text/RBBIRuleParseTable.java | 452 +- .../com/ibm/icu/text/RBBIRuleScanner.java | 990 +- .../java/com/ibm/icu/text/RBBISetBuilder.java | 447 +- .../com/ibm/icu/text/RBBISymbolTable.java | 42 +- .../com/ibm/icu/text/RBBITableBuilder.java | 2743 ++- .../icu/text/RBNFChinesePostProcessor.java | 139 +- .../com/ibm/icu/text/RBNFPostProcessor.java | 14 +- .../com/ibm/icu/text/RbnfLenientScanner.java | 31 +- .../icu/text/RbnfLenientScannerProvider.java | 4 +- .../icu/text/RelativeDateTimeFormatter.java | 849 +- .../java/com/ibm/icu/text/Replaceable.java | 158 +- .../icu/text/ReplaceableContextIterator.java | 166 +- .../com/ibm/icu/text/ReplaceableString.java | 94 +- .../ibm/icu/text/RuleBasedBreakIterator.java | 1959 +- .../ibm/icu/text/RuleBasedNumberFormat.java | 1015 +- .../src/main/java/com/ibm/icu/text/SCSU.java | 505 +- .../icu/text/ScientificNumberFormatter.java | 264 +- .../java/com/ibm/icu/text/SelectFormat.java | 251 +- .../com/ibm/icu/text/SimpleDateFormat.java | 4101 ++-- .../com/ibm/icu/text/SimpleFormatter.java | 60 +- .../com/ibm/icu/text/SimplePersonName.java | 103 +- .../java/com/ibm/icu/text/SpoofChecker.java | 935 +- .../ibm/icu/text/StringCharacterIterator.java | 147 +- .../java/com/ibm/icu/text/StringPrep.java | 484 +- .../icu/text/StringPrepParseException.java | 161 +- .../com/ibm/icu/text/StringTransform.java | 8 +- .../java/com/ibm/icu/text/SymbolTable.java | 79 +- .../java/com/ibm/icu/text/TimeUnitFormat.java | 153 +- .../java/com/ibm/icu/text/TimeZoneFormat.java | 1581 +- .../java/com/ibm/icu/text/TimeZoneNames.java | 301 +- .../main/java/com/ibm/icu/text/Transform.java | 10 +- .../com/ibm/icu/text/UCharacterIterator.java | 166 +- .../java/com/ibm/icu/text/UFieldPosition.java | 3 +- .../main/java/com/ibm/icu/text/UFormat.java | 70 +- .../icu/text/UForwardCharacterIterator.java | 92 +- .../src/main/java/com/ibm/icu/text/UTF16.java | 839 +- .../com/ibm/icu/text/UnicodeCompressor.java | 2056 +- .../com/ibm/icu/text/UnicodeDecompressor.java | 1174 +- .../java/com/ibm/icu/text/UnicodeFilter.java | 36 +- .../java/com/ibm/icu/text/UnicodeMatcher.java | 137 +- .../com/ibm/icu/text/UnicodeReplacer.java | 66 +- .../java/com/ibm/icu/text/UnicodeSet.java | 2579 +-- .../com/ibm/icu/text/UnicodeSetIterator.java | 127 +- .../com/ibm/icu/text/UnicodeSetSpanner.java | 309 +- .../com/ibm/icu/util/AnnualTimeZoneRule.java | 101 +- .../java/com/ibm/icu/util/BasicTimeZone.java | 460 +- .../com/ibm/icu/util/BuddhistCalendar.java | 150 +- .../com/ibm/icu/util/ByteArrayWrapper.java | 128 +- .../main/java/com/ibm/icu/util/BytesTrie.java | 911 +- .../com/ibm/icu/util/BytesTrieBuilder.java | 264 +- .../java/com/ibm/icu/util/CECalendar.java | 290 +- .../main/java/com/ibm/icu/util/Calendar.java | 5451 +++-- .../ibm/icu/util/CaseInsensitiveString.java | 26 +- .../main/java/com/ibm/icu/util/CharsTrie.java | 828 +- .../com/ibm/icu/util/CharsTrieBuilder.java | 216 +- .../com/ibm/icu/util/ChineseCalendar.java | 1007 +- .../java/com/ibm/icu/util/CodePointMap.java | 216 +- .../java/com/ibm/icu/util/CodePointTrie.java | 584 +- .../com/ibm/icu/util/CompactByteArray.java | 201 +- .../com/ibm/icu/util/CompactCharArray.java | 208 +- .../java/com/ibm/icu/util/CopticCalendar.java | 138 +- .../main/java/com/ibm/icu/util/Currency.java | 552 +- .../java/com/ibm/icu/util/CurrencyAmount.java | 28 +- .../com/ibm/icu/util/CurrencyServiceShim.java | 29 +- .../java/com/ibm/icu/util/DangiCalendar.java | 108 +- .../java/com/ibm/icu/util/DateInterval.java | 41 +- .../main/java/com/ibm/icu/util/DateRule.java | 61 +- .../java/com/ibm/icu/util/DateTimeRule.java | 185 +- .../java/com/ibm/icu/util/EasterHoliday.java | 176 +- .../com/ibm/icu/util/EthiopicCalendar.java | 126 +- .../main/java/com/ibm/icu/util/Freezable.java | 346 +- .../java/com/ibm/icu/util/GenderInfo.java | 132 +- .../com/ibm/icu/util/GregorianCalendar.java | 738 +- .../java/com/ibm/icu/util/HebrewCalendar.java | 837 +- .../java/com/ibm/icu/util/HebrewHoliday.java | 80 +- .../main/java/com/ibm/icu/util/Holiday.java | 118 +- .../util/ICUCloneNotSupportedException.java | 8 +- .../java/com/ibm/icu/util/ICUException.java | 3 +- .../icu/util/ICUInputTooLongException.java | 8 +- .../ibm/icu/util/ICUUncheckedIOException.java | 13 +- .../icu/util/IllformedLocaleException.java | 26 +- .../java/com/ibm/icu/util/IndianCalendar.java | 512 +- .../com/ibm/icu/util/InitialTimeZoneRule.java | 41 +- .../com/ibm/icu/util/IslamicCalendar.java | 1389 +- .../com/ibm/icu/util/JapaneseCalendar.java | 315 +- .../java/com/ibm/icu/util/LocaleData.java | 296 +- .../java/com/ibm/icu/util/LocaleMatcher.java | 502 +- .../com/ibm/icu/util/LocalePriorityList.java | 116 +- .../main/java/com/ibm/icu/util/Measure.java | 44 +- .../java/com/ibm/icu/util/MeasureUnit.java | 1072 +- .../ibm/icu/util/MutableCodePointTrie.java | 476 +- .../main/java/com/ibm/icu/util/NoUnit.java | 13 +- .../main/java/com/ibm/icu/util/Output.java | 9 +- .../main/java/com/ibm/icu/util/OutputInt.java | 11 +- .../com/ibm/icu/util/PersianCalendar.java | 373 +- .../java/com/ibm/icu/util/RangeDateRule.java | 52 +- .../com/ibm/icu/util/RangeValueIterator.java | 121 +- .../main/java/com/ibm/icu/util/Region.java | 384 +- .../com/ibm/icu/util/RuleBasedTimeZone.java | 267 +- .../main/java/com/ibm/icu/util/STZInfo.java | 5 +- .../java/com/ibm/icu/util/SimpleDateRule.java | 144 +- .../java/com/ibm/icu/util/SimpleHoliday.java | 180 +- .../java/com/ibm/icu/util/SimpleTimeZone.java | 1350 +- .../com/ibm/icu/util/StringTokenizer.java | 579 +- .../com/ibm/icu/util/StringTrieBuilder.java | 700 +- .../java/com/ibm/icu/util/TaiwanCalendar.java | 136 +- .../ibm/icu/util/TimeArrayTimeZoneRule.java | 62 +- .../main/java/com/ibm/icu/util/TimeUnit.java | 44 +- .../java/com/ibm/icu/util/TimeUnitAmount.java | 5 + .../main/java/com/ibm/icu/util/TimeZone.java | 961 +- .../java/com/ibm/icu/util/TimeZoneRule.java | 105 +- .../com/ibm/icu/util/TimeZoneTransition.java | 24 +- .../main/java/com/ibm/icu/util/ULocale.java | 2230 +- .../com/ibm/icu/util/UResourceBundle.java | 476 +- .../ibm/icu/util/UResourceBundleIterator.java | 62 +- .../util/UResourceTypeMismatchException.java | 21 +- .../com/ibm/icu/util/UniversalTimeScale.java | 665 +- .../main/java/com/ibm/icu/util/VTimeZone.java | 1148 +- .../java/com/ibm/icu/util/ValueIterator.java | 116 +- .../java/com/ibm/icu/util/VersionInfo.java | 362 +- .../dev/data/TestDataElements_testtypes.java | 214 +- .../dev/data/resources/TestDataElements.java | 41 +- .../TestDataElements_en_Latn_US.java | 23 +- .../resources/TestDataElements_en_US.java | 21 +- .../TestDataElements_fr_Latn_FR.java | 22 +- .../data/resources/TestDataElements_te.java | 22 +- .../icu/dev/data/resources/TestMessages.java | 5 +- .../impl/number/DecimalQuantity_64BitBCD.java | 352 +- .../number/DecimalQuantity_ByteArrayBCD.java | 457 +- .../number/DecimalQuantity_SimpleStorage.java | 1904 +- .../com/ibm/icu/dev/test/CoreTestFmwk.java | 106 +- .../java/com/ibm/icu/dev/test/ModuleTest.java | 54 +- .../com/ibm/icu/dev/test/ResourceModule.java | 354 +- .../com/ibm/icu/dev/test/TestBoilerplate.java | 95 +- .../com/ibm/icu/dev/test/TestDataModule.java | 94 +- .../icu/dev/test/TestUnicodeKnownIssues.java | 7 +- .../dev/test/UnicodeMapBoilerplateTest.java | 14 +- .../com/ibm/icu/dev/test/UnicodeMapTest.java | 345 +- .../dev/test/UnicodeSetBoilerplateTest.java | 15 +- .../dev/test/bidi/BiDiConformanceTest.java | 430 +- .../com/ibm/icu/dev/test/bidi/BidiFmwk.java | 297 +- .../com/ibm/icu/dev/test/bidi/TestBidi.java | 436 +- .../icu/dev/test/bidi/TestBidiTransform.java | 478 +- .../dev/test/bidi/TestCharFromDirProp.java | 24 +- .../icu/dev/test/bidi/TestClassOverride.java | 213 +- .../icu/dev/test/bidi/TestCompatibility.java | 324 +- .../ibm/icu/dev/test/bidi/TestContext.java | 95 +- .../com/ibm/icu/dev/test/bidi/TestData.java | 446 +- .../dev/test/bidi/TestFailureRecovery.java | 59 +- .../ibm/icu/dev/test/bidi/TestInverse.java | 137 +- .../dev/test/bidi/TestMultipleParagraphs.java | 310 +- .../ibm/icu/dev/test/bidi/TestReorder.java | 186 +- .../bidi/TestReorderArabicMathSymbols.java | 176 +- .../dev/test/bidi/TestReorderRunsOnly.java | 256 +- .../icu/dev/test/bidi/TestReorderingMode.java | 932 +- .../ibm/icu/dev/test/bidi/TestStreaming.java | 95 +- .../dev/test/bigdec/DiagBigDecimalTest.java | 17586 +++++++++++++--- .../ibm/icu/dev/test/calendar/AstroTest.java | 216 +- .../test/calendar/CalendarRegressionTest.java | 1968 +- .../dev/test/calendar/CalendarTestFmwk.java | 447 +- .../icu/dev/test/calendar/ChineseTest.java | 728 +- .../dev/test/calendar/ChineseTestCase.java | 61 +- .../dev/test/calendar/CompatibilityTest.java | 869 +- .../ibm/icu/dev/test/calendar/CopticTest.java | 333 +- .../ibm/icu/dev/test/calendar/DangiTest.java | 399 +- .../icu/dev/test/calendar/EraRulesTest.java | 29 +- .../icu/dev/test/calendar/EthiopicTest.java | 369 +- .../ibm/icu/dev/test/calendar/HebrewTest.java | 698 +- .../icu/dev/test/calendar/HolidayTest.java | 168 +- .../dev/test/calendar/IBMCalendarTest.java | 2631 ++- .../test/calendar/InTemporalLeapYearTest.java | 148 +- .../ibm/icu/dev/test/calendar/IndianTest.java | 205 +- .../icu/dev/test/calendar/IslamicTest.java | 1384 +- .../icu/dev/test/calendar/JapaneseTest.java | 329 +- .../dev/test/calendar/OrdinalMonthTest.java | 461 +- .../icu/dev/test/calendar/PersianTest.java | 151 +- .../test/calendar/TemporalMonthCodeTest.java | 330 +- .../ibm/icu/dev/test/calendar/TestCase.java | 213 +- .../test/charsetdet/TestCharsetDetector.java | 1396 +- .../test/compression/DecompressionTest.java | 437 +- .../dev/test/compression/ExhaustiveTest.java | 582 +- .../dev/test/duration/DataReadWriteTest.java | 121 +- .../dev/test/duration/ICUDurationTest.java | 214 +- .../dev/test/duration/LanguageTestFmwk.java | 384 +- .../duration/PeriodBuilderFactoryTest.java | 36 +- .../ibm/icu/dev/test/duration/PeriodTest.java | 20 +- .../icu/dev/test/duration/RegressionTest.java | 50 +- ...ceBasedPeriodFormatterDataServiceTest.java | 33 +- .../test/duration/languages/Test_ar_EG.java | 21 +- .../dev/test/duration/languages/Test_en.java | 20 +- .../dev/test/duration/languages/Test_es.java | 20 +- .../dev/test/duration/languages/Test_fr.java | 20 +- .../test/duration/languages/Test_he_IL.java | 21 +- .../dev/test/duration/languages/Test_hi.java | 83 +- .../dev/test/duration/languages/Test_it.java | 20 +- .../dev/test/duration/languages/Test_ja.java | 94 +- .../dev/test/duration/languages/Test_ko.java | 20 +- .../dev/test/duration/languages/Test_ru.java | 21 +- .../test/duration/languages/Test_zh_Hans.java | 21 +- .../duration/languages/Test_zh_Hans_SG.java | 20 +- .../test/duration/languages/Test_zh_Hant.java | 22 +- .../duration/languages/Test_zh_Hant_HK.java | 21 +- .../dev/test/format/BigNumberFormatTest.java | 378 +- .../DataDrivenNumberFormatTestData.java | 119 +- .../DataDrivenNumberFormatTestUtility.java | 135 +- .../dev/test/format/DateFormatMiscTests.java | 41 +- .../test/format/DateFormatRegressionTest.java | 897 +- .../format/DateFormatRegressionTestJ.java | 139 +- .../test/format/DateFormatRoundTripTest.java | 104 +- .../test/format/DateIntervalFormatTest.java | 4641 ++-- .../test/format/DateTimeGeneratorTest.java | 1980 +- .../format/FormattedStringBuilderTest.java | 49 +- .../dev/test/format/FormattedValueTest.java | 170 +- .../dev/test/format/IntlTestDateFormat.java | 119 +- .../test/format/IntlTestDateFormatAPI.java | 109 +- .../test/format/IntlTestDateFormatAPIC.java | 30 +- .../format/IntlTestDateFormatSymbols.java | 571 +- .../test/format/IntlTestDecimalFormatAPI.java | 216 +- .../format/IntlTestDecimalFormatSymbols.java | 175 +- .../dev/test/format/IntlTestNumberFormat.java | 149 +- .../test/format/IntlTestNumberFormatAPI.java | 160 +- .../format/IntlTestSimpleDateFormatAPI.java | 108 +- .../test/format/JavaTimeConvertersTest.java | 66 +- .../dev/test/format/JavaTimeFormatTest.java | 180 +- .../dev/test/format/ListFormatterTest.java | 364 +- .../test/format/MeasureUnitThreadTest.java | 46 +- .../test/format/MessagePatternUtilTest.java | 526 +- .../test/format/MessageRegressionTest.java | 733 +- .../NumberFormatJavaCompatilityTest.java | 36 +- .../format/NumberFormatRegistrationTest.java | 19 +- .../format/NumberFormatRoundTripTest.java | 88 +- .../format/NumberFormatSerialTestData.java | 1148 +- .../format/PersonNameConsistencyTest.java | 65 +- .../test/format/PersonNameFormatterTest.java | 2268 +- .../icu/dev/test/format/PluralFormatTest.java | 497 +- .../dev/test/format/PluralFormatUnitTest.java | 182 +- .../dev/test/format/PluralRulesFactory.java | 4 +- .../icu/dev/test/format/RBNFParseTest.java | 45 +- .../dev/test/format/RbnfRoundTripTest.java | 164 +- .../format/RelativeDateTimeFormatterTest.java | 2291 +- .../format/ScientificNumberFormatterTest.java | 66 +- .../dev/test/format/SelectFormatAPITest.java | 152 +- .../dev/test/format/SelectFormatUnitTest.java | 102 +- .../ibm/icu/dev/test/format/TimeUnitTest.java | 298 +- .../WriteNumberFormatSerialTestData.java | 117 +- .../test/impl/CSCharacterIteratorTest.java | 15 +- .../com/ibm/icu/dev/test/impl/CacheTest.java | 21 +- .../icu/dev/test/impl/StringSegmentTest.java | 4 +- .../com/ibm/icu/dev/test/impl/UnitsTest.java | 1027 +- .../test/iterator/TestUCharacterIterator.java | 516 +- .../dev/test/lang/DataDrivenUScriptTest.java | 393 +- .../ibm/icu/dev/test/lang/TestUScript.java | 738 +- .../ibm/icu/dev/test/lang/TestUScriptRun.java | 151 +- .../icu/dev/test/lang/UCharacterCaseTest.java | 1661 +- .../dev/test/lang/UCharacterCategoryTest.java | 118 +- .../icu/dev/test/lang/UCharacterCompare.java | 335 +- .../test/lang/UCharacterDirectionTest.java | 106 +- .../test/lang/UCharacterSurrogateTest.java | 350 +- .../ibm/icu/dev/test/lang/UCharacterTest.java | 4761 +++-- .../dev/test/lang/UCharacterThreadTest.java | 58 +- .../dev/test/lang/UPropertyAliasesTest.java | 103 +- .../com/ibm/icu/dev/test/lang/UTF16Test.java | 1977 +- .../test/lang/UnicodeSetStringSpanTest.java | 885 +- .../ibm/icu/dev/test/lang/UnicodeSetTest.java | 2287 +- .../com/ibm/icu/dev/test/message2/Args.java | 170 +- .../ibm/icu/dev/test/message2/CoreTest.java | 80 +- .../CustomFormatterGrammarCaseTest.java | 88 +- .../message2/CustomFormatterListTest.java | 64 +- .../CustomFormatterMessageRefTest.java | 83 +- .../message2/CustomFormatterPersonTest.java | 299 +- .../ibm/icu/dev/test/message2/ExpErrors.java | 2 +- .../test/message2/ExpectedErrorAdapter.java | 8 +- .../ibm/icu/dev/test/message2/MF2Test.java | 3 +- .../dev/test/message2/MessageFormat2Test.java | 720 +- .../ibm/icu/dev/test/message2/Mf2IcuTest.java | 211 +- .../com/ibm/icu/dev/test/message2/Param.java | 6 +- .../dev/test/message2/ParserSmokeTest.java | 5 +- .../dev/test/message2/SerializationTest.java | 7 +- .../test/message2/StringToListAdapter.java | 6 +- .../ibm/icu/dev/test/message2/TestCase.java | 7 +- .../test/message2/TestFunctionFactory.java | 36 +- .../ibm/icu/dev/test/message2/TestUtils.java | 105 +- .../com/ibm/icu/dev/test/message2/Unit.java | 40 +- .../dev/test/normalizer/ConformanceTest.java | 402 +- .../icu/dev/test/normalizer/IntHashtable.java | 14 +- .../test/normalizer/IntStringHashtable.java | 14 +- .../dev/test/normalizer/LongHashtable.java | 14 +- .../normalizer/NormalizationMonkeyTest.java | 56 +- .../test/normalizer/NormalizerBuilder.java | 277 +- .../dev/test/normalizer/NormalizerData.java | 119 +- .../normalizer/NormalizerRegressionTests.java | 5 +- .../normalizer/TestCanonicalIterator.java | 125 +- .../TestDeprecatedNormalizerAPI.java | 113 +- .../icu/dev/test/normalizer/UTS46Test.java | 1419 +- .../test/normalizer/UnicodeNormalizer.java | 114 +- .../UnicodeNormalizerConformanceTest.java | 158 +- .../icu/dev/test/number/AffixUtilsTest.java | 233 +- .../dev/test/number/DecimalQuantityTest.java | 647 +- .../dev/test/number/ExhaustiveNumberTest.java | 130 +- .../number/MutablePatternModifierTest.java | 12 +- .../dev/test/number/NumberSkeletonTest.java | 618 +- .../test/rbbi/AbstractBreakIteratorTests.java | 17 +- .../dev/test/rbbi/BreakIteratorRegTest.java | 190 +- .../rbbi/BreakIteratorRules_en_US_TEST.java | 322 +- .../icu/dev/test/rbbi/BreakIteratorTest.java | 322 +- .../ibm/icu/dev/test/rbbi/RBBIAPITest.java | 300 +- .../ibm/icu/dev/test/rbbi/RBBILSTMTest.java | 40 +- .../ibm/icu/dev/test/rbbi/RBBIMonkeyTest.java | 609 +- .../com/ibm/icu/dev/test/rbbi/RBBITest.java | 830 +- .../icu/dev/test/rbbi/RBBITestExtended.java | 1156 +- .../ibm/icu/dev/test/rbbi/RBBITestMonkey.java | 1549 +- .../ibm/icu/dev/test/rbbi/RBBITstUtils.java | 5 +- .../com/ibm/icu/dev/test/rbbi/RegexRule.java | 55 +- .../com/ibm/icu/dev/test/rbbi/RemapRule.java | 57 +- .../icu/dev/test/rbbi/SegmentationRule.java | 22 +- .../test/shaping/ArabicShapingRegTest.java | 262 +- .../DataDrivenArabicShapingRegTest.java | 697 +- .../test/stringprep/IDNAConformanceTest.java | 164 +- .../dev/test/stringprep/IDNAReference.java | 330 +- .../dev/test/stringprep/NFS4StringPrep.java | 149 +- .../test/stringprep/NamePrepTransform.java | 158 +- .../test/stringprep/PunycodeReference.java | 452 +- .../ibm/icu/dev/test/stringprep/TestData.java | 920 +- .../ibm/icu/dev/test/stringprep/TestIDNA.java | 1297 +- .../stringprep/TestInputDataStructure.java | 32 +- .../stringprep/TestStringPrepProfiles.java | 70 +- .../icu/dev/test/text/DisplayOptionsTest.java | 467 +- .../icu/dev/test/text/SpoofCheckerTest.java | 482 +- .../dev/test/timescale/TimeScaleAPITest.java | 103 +- .../dev/test/timescale/TimeScaleDataTest.java | 172 +- .../test/timescale/TimeScaleMonkeyTest.java | 49 +- .../dev/test/timezone/TimeZoneAliasTest.java | 202 +- .../test/timezone/TimeZoneBoundaryTest.java | 775 +- .../timezone/TimeZoneOffsetLocalTest.java | 313 +- .../test/timezone/TimeZoneRegressionTest.java | 1141 +- .../dev/test/timezone/TimeZoneRuleTest.java | 1250 +- .../icu/dev/test/timezone/TimeZoneTest.java | 2042 +- .../ibm/icu/dev/test/util/BytesTrieTest.java | 642 +- .../icu/dev/test/util/CalendarFieldsSet.java | 21 +- .../ibm/icu/dev/test/util/CharsTrieTest.java | 786 +- .../icu/dev/test/util/CodePointTrieTest.java | 856 +- .../icu/dev/test/util/CompactArrayTest.java | 242 +- .../dev/test/util/DataDrivenTestHelper.java | 49 +- .../icu/dev/test/util/DateTimeStyleSet.java | 31 +- .../ibm/icu/dev/test/util/DebugUtilities.java | 23 +- .../icu/dev/test/util/DebugUtilitiesData.java | 262 +- .../icu/dev/test/util/DebugUtilitiesTest.java | 76 +- .../icu/dev/test/util/DisplayNameTest.java | 225 +- .../com/ibm/icu/dev/test/util/Equator.java | 19 +- .../com/ibm/icu/dev/test/util/FieldsSet.java | 159 +- .../ibm/icu/dev/test/util/GenderInfoTest.java | 22 +- .../ibm/icu/dev/test/util/ICUBinaryTest.java | 71 +- .../dev/test/util/ICUServiceTestSample.java | 166 +- .../dev/test/util/ICUServiceThreadTest.java | 137 +- .../icu/dev/test/util/LocaleBuilderTest.java | 333 +- .../icu/dev/test/util/LocaleDistanceTest.java | 111 +- .../icu/dev/test/util/LocaleMatcherTest.java | 620 +- .../dev/test/util/LocalePriorityListTest.java | 35 +- .../com/ibm/icu/dev/test/util/RegionTest.java | 961 +- .../dev/test/util/SimpleFormatterTest.java | 472 +- .../dev/test/util/StaticUnicodeSetsTest.java | 3 +- .../dev/test/util/StringTokenizerTest.java | 1217 +- .../icu/dev/test/util/TestLocaleValidity.java | 399 +- .../icu/dev/test/util/TextTrieMapTest.java | 39 +- .../com/ibm/icu/dev/test/util/Trie2Test.java | 1486 +- .../com/ibm/icu/dev/test/util/TrieMap.java | 114 +- .../ibm/icu/dev/test/util/TrieMapTest.java | 404 +- .../com/ibm/icu/dev/test/util/TrieTest.java | 535 +- .../ibm/icu/dev/test/util/UtilityTest.java | 175 +- .../icu/dev/test/util/VersionInfoTest.java | 312 +- .../tool/locale/LocaleDistanceBuilder.java | 270 +- .../impl/ICUCurrencyDisplayInfoProvider.java | 159 +- .../com/ibm/icu/impl/ICUCurrencyMetaInfo.java | 40 +- .../com/ibm/icu/dev/test/AbstractTestLog.java | 62 +- .../java/com/ibm/icu/dev/test/TestFmwk.java | 366 +- .../java/com/ibm/icu/dev/test/TestLog.java | 50 +- .../java/com/ibm/icu/dev/test/TestUtil.java | 104 +- .../java/com/ibm/icu/dev/test/UTF16Util.java | 279 +- .../ibm/icu/dev/test/UnicodeKnownIssues.java | 69 +- .../test/java/com/ibm/icu/dev/util/Timer.java | 26 +- .../icu/impl/icuadapter/NumberFormatJDK.java | 91 +- .../ibm/icu/impl/icuadapter/TimeZoneJDK.java | 59 +- .../javaspi/ICULocaleServiceProvider.java | 48 +- .../text/BreakIteratorProviderICU.java | 26 +- .../javaspi/text/CollatorProviderICU.java | 11 +- .../javaspi/text/DateFormatProviderICU.java | 9 +- .../text/DateFormatSymbolsProviderICU.java | 11 +- .../text/DecimalFormatSymbolsProviderICU.java | 14 +- .../javaspi/text/NumberFormatProviderICU.java | 45 +- .../javaspi/util/CurrencyNameProviderICU.java | 14 +- .../javaspi/util/LocaleNameProviderICU.java | 29 +- .../javaspi/util/TimeZoneNameProviderICU.java | 54 +- .../icu/impl/jdkadapter/BreakIteratorICU.java | 12 +- .../ibm/icu/impl/jdkadapter/CalendarICU.java | 88 +- .../icu/impl/jdkadapter/CollationKeyICU.java | 8 +- .../ibm/icu/impl/jdkadapter/CollatorICU.java | 122 +- .../impl/jdkadapter/DateFormatSymbolsICU.java | 14 +- .../icu/impl/jdkadapter/DecimalFormatICU.java | 87 +- .../jdkadapter/DecimalFormatSymbolsICU.java | 13 +- .../icu/impl/jdkadapter/NumberFormatICU.java | 71 +- .../impl/jdkadapter/SimpleDateFormatICU.java | 55 +- .../ibm/icu/impl/jdkadapter/TimeZoneICU.java | 21 +- .../dev/test/localespi/BreakIteratorTest.java | 192 +- .../icu/dev/test/localespi/CollatorTest.java | 82 +- .../dev/test/localespi/CurrencyNameTest.java | 124 +- .../test/localespi/DateFormatSymbolsTest.java | 123 +- .../dev/test/localespi/DateFormatTest.java | 104 +- .../localespi/DecimalFormatSymbolsTest.java | 135 +- .../dev/test/localespi/LocaleNameTest.java | 188 +- .../dev/test/localespi/NumberFormatTest.java | 283 +- .../ibm/icu/dev/test/localespi/TestUtil.java | 5 +- .../dev/test/localespi/TimeZoneNameTest.java | 187 +- .../com/ibm/icu/impl/UtilityExtensions.java | 125 +- .../com/ibm/icu/text/AnyTransliterator.java | 204 +- .../com/ibm/icu/text/BreakTransliterator.java | 267 +- .../ibm/icu/text/CaseFoldTransliterator.java | 87 +- .../ibm/icu/text/CompoundTransliterator.java | 293 +- .../ibm/icu/text/EscapeTransliterator.java | 247 +- .../com/ibm/icu/text/FunctionReplacer.java | 59 +- .../ibm/icu/text/LowercaseTransliterator.java | 85 +- .../icu/text/NameUnicodeTransliterator.java | 215 +- .../icu/text/NormalizationTransliterator.java | 131 +- .../com/ibm/icu/text/NullTransliterator.java | 25 +- .../ibm/icu/text/RemoveTransliterator.java | 42 +- .../ibm/icu/text/RuleBasedTransliterator.java | 187 +- .../com/ibm/icu/text/SourceTargetUtility.java | 77 +- .../java/com/ibm/icu/text/StringMatcher.java | 169 +- .../java/com/ibm/icu/text/StringReplacer.java | 167 +- .../ibm/icu/text/TitlecaseTransliterator.java | 98 +- .../com/ibm/icu/text/TransliterationRule.java | 306 +- .../ibm/icu/text/TransliterationRuleSet.java | 137 +- .../java/com/ibm/icu/text/Transliterator.java | 1730 +- .../ibm/icu/text/TransliteratorIDParser.java | 375 +- .../ibm/icu/text/TransliteratorParser.java | 1175 +- .../ibm/icu/text/TransliteratorRegistry.java | 458 +- .../ibm/icu/text/UnescapeTransliterator.java | 214 +- .../icu/text/UnicodeNameTransliterator.java | 64 +- .../ibm/icu/text/UppercaseTransliterator.java | 83 +- .../icu/dev/test/translit/AnyScriptTest.java | 57 +- .../translit/CompoundTransliteratorTest.java | 292 +- .../ibm/icu/dev/test/translit/ErrorTest.java | 144 +- .../translit/IncrementalProgressTest.java | 39 +- .../ibm/icu/dev/test/translit/JamoTest.java | 528 +- .../dev/test/translit/RegexUtilitiesTest.java | 150 +- .../dev/test/translit/ReplaceableTest.java | 76 +- .../icu/dev/test/translit/RoundTripTest.java | 1618 +- .../icu/dev/test/translit/TestUtility.java | 783 +- .../ibm/icu/dev/test/translit/ThreadTest.java | 33 +- .../TransliteratorDisorderedMarksTest.java | 77 +- .../TransliteratorInstantiateAllTest.java | 19 +- .../dev/test/translit/TransliteratorTest.java | 3807 ++-- .../icu/dev/test/translit/WriteCharts.java | 356 +- .../perf/BreakIteratorPerformanceTest.java | 57 +- .../test/perf/CollationPerformanceTest.java | 979 +- .../test/perf/ConverterPerformanceTest.java | 294 +- .../test/perf/DateFormatPerformanceTest.java | 6 +- .../perf/DecimalFormatPerformanceTest.java | 18 +- .../test/perf/NormalizerPerformanceTest.java | 211 +- .../com/ibm/icu/dev/test/perf/PerfTest.java | 627 +- .../com/ibm/icu/dev/test/perf/RBBIPerf.java | 90 +- .../icu/dev/test/perf/ResourceBundlePerf.java | 245 +- .../test/perf/ServiceObjectCreationPerf.java | 14 +- .../ibm/icu/dev/test/perf/UCharacterPerf.java | 284 +- .../ibm/icu/dev/test/perf/UnicodeSetPerf.java | 18 +- .../ibm/icu/samples/iuc/PopulationData.java | 60 +- .../ibm/icu/samples/iuc/Sample13_Hello.java | 8 +- .../icu/samples/iuc/Sample30_ResHello.java | 9 +- .../ibm/icu/samples/iuc/Sample40_PopMsg.java | 34 +- .../ibm/icu/samples/iuc/Sample50_PopSort.java | 55 +- .../samples/iuc/SupplementalUtilities.java | 81 +- .../com/ibm/icu/samples/iuc/package-info.java | 4 +- .../samples/shaping/ArabicShapingSample.java | 110 +- .../DateIntervalFormatSample.java | 167 +- .../DateTimePatternGeneratorSample.java | 211 +- .../messagepattern/MessagePatternDemo.java | 117 +- .../MessagePatternUtilDemo.java | 412 +- .../messagepattern/MiniMessageFormatter.java | 140 +- .../text/pluralformat/PluralFormatSample.java | 158 +- .../icu/samples/util/timescale/PivotDemo.java | 75 +- .../util/timezone/BasicTimeZoneExample.java | 84 +- .../dev/tool/coverage/JacocoReportCheck.java | 80 +- .../com/ibm/icu/dev/tool/docs/APIData.java | 37 +- .../com/ibm/icu/dev/tool/docs/APIInfo.java | 741 +- .../docs/APIStatusConsistencyChecker.java | 37 +- .../com/ibm/icu/dev/tool/docs/CheckTags.java | 200 +- .../ibm/icu/dev/tool/docs/CodeMangler.java | 562 +- .../com/ibm/icu/dev/tool/docs/CollectAPI.java | 41 +- .../dev/tool/docs/DeprecatedAPIChecker.java | 114 +- .../com/ibm/icu/dev/tool/docs/Deprecator.java | 48 +- .../ibm/icu/dev/tool/docs/GatherAPIData.java | 138 +- .../ibm/icu/dev/tool/docs/ICUJDKCompare.java | 168 +- .../ibm/icu/dev/tool/docs/JavadocHelper.java | 89 +- .../com/ibm/icu/dev/tool/docs/ReportAPI.java | 65 +- .../dev/tool/errorprone/ErrorProneReport.java | 47 +- .../dev/tool/errorprone/ErrorProneUtils.java | 123 +- .../icu/dev/tool/errorprone/HtmlUtils.java | 70 +- .../com/ibm/icu/dev/tool/errorprone/Main.java | 101 +- .../ParseMavenOutForErrorProne.java | 54 +- .../icu/dev/tool/index/IndexGenerator.java | 37 +- .../dev/tool/charsetdet/mbcs/BIG5Tool.java | 153 +- .../icu/dev/tool/charsetdet/mbcs/EUCTool.java | 144 +- .../icu/dev/tool/charsetdet/sbcs/Checker.java | 144 +- .../dev/tool/charsetdet/sbcs/InputFile.java | 106 +- .../dev/tool/charsetdet/sbcs/NGramList.java | 112 +- .../dev/tool/charsetdet/sbcs/NGramParser.java | 143 +- .../tool/charsetdet/sbcs/StatisticsTool.java | 412 +- .../CompressionTableGenerator.java | 341 +- .../com/ibm/icu/dev/tool/ime/IMETest.java | 33 +- .../indic/BengaliInputMethodDescriptor.java | 379 +- .../DevanagariInputMethodDescriptor.java | 434 +- .../indic/GujaratiInputMethodDescriptor.java | 290 +- .../indic/GurmukhiInputMethodDescriptor.java | 327 +- .../dev/tool/ime/indic/IndicIMDescriptor.java | 27 +- .../dev/tool/ime/indic/IndicInputMethod.java | 34 +- .../tool/ime/indic/IndicInputMethodImpl.java | 220 +- .../indic/KannadaInputMethodDescriptor.java | 286 +- .../indic/MalayalamInputMethodDescriptor.java | 280 +- .../ime/indic/OriyaInputMethodDescriptor.java | 368 +- .../ime/indic/TamilInputMethodDescriptor.java | 281 +- .../indic/TeluguInputMethodDescriptor.java | 287 +- .../translit/TransliteratorInputMethod.java | 374 +- .../TransliteratorInputMethodDescriptor.java | 76 +- .../dev/tool/layout/ArabicCharacterData.java | 101 +- .../icu/dev/tool/layout/ArabicShaping.java | 27 +- .../dev/tool/layout/BuildMirroringTables.java | 67 +- .../icu/dev/tool/layout/CanonGSUBBuilder.java | 508 +- .../tool/layout/CanonicalCharacterData.java | 158 +- .../ibm/icu/dev/tool/layout/ClassTable.java | 142 +- .../ibm/icu/dev/tool/layout/DecompTable.java | 132 +- .../com/ibm/icu/dev/tool/layout/Feature.java | 41 +- .../ibm/icu/dev/tool/layout/FeatureList.java | 46 +- .../ibm/icu/dev/tool/layout/GDEFWriter.java | 35 +- .../ibm/icu/dev/tool/layout/GSUBWriter.java | 41 +- .../ibm/icu/dev/tool/layout/LanguageData.java | 82 +- .../icu/dev/tool/layout/LigatureEntry.java | 25 +- .../dev/tool/layout/LigatureModuleWriter.java | 10 +- .../ibm/icu/dev/tool/layout/LigatureTree.java | 120 +- .../dev/tool/layout/LigatureTreeWalker.java | 71 +- .../com/ibm/icu/dev/tool/layout/Lookup.java | 79 +- .../ibm/icu/dev/tool/layout/LookupList.java | 34 +- .../icu/dev/tool/layout/LookupSubtable.java | 3 +- .../ibm/icu/dev/tool/layout/ModuleWriter.java | 131 +- .../dev/tool/layout/OpenTypeTableWriter.java | 91 +- .../dev/tool/layout/OpenTypeTagBuilder.java | 241 +- .../ibm/icu/dev/tool/layout/ScriptData.java | 198 +- .../dev/tool/layout/ScriptIDModuleWriter.java | 354 +- .../ibm/icu/dev/tool/layout/ScriptList.java | 131 +- .../dev/tool/layout/ScriptModuleWriter.java | 9 +- .../dev/tool/layout/ScriptNameBuilder.java | 26 +- .../tool/layout/ScriptRunModuleWriter.java | 75 +- .../tool/layout/ScriptTagModuleWriter.java | 169 +- .../dev/tool/layout/ShapingTypeBuilder.java | 52 +- .../ibm/icu/dev/tool/layout/TagUtilities.java | 73 +- .../ibm/icu/dev/tool/layout/TagValueData.java | 21 +- .../ibm/icu/dev/tool/layout/TaggedRecord.java | 25 +- .../dev/tool/layout/ThaiCharacterClasses.java | 326 +- .../icu/dev/tool/layout/ThaiStateTable.java | 195 +- .../tool/layout/ThaiStateTableBuilder.java | 11 +- .../layout/ThaiStateTableModuleWriter.java | 13 +- .../dev/tool/layout/ThaiStateTransition.java | 43 +- .../ibm/icu/dev/tool/layout/TreeWalker.java | 6 +- .../tool/localeconverter/CalculateCRC32.java | 36 +- .../localeconverter/XLIFF2ICUConverter.java | 1108 +- .../dev/tool/timescale/CalculateLimits.java | 95 +- .../icu/dev/tool/timescale/EpochOffsets.java | 82 +- .../timescale/GenerateCTimeScaleData.java | 116 +- .../ibm/icu/dev/tool/timezone/ICUZDump.java | 69 +- .../ibm/icu/dev/tool/translit/SourceSet.java | 79 +- .../com/ibm/icu/dev/tool/translit/Trans.java | 51 +- .../tool/translit/UnicodeSetCloseOver.java | 279 +- .../dev/tool/translit/UnicodeSetClosure.java | 183 +- .../dev/tool/translit/WriteIndicCharts.java | 584 +- .../dev/tool/translit/genIndexFilters.java | 32 +- .../ibm/icu/dev/tool/docs/ICUBugTaglet.java | 3 +- .../icu/dev/tool/docs/ICUCategoryTaglet.java | 11 +- .../dev/tool/docs/ICUDiscouragedTaglet.java | 15 +- .../ibm/icu/dev/tool/docs/ICUDraftTaglet.java | 11 +- .../icu/dev/tool/docs/ICUEnhancedTaglet.java | 34 +- .../icu/dev/tool/docs/ICUInternalTaglet.java | 22 +- .../ibm/icu/dev/tool/docs/ICUNewTaglet.java | 26 +- .../ibm/icu/dev/tool/docs/ICUNoteTaglet.java | 17 +- .../icu/dev/tool/docs/ICUObsoleteTaglet.java | 21 +- .../dev/tool/docs/ICUProvisionalTaglet.java | 11 +- .../icu/dev/tool/docs/ICUStableTaglet.java | 11 +- .../icu/dev/tool/docs/ICUSummaryTaglet.java | 3 +- .../com/ibm/icu/dev/tool/docs/ICUTaglet.java | 65 +- .../ibm/icu/dev/tool/docs/ICUTestTaglet.java | 3 +- 1155 files changed, 242329 insertions(+), 189986 deletions(-) diff --git a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/Launcher.java b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/Launcher.java index c760f9c3d881..ec1873d93d3a 100644 --- a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/Launcher.java +++ b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/Launcher.java @@ -8,6 +8,9 @@ */ package com.ibm.icu.dev.demo; +import com.ibm.icu.dev.demo.impl.DemoApplet; +import com.ibm.icu.dev.demo.impl.DemoUtility; +import com.ibm.icu.util.VersionInfo; import java.awt.BorderLayout; import java.awt.Button; import java.awt.Color; @@ -22,26 +25,17 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import com.ibm.icu.dev.demo.impl.DemoApplet; -import com.ibm.icu.dev.demo.impl.DemoUtility; -import com.ibm.icu.util.VersionInfo; - - /** - * @author srl - * Application to provide a panel of demos to launch + * @author srl Application to provide a panel of demos to launch */ public class Launcher extends DemoApplet { private static final long serialVersionUID = -8054963875776183877L; - - /** - * base package of all demos - */ + + /** base package of all demos */ public static final String demoBase = "com.ibm.icu.dev.demo"; - /** - * list of classes, relative to the demoBase. all must have a static void main(String[]) - */ - public static final String demoList[] = { + + /** list of classes, relative to the demoBase. all must have a static void main(String[]) */ + public static final String demoList[] = { "calendar.CalendarApp", "charsetdet.DetectingViewer", "holiday.HolidayCalendarDemo", @@ -51,16 +45,16 @@ public class Launcher extends DemoApplet { public class LauncherFrame extends Frame implements ActionListener { private static final long serialVersionUID = -8054963875776183878L; - + public Button buttonList[] = new Button[demoList.length]; // one button for each demo public Label statusLabel; private DemoApplet applet; - + LauncherFrame(DemoApplet applet) { init(); this.applet = applet; } - + public void init() { // close down when close is clicked. // TODO: this should be factored.. @@ -74,114 +68,119 @@ public void windowClosing(WindowEvent e) { applet.demoClosed(); } else System.exit(0); } - } ); + }); setBackground(DemoUtility.bgColor); setLayout(new BorderLayout()); Panel topPanel = new Panel(); - topPanel.setLayout(new GridLayout(5,3)); + topPanel.setLayout(new GridLayout(5, 3)); - for(int i=0;i 0 && locales[i].getLanguage().equals(locales[i-1].getLanguage()) || - i < locales.length - 1 && - locales[i].getLanguage().equals(locales[i+1].getLanguage())) - { - localeMenu.addItem( locales[i].getDisplayName() ); + if (i > 0 && locales[i].getLanguage().equals(locales[i - 1].getLanguage()) + || i < locales.length - 1 + && locales[i].getLanguage().equals(locales[i + 1].getLanguage())) { + localeMenu.addItem(locales[i].getDisplayName()); } else { - localeMenu.addItem( locales[i].getDisplayLanguage()); + localeMenu.addItem(locales[i].getDisplayLanguage()); } - + thisMatch = DemoUtility.compareLocales(locales[i], defaultLocale); - + if (thisMatch >= bestMatch) { bestMatch = thisMatch; selectMe = i; } } - + localeMenu.setBackground(DemoUtility.choiceColor); localeMenu.select(selectMe); - Label localeLabel =new Label("Display Locale"); + Label localeLabel = new Label("Display Locale"); localeLabel.setFont(DemoUtility.labelFont); localePanel.add(localeLabel); localePanel.add(localeMenu); - DemoUtility.fixGrid(localePanel,2); - - localeMenu.addItemListener( new ItemListener() { - public void itemStateChanged(ItemEvent e) { - Locale loc = locales[localeMenu.getSelectedIndex()]; - System.out.println("Change locale to " + loc.getDisplayName()); - - for (int i = 0; i < calendars.length; i++) { - calendars[i].setLocale(loc); - } - millisFormat(); - } - } ); + DemoUtility.fixGrid(localePanel, 2); + + localeMenu.addItemListener( + new ItemListener() { + public void itemStateChanged(ItemEvent e) { + Locale loc = locales[localeMenu.getSelectedIndex()]; + System.out.println("Change locale to " + loc.getDisplayName()); + + for (int i = 0; i < calendars.length; i++) { + calendars[i].setLocale(loc); + } + millisFormat(); + } + }); } add(rollAddPanel); add(DemoUtility.createSpacer()); add(localePanel); add(DemoUtility.createSpacer()); -// COPYRIGHT + // COPYRIGHT Panel copyrightPanel = new Panel(); - addWithFont (copyrightPanel,new Label(DemoUtility.copyright1, Label.LEFT), - DemoUtility.creditFont); - DemoUtility.fixGrid(copyrightPanel,1); + addWithFont( + copyrightPanel, + new Label(DemoUtility.copyright1, Label.LEFT), + DemoUtility.creditFont); + DemoUtility.fixGrid(copyrightPanel, 1); add(copyrightPanel); } - /** - * This function is called when users change the pattern text. - */ + /** This function is called when users change the pattern text. */ public void setFormatFromPattern() { String timePattern = patternText.getText(); @@ -337,16 +316,15 @@ public void setFormatFromPattern() { } /** - * This function is called when it is necessary to parse the time - * string in one of the formatted date fields + * This function is called when it is necessary to parse the time string in one of the formatted + * date fields */ public void textChanged(int index) { String rightString = calendars[index].text.getText(); ParsePosition status = new ParsePosition(0); - if (rightString.length() == 0) - { + if (rightString.length() == 0) { errorText("Error: no input to parse!"); return; } @@ -354,14 +332,13 @@ public void textChanged(int index) { try { Date date = calendars[index].format.parse(rightString, status); time = date.getTime(); - } - catch (Exception e) { + } catch (Exception e) { for (int i = 0; i < calendars.length; i++) { if (i != index) { calendars[i].text.setText("ERROR"); } } - errorText("Exception: " + e.getClass().toString() + " parsing: "+rightString); + errorText("Exception: " + e.getClass().toString() + " parsing: " + rightString); return; } @@ -370,12 +347,11 @@ public void textChanged(int index) { millisFormat(); - calendars[index].text.select(start,end); + calendars[index].text.select(start, end); } /** - * This function is called when it is necessary to format the time - * in the "Millis" text field. + * This function is called when it is necessary to format the time in the "Millis" text field. */ public void millisFormat() { String out = ""; @@ -384,26 +360,25 @@ public void millisFormat() { try { out = calendars[i].format.format(new Date(time)); calendars[i].text.setText(out); - } - catch (Exception e) { + } catch (Exception e) { calendars[i].text.setText("ERROR"); - errorText("Exception: " + e.getClass().toString() + " formatting " - + calendars[i].name + " " + time); + errorText( + "Exception: " + + e.getClass().toString() + + " formatting " + + calendars[i].name + + " " + + time); } } } - - /** - * This function is called when users change the pattern text. - */ + /** This function is called when users change the pattern text. */ public void patternTextChanged() { setFormatFromPattern(); } - /** - * This function is called when users select a new representative city. - */ + /** This function is called when users select a new representative city. */ public void cityChanged() { TimeZone timeZone = TimeZone.getDefault(); @@ -413,17 +388,12 @@ public void cityChanged() { millisFormat(); } - /** - * This function is called when users select a new time field - * to add or roll its value. - */ + /** This function is called when users select a new time field to add or roll its value. */ public void dateFieldChanged(boolean isUp) { int field = kRollAddFields[dateMenu.getSelectedIndex()].field; - for (int i = 0; i < calendars.length; i++) - { - if (calendars[i].rollAdd.getState()) - { + for (int i = 0; i < calendars.length; i++) { + if (calendars[i].rollAdd.getState()) { Calendar c = calendars[i].calendar; c.setTime(new Date(time)); @@ -440,47 +410,38 @@ public void dateFieldChanged(boolean isUp) { } } - /** - * Print out the error message while debugging this program. - */ - public void errorText(String s) - { + /** Print out the error message while debugging this program. */ + public void errorText(String s) { if (true) { System.out.println(s); } } - - /** - * Called if an action occurs in the CalendarCalcFrame object. - */ - public void actionPerformed(ActionEvent evt) - { + + /** Called if an action occurs in the CalendarCalcFrame object. */ + public void actionPerformed(ActionEvent evt) { // *** Button events are handled here. Object obj = evt.getSource(); System.out.println("action " + obj); if (obj instanceof Button) { if (evt.getSource() == up) { dateFieldChanged(false); - } else - if (evt.getSource() == down) { - dateFieldChanged(true); + } else if (evt.getSource() == down) { + dateFieldChanged(true); } } } - + /** - * Handles the event. Returns true if the event is handled and should not - * be passed to the parent of this component. The default event handler - * calls some helper methods to make life easier on the programmer. + * Handles the event. Returns true if the event is handled and should not be passed to the + * parent of this component. The default event handler calls some helper methods to make life + * easier on the programmer. */ - protected void processKeyEvent(KeyEvent evt) - { + protected void processKeyEvent(KeyEvent evt) { System.out.println("key " + evt); - if (evt.getID() == KeyEvent.KEY_RELEASED) { + if (evt.getID() == KeyEvent.KEY_RELEASED) { if (evt.getSource() == patternText) { patternTextChanged(); - } - else { + } else { for (int i = 0; i < calendars.length; i++) { if (evt.getSource() == calendars[i].text) { textChanged(i); @@ -489,21 +450,19 @@ protected void processKeyEvent(KeyEvent evt) } } } - - protected void processWindowEvent(WindowEvent evt) - { + + protected void processWindowEvent(WindowEvent evt) { System.out.println("window " + evt); - if (evt.getID() == WindowEvent.WINDOW_CLOSING && - evt.getSource() == this) { + if (evt.getID() == WindowEvent.WINDOW_CLOSING && evt.getSource() == this) { this.hide(); this.dispose(); if (applet != null) { - applet.demoClosed(); + applet.demoClosed(); } else System.exit(0); } } - + /* protected void processEvent(AWTEvent evt) { @@ -518,69 +477,65 @@ else if (evt.id == Event.ACTION_EVENT && evt.target == down) { } */ - private static final int FIELD_COLUMNS = 35; - + private static final int FIELD_COLUMNS = 35; class CalendarRec { - public CalendarRec(String nameStr, Calendar cal) - { + public CalendarRec(String nameStr, Calendar cal) { name = nameStr; calendar = cal; rollAdd = new Checkbox(); - text = new JTextField("",FIELD_COLUMNS); + text = new JTextField("", FIELD_COLUMNS); text.setFont(DemoUtility.editFont); - format = DateFormat.getDateInstance(cal, DateFormat.FULL, - Locale.getDefault()); - //format.applyPattern(DEFAULT_FORMAT); + format = DateFormat.getDateInstance(cal, DateFormat.FULL, Locale.getDefault()); + // format.applyPattern(DEFAULT_FORMAT); } public void setLocale(Locale loc) { String pattern = toPattern(); - format = DateFormat.getDateInstance(calendar, DateFormat.FULL, - loc); + format = DateFormat.getDateInstance(calendar, DateFormat.FULL, loc); applyPattern(pattern); } public void applyPattern(String pattern) { if (format instanceof SimpleDateFormat) { - ((SimpleDateFormat)format).applyPattern(pattern); -//hey {al} - -// } else if (format instanceof java.text.SimpleDateFormat) { -// ((java.text.SimpleDateFormat)format).applyPattern(pattern); + ((SimpleDateFormat) format).applyPattern(pattern); + // hey {al} - + // } else if (format instanceof java.text.SimpleDateFormat) { + // ((java.text.SimpleDateFormat)format).applyPattern(pattern); } } - + private String toPattern() { if (format instanceof SimpleDateFormat) { - return ((SimpleDateFormat)format).toPattern(); -//hey {al} - -// } else if (format instanceof java.text.SimpleDateFormat) { -// return ((java.text.SimpleDateFormat)format).toPattern(); + return ((SimpleDateFormat) format).toPattern(); + // hey {al} - + // } else if (format instanceof java.text.SimpleDateFormat) { + // return ((java.text.SimpleDateFormat)format).toPattern(); } return ""; } - Calendar calendar; - DateFormat format; - String name; - JTextField text; - Checkbox rollAdd; + Calendar calendar; + DateFormat format; + String name; + JTextField text; + Checkbox rollAdd; } private final CalendarRec[] calendars = { - new CalendarRec("Gregorian", new GregorianCalendar()), - new CalendarRec("Hebrew", new HebrewCalendar()), - new CalendarRec("Islamic (civil)", makeIslamic(true)), - new CalendarRec("Islamic (true)", makeIslamic(false)), - new CalendarRec("Buddhist", new BuddhistCalendar()), - new CalendarRec("Japanese", new JapaneseCalendar()), -// new CalendarRec("Chinese", new ChineseCalendar()), + new CalendarRec("Gregorian", new GregorianCalendar()), + new CalendarRec("Hebrew", new HebrewCalendar()), + new CalendarRec("Islamic (civil)", makeIslamic(true)), + new CalendarRec("Islamic (true)", makeIslamic(false)), + new CalendarRec("Buddhist", new BuddhistCalendar()), + new CalendarRec("Japanese", new JapaneseCalendar()), + // new CalendarRec("Chinese", new ChineseCalendar()), }; - static private final Calendar makeIslamic(boolean civil) { + private static final Calendar makeIslamic(boolean civil) { IslamicCalendar cal = new IslamicCalendar(); cal.setCivil(civil); return cal; @@ -592,6 +547,7 @@ class RollAddField { this.field = field; this.name = name; } + int field; String name; } diff --git a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/calendar/CalendarFrame.java b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/calendar/CalendarFrame.java index d64b6c33f19b..a89a823ab00e 100644 --- a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/calendar/CalendarFrame.java +++ b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/calendar/CalendarFrame.java @@ -9,6 +9,16 @@ package com.ibm.icu.dev.demo.calendar; +import com.ibm.icu.dev.demo.impl.DemoApplet; +import com.ibm.icu.dev.demo.impl.DemoUtility; +import com.ibm.icu.text.DateFormat; +import com.ibm.icu.util.BuddhistCalendar; +import com.ibm.icu.util.Calendar; +import com.ibm.icu.util.GregorianCalendar; +import com.ibm.icu.util.HebrewCalendar; +import com.ibm.icu.util.IslamicCalendar; +import com.ibm.icu.util.JapaneseCalendar; +import com.ibm.icu.util.SimpleTimeZone; import java.awt.BorderLayout; import java.awt.Button; import java.awt.Choice; @@ -35,75 +45,60 @@ import java.util.Date; import java.util.Locale; -import com.ibm.icu.dev.demo.impl.DemoApplet; -import com.ibm.icu.dev.demo.impl.DemoUtility; -import com.ibm.icu.text.DateFormat; -import com.ibm.icu.util.BuddhistCalendar; -import com.ibm.icu.util.Calendar; -import com.ibm.icu.util.GregorianCalendar; -import com.ibm.icu.util.HebrewCalendar; -import com.ibm.icu.util.IslamicCalendar; -import com.ibm.icu.util.JapaneseCalendar; -import com.ibm.icu.util.SimpleTimeZone; - /** - * A Frame is a top-level window with a title. The default layout for a frame - * is BorderLayout. The CalendarFrame class defines the window layout of - * CalendarDemo. + * A Frame is a top-level window with a title. The default layout for a frame is BorderLayout. The + * CalendarFrame class defines the window layout of CalendarDemo. */ -class CalendarFrame extends Frame -{ - /** - * For serialization - */ +class CalendarFrame extends Frame { + /** For serialization */ private static final long serialVersionUID = -4289697663503820619L; private static final boolean DEBUG = false; private DemoApplet applet; - /** - * Constructs a new CalendarFrame that is initially invisible. - */ - public CalendarFrame(DemoApplet myApplet) - { + /** Constructs a new CalendarFrame that is initially invisible. */ + public CalendarFrame(DemoApplet myApplet) { super("Calendar Demo"); this.applet = myApplet; init(); // When the window is closed, we want to shut down the applet or application addWindowListener( - new WindowAdapter() { - public void windowClosing(WindowEvent e) { - setVisible(false); - dispose(); - - if (applet != null) { - applet.demoClosed(); - } else System.exit(0); - } - } ); + new WindowAdapter() { + public void windowClosing(WindowEvent e) { + setVisible(false); + dispose(); + + if (applet != null) { + applet.demoClosed(); + } else System.exit(0); + } + }); } - private Choice displayMenu; - private Locale[] locales = DemoUtility.getG7Locales(); - - private Calendar calendars[] = new Calendar[2]; - private Choice calMenu[] = new Choice[2]; - private ColoredLabel monthLabel[] = new ColoredLabel[2]; - private DateFormat monthFormat[] = new DateFormat[2]; - - private Button prevYear; - private Button prevMonth; - private Button gotoToday; - private Button nextMonth; - private Button nextYear; - private CalendarPanel calendarPanel; - - private static void add(Container container, Component component, - GridBagLayout g, GridBagConstraints c, - int gridwidth, int weightx) - { + private Choice displayMenu; + private Locale[] locales = DemoUtility.getG7Locales(); + + private Calendar calendars[] = new Calendar[2]; + private Choice calMenu[] = new Choice[2]; + private ColoredLabel monthLabel[] = new ColoredLabel[2]; + private DateFormat monthFormat[] = new DateFormat[2]; + + private Button prevYear; + private Button prevMonth; + private Button gotoToday; + private Button nextMonth; + private Button nextYear; + private CalendarPanel calendarPanel; + + private static void add( + Container container, + Component component, + GridBagLayout g, + GridBagConstraints c, + int gridwidth, + int weightx) { c.gridwidth = gridwidth; c.weightx = weightx; g.setConstraints(component, c); @@ -111,12 +106,12 @@ private static void add(Container container, Component component, } /** - * Initializes the applet. You never need to call this directly, it - * is called automatically by the system once the applet is created. + * Initializes the applet. You never need to call this directly, it is called automatically by + * the system once the applet is created. */ public void init() { setBackground(DemoUtility.bgColor); - setLayout(new BorderLayout(10,10)); + setLayout(new BorderLayout(10, 10)); Panel topPanel = new Panel(); GridBagLayout g = new GridBagLayout(); @@ -154,13 +149,13 @@ public void init() { prevMonth.addActionListener(new AddAction(Calendar.MONTH, -1)); gotoToday = new Button("Today"); - gotoToday.addActionListener( new ActionListener() - { - public void actionPerformed(ActionEvent e) { - calendarPanel.setDate( new Date() ); - updateMonthName(); - } - } ); + gotoToday.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + calendarPanel.setDate(new Date()); + updateMonthName(); + } + }); nextMonth = new Button(">"); nextMonth.addActionListener(new AddAction(Calendar.MONTH, 1)); @@ -169,11 +164,11 @@ public void actionPerformed(ActionEvent e) { nextYear.addActionListener(new AddAction(Calendar.YEAR, 1)); c.fill = GridBagConstraints.NONE; - add(topPanel, prevYear, g, c, 1, 0); + add(topPanel, prevYear, g, c, 1, 0); add(topPanel, prevMonth, g, c, 1, 0); add(topPanel, gotoToday, g, c, 1, 0); add(topPanel, nextMonth, g, c, 1, 0); - add(topPanel, nextYear, g, c, 1, 0); + add(topPanel, nextYear, g, c, 1, 0); // Now add the menu for selecting the display language Panel displayPanel = new Panel(); @@ -182,39 +177,37 @@ public void actionPerformed(ActionEvent e) { Locale defaultLocale = Locale.getDefault(); int bestMatch = -1, thisMatch = -1; int selectMe = 0; - + for (int i = 0; i < locales.length; i++) { - if (i > 0 && - locales[i].getLanguage().equals(locales[i-1].getLanguage()) || - i < locales.length - 1 && - locales[i].getLanguage().equals(locales[i+1].getLanguage())) - { - displayMenu.addItem( locales[i].getDisplayName() ); + if (i > 0 && locales[i].getLanguage().equals(locales[i - 1].getLanguage()) + || i < locales.length - 1 + && locales[i].getLanguage().equals(locales[i + 1].getLanguage())) { + displayMenu.addItem(locales[i].getDisplayName()); } else { - displayMenu.addItem( locales[i].getDisplayLanguage()); + displayMenu.addItem(locales[i].getDisplayLanguage()); } thisMatch = DemoUtility.compareLocales(locales[i], defaultLocale); - + if (thisMatch >= bestMatch) { bestMatch = thisMatch; selectMe = i; } } - + displayMenu.setBackground(DemoUtility.choiceColor); displayMenu.select(selectMe); - displayMenu.addItemListener( new ItemListener() - { - public void itemStateChanged(ItemEvent e) { - Locale loc = locales[displayMenu.getSelectedIndex()]; - calendarPanel.setLocale( loc ); - monthFormat[0] = monthFormat[1] = null; - updateMonthName(); - repaint(); - } - } ); + displayMenu.addItemListener( + new ItemListener() { + public void itemStateChanged(ItemEvent e) { + Locale loc = locales[displayMenu.getSelectedIndex()]; + calendarPanel.setLocale(loc); + monthFormat[0] = monthFormat[1] = null; + updateMonthName(); + repaint(); + } + }); Label l1 = new Label("Display Language:", Label.RIGHT); l1.setFont(DemoUtility.labelFont); @@ -222,7 +215,6 @@ public void itemStateChanged(ItemEvent e) { displayPanel.setLayout(new FlowLayout()); displayPanel.add(l1); displayPanel.add(displayMenu); - } c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.EAST; @@ -238,7 +230,7 @@ public void itemStateChanged(ItemEvent e) { add("South", copyright); // Now create the big calendar panel and stick it in the middle - calendarPanel = new CalendarPanel( locales[displayMenu.getSelectedIndex()] ); + calendarPanel = new CalendarPanel(locales[displayMenu.getSelectedIndex()]); add("Center", calendarPanel); for (int i = 0; i < 2; i++) { @@ -249,51 +241,47 @@ public void itemStateChanged(ItemEvent e) { updateMonthName(); } - - private void updateMonthName() - { - for (int i = 0; i < 2; i++) { - try { - if (monthFormat[i] == null) { // TODO: optimize - DateFormat f = DateFormat.getDateTimeInstance( - calendars[i], DateFormat.MEDIUM, -1, - locales[displayMenu.getSelectedIndex()]); - if (f instanceof com.ibm.icu.text.SimpleDateFormat) { - com.ibm.icu.text.SimpleDateFormat f1 = (com.ibm.icu.text.SimpleDateFormat) f; - f1.applyPattern("MMMM, yyyy G"); - f1.setTimeZone(new SimpleTimeZone(0, "UTC")); - } - monthFormat[i] = f; + private void updateMonthName() { + for (int i = 0; i < 2; i++) { + try { + if (monthFormat[i] == null) { // TODO: optimize + DateFormat f = + DateFormat.getDateTimeInstance( + calendars[i], + DateFormat.MEDIUM, + -1, + locales[displayMenu.getSelectedIndex()]); + if (f instanceof com.ibm.icu.text.SimpleDateFormat) { + com.ibm.icu.text.SimpleDateFormat f1 = + (com.ibm.icu.text.SimpleDateFormat) f; + f1.applyPattern("MMMM, yyyy G"); + f1.setTimeZone(new SimpleTimeZone(0, "UTC")); } - } catch (ClassCastException e) { - //hey {lw} - there's something wrong in this routine that causes exceptions. - System.out.println(e); + monthFormat[i] = f; } - - monthLabel[i].setText( monthFormat[i].format( calendarPanel.firstOfMonth() )); + } catch (ClassCastException e) { + // hey {lw} - there's something wrong in this routine that causes exceptions. + System.out.println(e); } + + monthLabel[i].setText(monthFormat[i].format(calendarPanel.firstOfMonth())); + } } /** - * CalMenuListener responds to events in the two popup menus that select - * the calendar systems to be used in the display. It figures out which - * of the two menus the event occurred in and updates the corresponding - * element of the calendars[] array to match the new selection. + * CalMenuListener responds to events in the two popup menus that select the calendar systems to + * be used in the display. It figures out which of the two menus the event occurred in and + * updates the corresponding element of the calendars[] array to match the new selection. */ - private class CalMenuListener implements ItemListener - { - public void itemStateChanged(ItemEvent e) - { - for (int i = 0; i < calMenu.length; i++) - { - if (e.getItemSelectable() == calMenu[i]) - { + private class CalMenuListener implements ItemListener { + public void itemStateChanged(ItemEvent e) { + for (int i = 0; i < calMenu.length; i++) { + if (e.getItemSelectable() == calMenu[i]) { // We found the menu that the event happened in. // Figure out which new calendar they selected. - Calendar newCal = CALENDARS[ calMenu[i].getSelectedIndex() ].calendar; + Calendar newCal = CALENDARS[calMenu[i].getSelectedIndex()].calendar; - if (newCal != calendars[i]) - { + if (newCal != calendars[i]) { // If any of the other menus are set to the same new calendar // we're about to use for this menu, set them to the current // calendar from *this* menu so we won't have two the same @@ -321,12 +309,10 @@ public void itemStateChanged(ItemEvent e) break; } } - } + } } - /** - * AddAction handles the next/previous year/month buttons... - */ + /** AddAction handles the next/previous year/month buttons... */ private class AddAction implements ActionListener { AddAction(int field, int amount) { this.field = field; @@ -344,17 +330,15 @@ public void actionPerformed(ActionEvent e) { /** * ColoredLabel is similar to java.awt.Label, with two differences: * - * - You can set its text color + *

- You can set its text color * - * - It draws text using drawString rather than using a host-specific - * "Peer" object like AWT does. On 1.2, using drawString gives - * us Bidi reordering for free. + *

- It draws text using drawString rather than using a host-specific "Peer" object like AWT + * does. On 1.2, using drawString gives us Bidi reordering for free. */ - static private class ColoredLabel extends Component { - /** - * For serialization - */ + private static class ColoredLabel extends Component { + /** For serialization */ private static final long serialVersionUID = 5004484960341875722L; + public ColoredLabel(String label) { text = label; } @@ -381,9 +365,10 @@ public void paint(Graphics g) { g.setColor(color); g.setFont(font); - g.drawString(text, fm.stringWidth("\u00a0"), - bounds.height/2 + fm.getHeight() - - fm.getAscent() + fm.getLeading()/2); + g.drawString( + text, + fm.stringWidth("\u00a0"), + bounds.height / 2 + fm.getHeight() - fm.getAscent() + fm.getLeading() / 2); } public Dimension getPreferredSize() { @@ -393,8 +378,9 @@ public Dimension getPreferredSize() { public Dimension getMinimumSize() { FontMetrics fm = getFontMetrics(font); - return new Dimension( fm.stringWidth(text) + 2*fm.stringWidth("\u00a0"), - fm.getHeight() + fm.getLeading()*2); + return new Dimension( + fm.stringWidth(text) + 2 * fm.stringWidth("\u00a0"), + fm.getHeight() + fm.getLeading() * 2); } String text; @@ -402,43 +388,37 @@ public Dimension getMinimumSize() { Font font = DemoUtility.labelFont; } - /** - * Print out the error message while debugging this program. - */ - public void errorText(String s) - { - if (DEBUG) - { + /** Print out the error message while debugging this program. */ + public void errorText(String s) { + if (DEBUG) { System.out.println(s); } } class CalendarRec { - public CalendarRec(String nameStr, Calendar cal) - { + public CalendarRec(String nameStr, Calendar cal) { name = nameStr; calendar = cal; } - Calendar calendar; - String name; + Calendar calendar; + String name; } private final CalendarRec[] CALENDARS = { - new CalendarRec("Gregorian Calendar", new GregorianCalendar()), - new CalendarRec("Hebrew Calendar", new HebrewCalendar()), - new CalendarRec("Islamic Calendar", makeIslamic(false)), - new CalendarRec("Islamic Civil Calendar ", makeIslamic(true)), - new CalendarRec("Buddhist Calendar", new BuddhistCalendar()), - new CalendarRec("Japanese Calendar", new JapaneseCalendar()), + new CalendarRec("Gregorian Calendar", new GregorianCalendar()), + new CalendarRec("Hebrew Calendar", new HebrewCalendar()), + new CalendarRec("Islamic Calendar", makeIslamic(false)), + new CalendarRec("Islamic Civil Calendar ", makeIslamic(true)), + new CalendarRec("Buddhist Calendar", new BuddhistCalendar()), + new CalendarRec("Japanese Calendar", new JapaneseCalendar()), }; - static private final Calendar makeIslamic(boolean civil) { + private static final Calendar makeIslamic(boolean civil) { IslamicCalendar cal = new IslamicCalendar(); cal.setCivil(civil); return cal; } - static final Color[] COLORS = { Color.blue, Color.black }; + static final Color[] COLORS = {Color.blue, Color.black}; } - diff --git a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/calendar/CalendarPanel.java b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/calendar/CalendarPanel.java index ba28f8d30fe0..ac0a8e6625b5 100644 --- a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/calendar/CalendarPanel.java +++ b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/calendar/CalendarPanel.java @@ -9,6 +9,10 @@ package com.ibm.icu.dev.demo.calendar; +import com.ibm.icu.dev.demo.impl.DemoUtility; +import com.ibm.icu.text.DateFormatSymbols; +import com.ibm.icu.util.Calendar; +import com.ibm.icu.util.SimpleTimeZone; import java.awt.Canvas; import java.awt.Color; import java.awt.Dimension; @@ -18,19 +22,12 @@ import java.util.Date; import java.util.Locale; -import com.ibm.icu.dev.demo.impl.DemoUtility; -import com.ibm.icu.text.DateFormatSymbols; -import com.ibm.icu.util.Calendar; -import com.ibm.icu.util.SimpleTimeZone; - class CalendarPanel extends Canvas { - /** - * For serialization - */ + /** For serialization */ private static final long serialVersionUID = 625400018027387141L; - public CalendarPanel( Locale locale ) { + public CalendarPanel(Locale locale) { setLocale(locale); } @@ -41,8 +38,7 @@ public void setLocale(Locale locale) { for (int i = 0; i < fCalendar.length; i++) { if (fCalendar[i] != null) { - fSymbols[i] = new DateFormatSymbols(fCalendar[i], - fDisplayLocale); + fSymbols[i] = new DateFormatSymbols(fCalendar[i], fDisplayLocale); } } String lang = locale.getLanguage(); @@ -58,9 +54,8 @@ public void setDate(Date date) { repaint(); } - public void add(int field, int delta) - { - synchronized(fCalendar) { + public void add(int field, int delta) { + synchronized (fCalendar) { fCalendar[0].setTime(fStartOfMonth); fCalendar[0].add(field, delta); fStartOfMonth = fCalendar[0].getTime(); @@ -75,8 +70,7 @@ public void setColor(int index, Color c) { } public void setCalendar(int index, Calendar c) { - Date date = (fCalendar[index] == null) ? new Date() - : fCalendar[index].getTime(); + Date date = (fCalendar[index] == null) ? new Date() : fCalendar[index].getTime(); fCalendar[index] = c; fCalendar[index].setTime(date); @@ -98,9 +92,8 @@ public Date firstOfMonth() { return fStartOfMonth; } - private Date startOfMonth(Date dateInMonth) - { - synchronized(fCalendar) { + private Date startOfMonth(Date dateInMonth) { + synchronized (fCalendar) { fCalendar[0].setTime(dateInMonth); int era = fCalendar[0].get(Calendar.ERA); @@ -117,8 +110,7 @@ private Date startOfMonth(Date dateInMonth) } } - private void calculate() - { + private void calculate() { // // As a workaround for JDK 1.1.3 and below, where Calendars and time // zones are a bit goofy, always set my calendar's time zone to UTC. @@ -129,7 +121,7 @@ private void calculate() // fCalendar[0].setTimeZone(new SimpleTimeZone(0, "UTC")); - Calendar c = (Calendar)fCalendar[0].clone(); // Temporary copy + Calendar c = (Calendar) fCalendar[0].clone(); // Temporary copy fStartOfMonth = startOfMonth(fStartOfMonth); @@ -153,15 +145,15 @@ private void calculate() // Finally, find the end of the month, i.e. the start of the next one c.roll(Calendar.DATE, true); c.add(Calendar.MONTH, 1); - c.getTime(); // JDK 1.1.2 bug workaround + c.getTime(); // JDK 1.1.2 bug workaround c.add(Calendar.SECOND, -1); Date endOfMonth = c.getTime(); - if(endOfMonth==null){ - //do nothing + if (endOfMonth == null) { + // do nothing } endOfMonth = null; int lastWeek = c.get(Calendar.WEEK_OF_MONTH); - + // Calculate the number of full or partial weeks in this month. numWeeks = lastWeek - firstWeek + 1; @@ -175,8 +167,7 @@ private void calculate() * Convert from the day number within a month (1-based) * to the cell coordinates on the calendar (0-based) */ - private void dateToCell(int date, Point pos) - { + private void dateToCell(int date, Point pos) { int cell = (date + firstDayInMonth - firstDayOfWeek - minDay); if (firstDayInMonth < firstDayOfWeek) { cell += daysInWeek; @@ -185,11 +176,12 @@ private void dateToCell(int date, Point pos) pos.x = cell % daysInWeek; pos.y = cell / daysInWeek; } - //private Point dateToCell(int date) { + + // private Point dateToCell(int date) { // Point p = new Point(0,0); // dateToCell(date, p); // return p; - //} + // } public void paint(Graphics g) { @@ -197,11 +189,11 @@ public void paint(Graphics g) { calculate(); } - Point cellPos = new Point(0,0); // Temporary variable + Point cellPos = new Point(0, 0); // Temporary variable Dimension d = this.getSize(); g.setColor(Color.lightGray); - g.fillRect(0,0,d.width,d.height); + g.fillRect(0, 0, d.width, d.height); // Draw the day names at the top g.setColor(Color.black); @@ -214,20 +206,19 @@ public void paint(Graphics g) { int dayNum = (i + minDay + firstDayOfWeek - 2) % daysInWeek + 1; String dayName = fSymbols[0].getWeekdays()[dayNum]; - double h; if (leftToRight) { - h = d.width*(i + 0.5) / daysInWeek; + h = d.width * (i + 0.5) / daysInWeek; } else { - h = d.width*(daysInWeek - i - 0.5) / daysInWeek; + h = d.width * (daysInWeek - i - 0.5) / daysInWeek; } h -= fm.stringWidth(dayName) / 2; - g.drawString(dayName, (int)h, v); + g.drawString(dayName, (int) h, v); } double cellHeight = (d.height - labelHeight - 1) / numWeeks; - double cellWidth = (double)(d.width - 1) / daysInWeek; + double cellWidth = (double) (d.width - 1) / daysInWeek; // Draw a white background in the part of the calendar // that displays this month. @@ -235,41 +226,47 @@ public void paint(Graphics g) { { g.setColor(Color.white); dateToCell(1, cellPos); - int width = (int)(cellPos.x*cellWidth); // Width of unshaded area + int width = (int) (cellPos.x * cellWidth); // Width of unshaded area if (leftToRight) { - g.fillRect((int)(width), labelHeight , - d.width - width, (int)cellHeight); + g.fillRect((int) (width), labelHeight, d.width - width, (int) cellHeight); } else { - g.fillRect(0, labelHeight , - d.width - width, (int)cellHeight); + g.fillRect(0, labelHeight, d.width - width, (int) cellHeight); } // All of the intermediate weeks get shaded completely - g.fillRect(0, (int)(labelHeight + cellHeight), - d.width, (int)(cellHeight * (numWeeks - 2))); + g.fillRect( + 0, + (int) (labelHeight + cellHeight), + d.width, + (int) (cellHeight * (numWeeks - 2))); // Now figure out the last week. dateToCell(daysInMonth, cellPos); - width = (int)((cellPos.x+1)*cellWidth); // Width of shaded area + width = (int) ((cellPos.x + 1) * cellWidth); // Width of shaded area if (leftToRight) { - g.fillRect(0, (int)(labelHeight + (numWeeks-1) * cellHeight), - width, (int)cellHeight); + g.fillRect( + 0, + (int) (labelHeight + (numWeeks - 1) * cellHeight), + width, + (int) cellHeight); } else { - g.fillRect(d.width - width, (int)(labelHeight + (numWeeks-1) * cellHeight), - width, (int)cellHeight); + g.fillRect( + d.width - width, + (int) (labelHeight + (numWeeks - 1) * cellHeight), + width, + (int) cellHeight); } - } // Draw the X/Y grid lines g.setColor(Color.black); for (int i = 0; i <= numWeeks; i++) { - int y = (int)(labelHeight + i * cellHeight); + int y = (int) (labelHeight + i * cellHeight); g.drawLine(0, y, d.width - 1, y); } for (int i = 0; i <= daysInWeek; i++) { - int x = (int)(i * cellWidth); + int x = (int) (i * cellWidth); g.drawLine(x, labelHeight, x, d.height - 1); } @@ -282,7 +279,7 @@ public void paint(Graphics g) { cell += daysInWeek; } - Calendar c = (Calendar)fCalendar[0].clone(); + Calendar c = (Calendar) fCalendar[0].clone(); c.setTime(fStartOfMonth); c.add(Calendar.DATE, -cell); @@ -297,12 +294,12 @@ public void paint(Graphics g) { int cellx; if (leftToRight) { - cellx = (int)((col) * cellWidth); + cellx = (int) ((col) * cellWidth); } else { - cellx = (int)((daysInWeek - col - 1) * cellWidth); + cellx = (int) ((daysInWeek - col - 1) * cellWidth); } - int celly = (int)(row * cellHeight + labelHeight); + int celly = (int) (row * cellHeight + labelHeight); for (int i = 0; i < 2; i++) { fCalendar[i].setTime(c.getTime()); @@ -315,11 +312,11 @@ public void paint(Graphics g) { int x; if (leftToRight) { - x = cellx + (int)cellWidth - XINSET - fm.stringWidth(dayNum); + x = cellx + (int) cellWidth - XINSET - fm.stringWidth(dayNum); } else { x = cellx + XINSET; } - int y = celly + + fm.getAscent() + YINSET + i * fm.getHeight(); + int y = celly + +fm.getAscent() + YINSET + i * fm.getHeight(); if (fColor[i] != null) { g.setColor(fColor[i]); @@ -328,13 +325,12 @@ public void paint(Graphics g) { if (date == 1 || row == 0 && col == 0) { g.setFont(DemoUtility.numberFont); - String month = fSymbols[i].getMonths()[ - fCalendar[i].get(Calendar.MONTH)]; + String month = fSymbols[i].getMonths()[fCalendar[i].get(Calendar.MONTH)]; if (leftToRight) { x = cellx + XINSET; } else { - x = cellx + (int)cellWidth - XINSET - fm.stringWidth(month); + x = cellx + (int) cellWidth - XINSET - fm.stringWidth(month); } g.drawString(month, x, y); } @@ -346,22 +342,22 @@ public void paint(Graphics g) { } // Important state variables - private Calendar[] fCalendar = new Calendar[4]; - private Color[] fColor = new Color[4]; + private Calendar[] fCalendar = new Calendar[4]; + private Color[] fColor = new Color[4]; - private Locale fDisplayLocale; + private Locale fDisplayLocale; private DateFormatSymbols[] fSymbols = new DateFormatSymbols[4]; - private Date fStartOfMonth = new Date(); // 00:00:00 on first day of month + private Date fStartOfMonth = new Date(); // 00:00:00 on first day of month // Cached calculations to make drawing faster. - private transient int minDay; // Minimum legal day # - private transient int daysInWeek; // # of days in a week - private transient int firstDayOfWeek; // First day to display in week - private transient int numWeeks; // # full or partial weeks in month - private transient int daysInMonth; // # days in this month - private transient int firstDayInMonth; // Day of week of first day in month - private transient boolean leftToRight; + private transient int minDay; // Minimum legal day # + private transient int daysInWeek; // # of days in a week + private transient int firstDayOfWeek; // First day to display in week + private transient int numWeeks; // # full or partial weeks in month + private transient int daysInMonth; // # days in this month + private transient int firstDayInMonth; // Day of week of first day in month + private transient boolean leftToRight; private transient boolean dirty = true; } diff --git a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/charsetdet/DetectingViewer.java b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/charsetdet/DetectingViewer.java index 961224329dad..cfacb07d7f40 100644 --- a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/charsetdet/DetectingViewer.java +++ b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/charsetdet/DetectingViewer.java @@ -10,6 +10,10 @@ package com.ibm.icu.dev.demo.charsetdet; +import com.ibm.icu.charset.CharsetICU; +import com.ibm.icu.dev.demo.impl.DemoApplet; +import com.ibm.icu.text.CharsetDetector; +import com.ibm.icu.text.CharsetMatch; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -26,7 +30,6 @@ import java.nio.ByteBuffer; import java.nio.charset.Charset; import java.security.AccessControlException; - import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JMenu; @@ -37,42 +40,35 @@ import javax.swing.JTextPane; import javax.swing.KeyStroke; -import com.ibm.icu.charset.CharsetICU; -import com.ibm.icu.dev.demo.impl.DemoApplet; -import com.ibm.icu.text.CharsetDetector; -import com.ibm.icu.text.CharsetMatch; - /** - * This simple application demonstrates how to use the CharsetDetector API. It - * opens a file or web page, detects the encoding, and then displays it using that - * encoding. + * This simple application demonstrates how to use the CharsetDetector API. It opens a file or web + * page, detects the encoding, and then displays it using that encoding. */ -public class DetectingViewer extends JFrame implements ActionListener -{ - - /** - * For serialization - */ +public class DetectingViewer extends JFrame implements ActionListener { + + /** For serialization */ private static final long serialVersionUID = -2307065724464747775L; + private JTextPane text; private JFileChooser fileChooser; - + /** * @throws java.awt.HeadlessException */ - public DetectingViewer() - { + public DetectingViewer() { super(); DemoApplet.demoFrameOpened(); - + try { fileChooser = new JFileChooser(); } catch (AccessControlException ace) { - System.err.println("no file chooser - access control exception. Continuing without file browsing. "+ace.toString()); + System.err.println( + "no file chooser - access control exception. Continuing without file browsing. " + + ace.toString()); fileChooser = null; // } - -// setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + // setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(800, 800); setJMenuBar(makeMenus()); @@ -80,75 +76,67 @@ public DetectingViewer() text.setContentType("text/plain"); text.setText(""); text.setSize(800, 800); - + Font font = new Font("Arial Unicode MS", Font.PLAIN, 24); text.setFont(font); - + JScrollPane scrollPane = new JScrollPane(text); - + getContentPane().add(scrollPane); setVisible(true); addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e) { -// setVisible(false); -// dispose(); + // setVisible(false); + // dispose(); - doQuit(); + doQuit(); } - } ); - - + }); } - public void actionPerformed(ActionEvent event) - { + public void actionPerformed(ActionEvent event) { String cmd = event.getActionCommand(); - + if (cmd.equals("New...")) { - doNew(); + doNew(); } else if (cmd.equals("Open File...")) { - doOpenFile(); + doOpenFile(); } else if (cmd.equals("Open URL...")) { doOpenURL(); } else if (cmd.equals("Quit")) { - doQuit(); + doQuit(); } } - public static void main(String[] args) - { + public static void main(String[] args) { new DetectingViewer(); } - - private void errorDialog(String title, String msg) - { + + private void errorDialog(String title, String msg) { JOptionPane.showMessageDialog(this, msg, title, JOptionPane.ERROR_MESSAGE); } - - private BufferedInputStream openFile(File file) - { + + private BufferedInputStream openFile(File file) { FileInputStream fileStream = null; - + try { fileStream = new FileInputStream(file); } catch (Exception e) { errorDialog("Error Opening File", e.getMessage()); return null; } - + return new BufferedInputStream(fileStream); } - -// private void openFile(String directory, String filename) -// { -// openFile(new File(directory, filename)); -// } - - - private BufferedInputStream openURL(String url) - { + + // private void openFile(String directory, String filename) + // { + // openFile(new File(directory, filename)); + // } + + private BufferedInputStream openURL(String url) { InputStream s = null; try { @@ -158,75 +146,72 @@ private BufferedInputStream openURL(String url) errorDialog("Error Opening URL", e.getMessage()); return null; } - + return new BufferedInputStream(s); } - - private String encodingName(CharsetMatch match) - { + + private String encodingName(CharsetMatch match) { return match.getName() + " (" + match.getLanguage() + ")"; } - - private void setMatchMenu(CharsetMatch[] matches) - { + + private void setMatchMenu(CharsetMatch[] matches) { JMenu menu = getJMenuBar().getMenu(1); JMenuItem menuItem; - + menu.removeAll(); - + for (int i = 0; i < matches.length; i += 1) { CharsetMatch match = matches[i]; - + menuItem = new JMenuItem(encodingName(match) + " " + match.getConfidence()); - + menu.add(menuItem); } } - - private byte[] scriptTag = {(byte) 's', (byte) 'c', (byte) 'r', (byte) 'i', (byte) 'p', (byte) 't'}; - private byte[] styleTag = {(byte) 's', (byte) 't', (byte) 'y', (byte) 'l', (byte) 'e'}; + + private byte[] scriptTag = { + (byte) 's', (byte) 'c', (byte) 'r', (byte) 'i', (byte) 'p', (byte) 't' + }; + private byte[] styleTag = {(byte) 's', (byte) 't', (byte) 'y', (byte) 'l', (byte) 'e'}; private static int BUFFER_SIZE = 100000; - - private boolean openTag(byte[] buffer, int offset, int length, byte[] tag) - { + + private boolean openTag(byte[] buffer, int offset, int length, byte[] tag) { int tagLen = tag.length; int bufRem = length - offset; int b; - + for (b = 0; b < tagLen && b < bufRem; b += 1) { if (buffer[b + offset] != tag[b]) { return false; } } - + return b == tagLen; } - - private boolean closedTag(byte[] buffer, int offset, int length, byte[] tag) - { + + private boolean closedTag(byte[] buffer, int offset, int length, byte[] tag) { if (buffer[offset] != (byte) '/') { return false; } - + return openTag(buffer, offset + 1, length, tag); } - - private byte[] filter(InputStream in) - { + + private byte[] filter(InputStream in) { byte[] buffer = new byte[BUFFER_SIZE]; int bytesRemaining = BUFFER_SIZE; int bufLen = 0; - + in.mark(BUFFER_SIZE); - + try { while (bytesRemaining > 0) { int bytesRead = in.read(buffer, bufLen, bytesRemaining); - + if (bytesRead <= 0) { break; } - + bufLen += bytesRead; bytesRemaining -= bytesRead; } @@ -234,89 +219,86 @@ private byte[] filter(InputStream in) // TODO: error handling? return null; } - + boolean inTag = false; - boolean skip = false; + boolean skip = false; int out = 0; - + for (int i = 0; i < bufLen; i += 1) { byte b = buffer[i]; - + if (b == (byte) '<') { inTag = true; - - if (openTag(buffer, i + 1, bufLen, scriptTag) || - openTag(buffer, i + 1, bufLen, styleTag)) { + + if (openTag(buffer, i + 1, bufLen, scriptTag) + || openTag(buffer, i + 1, bufLen, styleTag)) { skip = true; - } else if (closedTag(buffer, i + 1, bufLen, scriptTag) || - closedTag(buffer, i + 1, bufLen, styleTag)) { + } else if (closedTag(buffer, i + 1, bufLen, scriptTag) + || closedTag(buffer, i + 1, bufLen, styleTag)) { skip = false; } } else if (b == (byte) '>') { inTag = false; - } else if (! (inTag || skip)) { + } else if (!(inTag || skip)) { buffer[out++] = b; } } byte[] filtered = new byte[out]; - + System.arraycopy(buffer, 0, filtered, 0, out); return filtered; } - - private CharsetMatch[] detect(byte[] bytes) - { + + private CharsetMatch[] detect(byte[] bytes) { CharsetDetector det = new CharsetDetector(); - + det.setText(bytes); - + return det.detectAll(); } - - private CharsetMatch[] detect(BufferedInputStream inputStream) - { - CharsetDetector det = new CharsetDetector(); - + + private CharsetMatch[] detect(BufferedInputStream inputStream) { + CharsetDetector det = new CharsetDetector(); + try { det.setText(inputStream); - + return det.detectAll(); } catch (Exception e) { // TODO: error message? return null; } } - - private void show(InputStream inputStream, CharsetMatch[] matches, String title) - { + + private void show(InputStream inputStream, CharsetMatch[] matches, String title) { InputStreamReader isr; char[] buffer = new char[1024]; int bytesRead = 0; - + if (matches == null || matches.length == 0) { errorDialog("Match Error", "No matches!"); return; } - + try { StringBuffer sb = new StringBuffer(); String encoding = matches[0].getName(); - + inputStream.reset(); - + if (encoding.startsWith("UTF-32")) { byte[] bytes = new byte[1024]; int offset = 0; int chBytes = 0; Charset utf32 = CharsetICU.forNameICU(encoding); - + while ((bytesRead = inputStream.read(bytes, offset, 1024)) >= 0) { - offset = bytesRead % 4; + offset = bytesRead % 4; chBytes = bytesRead - offset; - + sb.append(utf32.decode(ByteBuffer.wrap(bytes)).toString()); - + if (offset != 0) { for (int i = 0; i < offset; i += 1) { bytes[i] = bytes[chBytes + i]; @@ -325,16 +307,16 @@ private void show(InputStream inputStream, CharsetMatch[] matches, String title) } } else { isr = new InputStreamReader(inputStream, encoding); - + while ((bytesRead = isr.read(buffer, 0, 1024)) >= 0) { sb.append(buffer, 0, bytesRead); } - + isr.close(); } - + this.setTitle(title + " - " + encodingName(matches[0])); - + setMatchMenu(matches); text.setText(sb.toString()); } catch (IOException e) { @@ -343,81 +325,84 @@ private void show(InputStream inputStream, CharsetMatch[] matches, String title) errorDialog("Internal Error", e.getMessage()); } } - - private void doNew() - { + + private void doNew() { // open a new window... } - - private void doOpenFile() - { + + private void doOpenFile() { int retVal = fileChooser.showOpenDialog(this); - + if (retVal == JFileChooser.APPROVE_OPTION) { File file = fileChooser.getSelectedFile(); BufferedInputStream inputStream = openFile(file); - + if (inputStream != null) { CharsetMatch[] matches = detect(inputStream); - - show(inputStream, matches, file.getName()); + + show(inputStream, matches, file.getName()); } } } - - private void doOpenURL() - { - String url = (String) JOptionPane.showInputDialog(this, "URL to open:", "Open URL", JOptionPane.PLAIN_MESSAGE, - null, null, null); - + + private void doOpenURL() { + String url = + (String) + JOptionPane.showInputDialog( + this, + "URL to open:", + "Open URL", + JOptionPane.PLAIN_MESSAGE, + null, + null, + null); + if (url != null && url.length() > 0) { BufferedInputStream inputStream = openURL(url); - + if (inputStream != null) { byte[] filtered = filter(inputStream); CharsetMatch[] matches = detect(filtered); - - show(inputStream, matches, url); + + show(inputStream, matches, url); } } -} - - private void doQuit() - { + } + + private void doQuit() { DemoApplet.demoFrameClosed(); this.setVisible(false); this.dispose(); } - - private JMenuBar makeMenus() - { + + private JMenuBar makeMenus() { JMenu menu = new JMenu("File"); JMenuItem mi; - + mi = new JMenuItem("Open File..."); mi.setAccelerator((KeyStroke.getKeyStroke(KeyEvent.VK_O, ActionEvent.CTRL_MASK))); mi.addActionListener(this); menu.add(mi); - if(fileChooser == null) { + if (fileChooser == null) { mi.setEnabled(false); // no file chooser. } - + mi = new JMenuItem("Open URL..."); mi.setAccelerator((KeyStroke.getKeyStroke(KeyEvent.VK_U, ActionEvent.CTRL_MASK))); mi.addActionListener(this); menu.add(mi); - + mi = new JMenuItem("Quit"); mi.setAccelerator((KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.CTRL_MASK))); mi.addActionListener(this); menu.add(mi); - + JMenuBar mbar = new JMenuBar(); mbar.add(menu); - + menu = new JMenu("Detected Encodings"); mbar.add(menu); - + return mbar; } } diff --git a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/holiday/HolidayBorderPanel.java b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/holiday/HolidayBorderPanel.java index 4949811e2d96..220fe9d93a0b 100644 --- a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/holiday/HolidayBorderPanel.java +++ b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/holiday/HolidayBorderPanel.java @@ -17,64 +17,77 @@ import java.awt.Panel; /** - * Various graphical borders. The border itself is a Panel so that it can - * contain other Components (i.e. it borders something). You use the - * HolidayBorderPanel like any other Panel: you set the layout that you prefer and - * add Components to it. Beware that a null layout does not obey the insets - * of the panel so if you use null layouts, adjust your measurements to - * handle the border by calling insets(). + * Various graphical borders. The border itself is a Panel so that it can contain other Components + * (i.e. it borders something). You use the HolidayBorderPanel like any other Panel: you set the + * layout that you prefer and add Components to it. Beware that a null layout does not obey the + * insets of the panel so if you use null layouts, adjust your measurements to handle the border by + * calling insets(). * - * @author Andy Clark, Taligent Inc. + * @author Andy Clark, Taligent Inc. * @version 1.0 */ public class HolidayBorderPanel extends Panel { - /** - * For serialization - */ + /** For serialization */ private static final long serialVersionUID = 4669213306492461159L; + // Constants /** Solid border. */ - public final static int SOLID = 0; + public static final int SOLID = 0; + /** A raised border. */ - public final static int RAISED = 1; + public static final int RAISED = 1; + /** A lowered border. */ - public final static int LOWERED = 2; + public static final int LOWERED = 2; + /** An etched in border. */ - public final static int IN = 3; + public static final int IN = 3; + /** An etched out border. */ - public final static int OUT = 4; + public static final int OUT = 4; /** Left alignment. */ - public final static int LEFT = 0; + public static final int LEFT = 0; + /** Center alignment. */ - public final static int CENTER = 1; + public static final int CENTER = 1; + /** Right alignment. */ - public final static int RIGHT = 2; + public static final int RIGHT = 2; /** Default style (IN). */ - public final static int DEFAULT_STYLE = IN; + public static final int DEFAULT_STYLE = IN; + /** Default thickness (10). */ - public final static int DEFAULT_THICKNESS = 10; + public static final int DEFAULT_THICKNESS = 10; + /** Default thickness for solid borders (4). */ - public final static int DEFAULT_SOLID_THICKNESS = 4; + public static final int DEFAULT_SOLID_THICKNESS = 4; + /** Default thickness for raised borders (2). */ - public final static int DEFAULT_RAISED_THICKNESS = 2; + public static final int DEFAULT_RAISED_THICKNESS = 2; + /** Default thickness for lowered borders (2). */ - public final static int DEFAULT_LOWERED_THICKNESS = 2; + public static final int DEFAULT_LOWERED_THICKNESS = 2; + /** Default thickness for etched-in borders (10). */ - public final static int DEFAULT_IN_THICKNESS = 10; + public static final int DEFAULT_IN_THICKNESS = 10; + /** Default thickness for etched-out borders (10). */ - public final static int DEFAULT_OUT_THICKNESS = 10; + public static final int DEFAULT_OUT_THICKNESS = 10; + /** Default gap between border and contained component (5). */ - public final static int DEFAULT_GAP = 5; + public static final int DEFAULT_GAP = 5; + /** Default color (black). Applies to SOLID and etched borders. */ - public final static Color DEFAULT_COLOR = Color.black; + public static final Color DEFAULT_COLOR = Color.black; /** Default font (TimesRoman,PLAIN,14). Only applies to etched borders. */ - public final static Font DEFAULT_FONT = new Font("TimesRoman", Font.PLAIN, 14); + public static final Font DEFAULT_FONT = new Font("TimesRoman", Font.PLAIN, 14); + /** Default alignment (LEFT). Only applies to etched borders. */ - public final static int DEFAULT_ALIGNMENT = LEFT; + public static final int DEFAULT_ALIGNMENT = LEFT; // Data private int style; @@ -86,39 +99,36 @@ public class HolidayBorderPanel extends Panel { private String text; private int alignment; - /** - * Constructor. Makes default border. - */ + /** Constructor. Makes default border. */ public HolidayBorderPanel() { // initialize data - style = DEFAULT_STYLE; - thickness = DEFAULT_THICKNESS; - gap = DEFAULT_GAP; - color = DEFAULT_COLOR; - - text = null; - font = DEFAULT_FONT; - alignment = DEFAULT_ALIGNMENT; - - } + style = DEFAULT_STYLE; + thickness = DEFAULT_THICKNESS; + gap = DEFAULT_GAP; + color = DEFAULT_COLOR; + + text = null; + font = DEFAULT_FONT; + alignment = DEFAULT_ALIGNMENT; + } /** * Constructor. Makes an etched IN border with given text caption. * - * @param text Text caption + * @param text Text caption */ public HolidayBorderPanel(String text) { this(); style = IN; this.text = text; - } + } /** * Constructor. Makes SOLID border with color and thickness given. * - * @param color The color for the border. + * @param color The color for the border. * @param thickness The thickness of the border. */ public HolidayBorderPanel(Color color, int thickness) { @@ -127,11 +137,10 @@ public HolidayBorderPanel(Color color, int thickness) { style = SOLID; this.color = color; this.thickness = thickness; - } + } /** - * Constructor. Makes a border of the given style with the default - * thickness for that style. + * Constructor. Makes a border of the given style with the default thickness for that style. * * @param style The style for this border. */ @@ -140,22 +149,32 @@ public HolidayBorderPanel(int style) { // set thickness appropriate to this style switch (style) { - case SOLID: thickness = DEFAULT_SOLID_THICKNESS; break; - case RAISED: thickness = DEFAULT_RAISED_THICKNESS; break; - case LOWERED: thickness = DEFAULT_LOWERED_THICKNESS; break; - case IN: thickness = DEFAULT_IN_THICKNESS; break; - case OUT: thickness = DEFAULT_OUT_THICKNESS; break; + case SOLID: + thickness = DEFAULT_SOLID_THICKNESS; + break; + case RAISED: + thickness = DEFAULT_RAISED_THICKNESS; + break; + case LOWERED: + thickness = DEFAULT_LOWERED_THICKNESS; + break; + case IN: + thickness = DEFAULT_IN_THICKNESS; + break; + case OUT: + thickness = DEFAULT_OUT_THICKNESS; + break; default: thickness = DEFAULT_THICKNESS; - } + } this.style = style; - } + } /** * Constructor. Makes border with given style and thickness. * - * @param style The style for this border. + * @param style The style for this border. * @param thickness The thickness for this border. */ public HolidayBorderPanel(int style, int thickness) { @@ -163,11 +182,9 @@ public HolidayBorderPanel(int style, int thickness) { this.style = style; this.thickness = thickness; - } + } - /** - * Returns the insets of this panel.. - */ + /** Returns the insets of this panel.. */ public Insets getInsets() { int adjustment = 0; @@ -177,21 +194,19 @@ public Insets getInsets() { try { // set font and get info int height = getGraphics().getFontMetrics(font).getHeight(); - if (height > thickness) - adjustment = height - thickness; - } - catch (Exception e) { + if (height > thickness) adjustment = height - thickness; + } catch (Exception e) { // nothing: just in case there is no graphics context // at the beginning. System.out.print(""); - } } } + } // return appropriate insets int dist = thickness + gap; return new Insets(dist + adjustment, dist, dist, dist); - } + } /** * Sets the style of the border @@ -206,15 +221,13 @@ public HolidayBorderPanel setStyle(int style) { repaint(); return this; - } + } - /** - * Gets the style of the border - */ + /** Gets the style of the border */ public int getStyle() { return style; - } + } /** * Sets the thickness of the border. @@ -227,18 +240,16 @@ public HolidayBorderPanel setThickness(int thickness) { this.thickness = thickness; doLayout(); repaint(); - } + } return this; - } + } - /** - * Gets the thickness of the border. - */ + /** Gets the thickness of the border. */ public int getThickness() { return thickness; - } + } /** * Sets the gap between the border and the contained Component. @@ -251,46 +262,37 @@ public HolidayBorderPanel setGap(int gap) { this.gap = gap; doLayout(); repaint(); - } + } return this; - } + } - /** - * Gets the gap between the border and the contained Component. - */ + /** Gets the gap between the border and the contained Component. */ public int getGap() { return gap; - } + } /** - * Sets the current color for SOLID borders and the caption text - * color for etched borders. + * Sets the current color for SOLID borders and the caption text color for etched borders. * * @param color The new color. */ public HolidayBorderPanel setColor(Color color) { this.color = color; - if (style == SOLID || style == IN || style == OUT) - repaint(); + if (style == SOLID || style == IN || style == OUT) repaint(); return this; - } + } - /** - * Gets the current color for SOLID borders and the caption - * text color for etched borders. - */ + /** Gets the current color for SOLID borders and the caption text color for etched borders. */ public Color getColor() { return color; - } + } - /** - * Sets the font. Only applies to etched borders. - */ + /** Sets the font. Only applies to etched borders. */ public HolidayBorderPanel setTextFont(Font font) { // set font @@ -299,24 +301,22 @@ public HolidayBorderPanel setTextFont(Font font) { if (style == IN || style == OUT) { doLayout(); repaint(); - } } + } return this; - } + } - /** - * Gets the font of the text. Only applies to etched borders. - */ + /** Gets the font of the text. Only applies to etched borders. */ public Font getTextFont() { return font; - } + } /** * Sets the text. Only applies to etched borders. * - * @param text The new text. + * @param text The new text. */ public HolidayBorderPanel setText(String text) { @@ -324,18 +324,16 @@ public HolidayBorderPanel setText(String text) { if (style == IN || style == OUT) { doLayout(); repaint(); - } + } return this; - } + } - /** - * Gets the text. Only applies to etched borders. - */ + /** Gets the text. Only applies to etched borders. */ public String getText() { return text; - } + } /** * Sets the text alignment. Only applies to etched borders. @@ -348,18 +346,16 @@ public HolidayBorderPanel setAlignment(int alignment) { if (style == IN || style == OUT) { doLayout(); repaint(); - } + } return this; - } + } - /** - * Gets the text alignment. - */ + /** Gets the text alignment. */ public int getAlignment() { return alignment; - } + } /** * Repaints the border. @@ -379,7 +375,7 @@ public void paint(Graphics g) { // Draw border switch (style) { - case RAISED: // 3D Border (in or out) + case RAISED: // 3D Border (in or out) case LOWERED: Color topleft = null; Color bottomright = null; @@ -388,26 +384,25 @@ public void paint(Graphics g) { if (style == RAISED) { topleft = light; bottomright = dark; - } - else { + } else { topleft = dark; bottomright = light; - } + } // draw border g.setColor(topleft); for (int i = 0; i < thickness; i++) { g.drawLine(i, i, width - i - 2, i); g.drawLine(i, i + 1, i, height - i - 1); - } + } g.setColor(bottomright); for (int i = 0; i < thickness; i++) { g.drawLine(i + 1, height - i - 1, width - i - 1, height - i - 1); g.drawLine(width - i - 1, i, width - i - 1, height - i - 2); - } + } break; - case IN: // Etched Border (in or out) + case IN: // Etched Border (in or out) case OUT: int adjust1 = 0; int adjust2 = 0; @@ -419,17 +414,14 @@ public void paint(Graphics g) { int ascent = fm.getAscent(); // set adjustment - if (style == IN) - adjust1 = 1; - else - adjust2 = 1; + if (style == IN) adjust1 = 1; + else adjust2 = 1; // Calculate adjustment for text int adjustment = 0; if (text != null && text.length() > 0) { - if (ascent > thickness) - adjustment = (ascent - thickness) / 2; - } + if (ascent > thickness) adjustment = (ascent - thickness) / 2; + } // The adjustment is there so that we always draw the // light rectangle first. Otherwise, your eye picks up @@ -453,8 +445,7 @@ public void paint(Graphics g) { int strwidth = fm.stringWidth(text); int textwidth = width - 2 * (thickness + 5); - if (strwidth > textwidth) - strwidth = textwidth; + if (strwidth > textwidth) strwidth = textwidth; // calculate offset for alignment int offset; @@ -469,10 +460,10 @@ public void paint(Graphics g) { default: // assume left alignment if invalid offset = thickness + 5; break; - } + } // clear drawing area and set clipping region - g.clearRect(offset - 5, 0, strwidth + 10, fontheight); + g.clearRect(offset - 5, 0, strwidth + 10, fontheight); g.clipRect(offset, 0, strwidth, fontheight); // draw text @@ -481,7 +472,7 @@ public void paint(Graphics g) { // restore old clipping area g.clipRect(0, 0, width, height); - } + } g.setFont(oldfont); break; @@ -491,26 +482,34 @@ public void paint(Graphics g) { g.setColor(color); for (int i = 0; i < thickness; i++) g.drawRect(i, i, width - 2 * i - 1, height - 2 * i - 1); - } - } + } - /** - * Returns the settings of this HolidayBorderPanel instance as a string. - */ + /** Returns the settings of this HolidayBorderPanel instance as a string. */ public String toString() { StringBuffer str = new StringBuffer("HolidayBorderPanel["); // style str.append("style="); switch (style) { - case SOLID: str.append("SOLID"); break; - case RAISED: str.append("RAISED"); break; - case LOWERED: str.append("LOWERED"); break; - case IN: str.append("IN"); break; - case OUT: str.append("OUT"); break; - default: str.append("unknown"); - } + case SOLID: + str.append("SOLID"); + break; + case RAISED: + str.append("RAISED"); + break; + case LOWERED: + str.append("LOWERED"); + break; + case IN: + str.append("IN"); + break; + case OUT: + str.append("OUT"); + break; + default: + str.append("unknown"); + } str.append(","); // thickness @@ -539,16 +538,21 @@ public String toString() { // alignment str.append("alignment="); switch (alignment) { - case LEFT: str.append("LEFT"); break; - case CENTER: str.append("CENTER"); break; - case RIGHT: str.append("RIGHT"); break; - default: str.append("unknown"); - } + case LEFT: + str.append("LEFT"); + break; + case CENTER: + str.append("CENTER"); + break; + case RIGHT: + str.append("RIGHT"); + break; + default: + str.append("unknown"); + } str.append("]"); return str.toString(); - } - } - +} diff --git a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/holiday/HolidayCalendarDemo.java b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/holiday/HolidayCalendarDemo.java index 068696a99f1f..e3ed9bbe1fc1 100644 --- a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/holiday/HolidayCalendarDemo.java +++ b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/holiday/HolidayCalendarDemo.java @@ -9,6 +9,13 @@ package com.ibm.icu.dev.demo.holiday; +import com.ibm.icu.dev.demo.impl.DemoApplet; +import com.ibm.icu.dev.demo.impl.DemoTextBox; +import com.ibm.icu.dev.demo.impl.DemoUtility; +import com.ibm.icu.text.DateTimePatternGenerator; +import com.ibm.icu.text.SimpleDateFormat; +import com.ibm.icu.util.Calendar; +import com.ibm.icu.util.Holiday; import java.awt.BorderLayout; import java.awt.Button; import java.awt.Canvas; @@ -36,27 +43,14 @@ import java.util.Locale; import java.util.Vector; -import com.ibm.icu.dev.demo.impl.DemoApplet; -import com.ibm.icu.dev.demo.impl.DemoTextBox; -import com.ibm.icu.dev.demo.impl.DemoUtility; -import com.ibm.icu.text.DateTimePatternGenerator; -import com.ibm.icu.text.SimpleDateFormat; -import com.ibm.icu.util.Calendar; -import com.ibm.icu.util.Holiday; - -/** - * CalendarDemo demonstrates how Calendar works. - */ -public class HolidayCalendarDemo extends DemoApplet -{ - /** - * For serialization - */ +/** CalendarDemo demonstrates how Calendar works. */ +public class HolidayCalendarDemo extends DemoApplet { + /** For serialization */ private static final long serialVersionUID = 4546085430817359372L; /** - * The main function which defines the behavior of the CalendarDemo - * applet when an applet is started. + * The main function which defines the behavior of the CalendarDemo applet when an applet is + * started. */ public static void main(String argv[]) { @@ -69,33 +63,28 @@ public Frame createDemoFrame(DemoApplet applet) { } /** - * A Frame is a top-level window with a title. The default layout for a frame - * is BorderLayout. The CalendarFrame class defines the window layout of - * CalendarDemo. - */ - private static class CalendarFrame extends Frame implements ActionListener, - ItemListener - { - /** - * For serialization - */ + * A Frame is a top-level window with a title. The default layout for a frame is BorderLayout. + * The CalendarFrame class defines the window layout of CalendarDemo. + */ + private static class CalendarFrame extends Frame implements ActionListener, ItemListener { + /** For serialization */ private static final long serialVersionUID = -7023296782393042761L; private static final boolean DEBUG = false; - //private Locale curLocale = Locale.US; // unused + // private Locale curLocale = Locale.US; // unused private DemoApplet applet; private static final Locale[] calendars = { - //new Locale("de","AT"), + // new Locale("de","AT"), Locale.CANADA, Locale.CANADA_FRENCH, Locale.FRANCE, Locale.GERMANY, - new Locale("iw","IL"), - new Locale("el","GR"), - //new Locale("es","MX"), + new Locale("iw", "IL"), + new Locale("el", "GR"), + // new Locale("es","MX"), Locale.UK, Locale.US, }; @@ -105,18 +94,15 @@ private static class CalendarFrame extends Frame implements ActionListener, Locale.US, Locale.FRANCE, Locale.CANADA_FRENCH, - //new Locale("de","AT"), + // new Locale("de","AT"), Locale.GERMAN, - new Locale("el","GR"), - //new Locale("iw","IL"), - new Locale("es","MX"), + new Locale("el", "GR"), + // new Locale("iw","IL"), + new Locale("es", "MX"), }; - /** - * Constructs a new CalendarFrame that is initially invisible. - */ - public CalendarFrame(DemoApplet applet) - { + /** Constructs a new CalendarFrame that is initially invisible. */ + public CalendarFrame(DemoApplet applet) { super("Calendar Demo"); this.applet = applet; init(); @@ -125,11 +111,10 @@ public CalendarFrame(DemoApplet applet) } /** - * Initializes the applet. You never need to call this directly, it - * is called automatically by the system once the applet is created. - */ - public void init() - { + * Initializes the applet. You never need to call this directly, it is called automatically + * by the system once the applet is created. + */ + public void init() { // Get G7 locales only for demo purpose. To get all the locales // supported, switch to calling Calendar.getAvailableLocales(). // commented @@ -138,49 +123,45 @@ public void init() buildGUI(); } - //------------------------------------------------------------ + // ------------------------------------------------------------ // package private - //------------------------------------------------------------ + // ------------------------------------------------------------ void addWithFont(Container container, Component foo, Font font) { - if (font != null) - foo.setFont(font); + if (font != null) foo.setFont(font); container.add(foo); } /** - * Called to start the applet. You never need to call this method - * directly, it is called when the applet's document is visited. - */ - public void start() - { + * Called to start the applet. You never need to call this method directly, it is called + * when the applet's document is visited. + */ + public void start() { // do nothing } - private Choice localeMenu; - private Choice displayMenu; - private Locale[] locales; + private Choice localeMenu; + private Choice displayMenu; + private Locale[] locales; - private Label monthLabel; - private Button prevYear; - private Button prevMonth; - private Button gotoToday; - private Button nextMonth; - private Button nextYear; - private CalendarPanel calendarPanel; + private Label monthLabel; + private Button prevYear; + private Button prevMonth; + private Button gotoToday; + private Button nextMonth; + private Button nextYear; + private CalendarPanel calendarPanel; private static final Locale kFirstLocale = Locale.US; - private static void add(Container container, Component component, - GridBagLayout g, GridBagConstraints c) - { + private static void add( + Container container, Component component, GridBagLayout g, GridBagConstraints c) { g.setConstraints(component, c); container.add(component); } - public void buildGUI() - { + public void buildGUI() { setBackground(DemoUtility.bgColor); - setLayout(new BorderLayout(10,10)); + setLayout(new BorderLayout(10, 10)); // Label for the demo's title Label titleLabel = new Label("Calendar Demo", Label.CENTER); @@ -188,55 +169,58 @@ public void buildGUI() // Label for the current month name monthLabel = new Label("", Label.LEFT); - monthLabel.setFont(new Font(DemoUtility.titleFont.getName(), - DemoUtility.titleFont.getStyle(), - (DemoUtility.titleFont.getSize() * 3)/2)); + monthLabel.setFont( + new Font( + DemoUtility.titleFont.getName(), + DemoUtility.titleFont.getStyle(), + (DemoUtility.titleFont.getSize() * 3) / 2)); // Make the locale popup menus - localeMenu= new Choice(); + localeMenu = new Choice(); localeMenu.addItemListener(this); int selectMe = 0; - + for (int i = 0; i < calendars.length; i++) { - if (i > 0 && - calendars[i].getCountry().equals(calendars[i-1].getCountry()) || - i < calendars.length - 1 && - calendars[i].getCountry().equals(calendars[i+1].getCountry())) - { - localeMenu.addItem(calendars[i].getDisplayCountry() + " (" + - calendars[i].getDisplayLanguage() + ")"); + if (i > 0 && calendars[i].getCountry().equals(calendars[i - 1].getCountry()) + || i < calendars.length - 1 + && calendars[i] + .getCountry() + .equals(calendars[i + 1].getCountry())) { + localeMenu.addItem( + calendars[i].getDisplayCountry() + + " (" + + calendars[i].getDisplayLanguage() + + ")"); } else { - localeMenu.addItem( calendars[i].getDisplayCountry() ); + localeMenu.addItem(calendars[i].getDisplayCountry()); } - + if (calendars[i].equals(kFirstLocale)) { selectMe = i; } } - + localeMenu.setBackground(DemoUtility.choiceColor); localeMenu.select(selectMe); displayMenu = new Choice(); displayMenu.addItemListener(this); - + selectMe = 0; for (int i = 0; i < locales.length; i++) { - if (i > 0 && - locales[i].getLanguage().equals(locales[i-1].getLanguage()) || - i < locales.length - 1 && - locales[i].getLanguage().equals(locales[i+1].getLanguage())) - { - displayMenu.addItem( locales[i].getDisplayName() ); + if (i > 0 && locales[i].getLanguage().equals(locales[i - 1].getLanguage()) + || i < locales.length - 1 + && locales[i].getLanguage().equals(locales[i + 1].getLanguage())) { + displayMenu.addItem(locales[i].getDisplayName()); } else { - displayMenu.addItem( locales[i].getDisplayLanguage()); + displayMenu.addItem(locales[i].getDisplayLanguage()); } - + if (locales[i].equals(kFirstLocale)) { selectMe = i; } } - + displayMenu.setBackground(DemoUtility.choiceColor); displayMenu.select(selectMe); @@ -310,7 +294,7 @@ public void buildGUI() { topPanel.setLayout(new BorderLayout()); - //topPanel.add("North", titleLabel); + // topPanel.add("North", titleLabel); topPanel.add("Center", monthPanel); topPanel.add("East", menuPanel); } @@ -322,84 +306,65 @@ public void buildGUI() add("South", copyright); // Now create the big calendar panel and stick it in the middle - calendarPanel = new CalendarPanel( kFirstLocale ); + calendarPanel = new CalendarPanel(kFirstLocale); add("Center", calendarPanel); updateMonthName(); } - private void updateMonthName() - { + private void updateMonthName() { final Locale displayLocale = calendarPanel.getDisplayLocale(); - final String pattern = DateTimePatternGenerator. - getInstance(displayLocale).getBestPattern("MMMMy"); - SimpleDateFormat f = new SimpleDateFormat(pattern, - displayLocale); + final String pattern = + DateTimePatternGenerator.getInstance(displayLocale).getBestPattern("MMMMy"); + SimpleDateFormat f = new SimpleDateFormat(pattern, displayLocale); f.setCalendar(calendarPanel.getCalendar()); - monthLabel.setText( f.format( calendarPanel.firstOfMonth() )); + monthLabel.setText(f.format(calendarPanel.firstOfMonth())); } - + /** - * Handles the event. Returns true if the event is handled and should not - * be passed to the parent of this component. The default event handler - * calls some helper methods to make life easier on the programmer. - */ - public void actionPerformed(ActionEvent e) - { + * Handles the event. Returns true if the event is handled and should not be passed to the + * parent of this component. The default event handler calls some helper methods to make + * life easier on the programmer. + */ + public void actionPerformed(ActionEvent e) { Object obj = e.getSource(); - + // *** Button events are handled here. if (obj instanceof Button) { if (obj == nextMonth) { calendarPanel.add(Calendar.MONTH, +1); - } - else - if (obj == prevMonth) { + } else if (obj == prevMonth) { calendarPanel.add(Calendar.MONTH, -1); - } - else - if (obj == prevYear) { + } else if (obj == prevYear) { calendarPanel.add(Calendar.YEAR, -1); - } - else - if (obj == nextYear) { + } else if (obj == nextYear) { calendarPanel.add(Calendar.YEAR, +1); - } - else - if (obj == gotoToday) { - calendarPanel.set( new Date() ); + } else if (obj == gotoToday) { + calendarPanel.set(new Date()); } updateMonthName(); } } - - public void itemStateChanged(ItemEvent e) - { + + public void itemStateChanged(ItemEvent e) { Object obj = e.getSource(); if (obj == localeMenu) { calendarPanel.setCalendarLocale(calendars[localeMenu.getSelectedIndex()]); updateMonthName(); + } else if (obj == displayMenu) { + calendarPanel.setDisplayLocale(locales[displayMenu.getSelectedIndex()]); + updateMonthName(); } - else - if (obj == displayMenu) { - calendarPanel.setDisplayLocale(locales[displayMenu.getSelectedIndex()]); - updateMonthName(); - } } - - /** - * Print out the error message while debugging this program. - */ - public void errorText(String s) - { - if (DEBUG) - { + + /** Print out the error message while debugging this program. */ + public void errorText(String s) { + if (DEBUG) { System.out.println(s); } } - - protected void processWindowEvent(WindowEvent e) - { + + protected void processWindowEvent(WindowEvent e) { System.out.println("event " + e); if (e.getID() == WindowEvent.WINDOW_CLOSING) { this.hide(); @@ -414,15 +379,12 @@ protected void processWindowEvent(WindowEvent e) } } - private static class CalendarPanel extends Canvas { - /** - * For serialization - */ + /** For serialization */ private static final long serialVersionUID = 1521099412250120821L; - public CalendarPanel( Locale locale ) { + public CalendarPanel(Locale locale) { set(locale, locale, new Date()); } @@ -438,8 +400,7 @@ public void set(Date date) { set(fCalendarLocale, fDisplayLocale, date); } - public void set(Locale loc, Locale display, Date date) - { + public void set(Locale loc, Locale display, Date date) { if (fCalendarLocale == null || !loc.equals(fCalendarLocale)) { fCalendarLocale = loc; fCalendar = Calendar.getInstance(fCalendarLocale); @@ -456,9 +417,8 @@ public void set(Locale loc, Locale display, Date date) repaint(); } - public void add(int field, int delta) - { - synchronized(fCalendar) { + public void add(int field, int delta) { + synchronized (fCalendar) { fCalendar.setTime(fStartOfMonth); fCalendar.add(field, delta); fStartOfMonth = fCalendar.getTime(); @@ -479,15 +439,13 @@ public Locale getDisplayLocale() { return fDisplayLocale; } - public Date firstOfMonth() { return fStartOfMonth; } - private Date startOfMonth(Date dateInMonth) - { - synchronized(fCalendar) { - fCalendar.setTime(dateInMonth); // TODO: synchronization + private Date startOfMonth(Date dateInMonth) { + synchronized (fCalendar) { + fCalendar.setTime(dateInMonth); // TODO: synchronization int era = fCalendar.get(Calendar.ERA); int year = fCalendar.get(Calendar.YEAR); @@ -503,9 +461,8 @@ private Date startOfMonth(Date dateInMonth) } } - private void calculate() - { - Calendar c = (Calendar)fCalendar.clone(); // Temporary copy + private void calculate() { + Calendar c = (Calendar) fCalendar.clone(); // Temporary copy fStartOfMonth = startOfMonth(fStartOfMonth); @@ -528,7 +485,7 @@ private void calculate() // Finally, find the end of the month, i.e. the start of the next one c.roll(Calendar.DATE, true); c.add(Calendar.MONTH, 1); - c.getTime(); // JDK 1.1.2 bug workaround + c.getTime(); // JDK 1.1.2 bug workaround c.add(Calendar.SECOND, -1); Date endOfMonth = c.getTime(); @@ -543,21 +500,30 @@ private void calculate() // to save the trouble of having to do it later fHolidays.setSize(0); - for (int h = 0; h < fAllHolidays.length; h++) - { + for (int h = 0; h < fAllHolidays.length; h++) { Date d = fStartOfMonth; - while ( (d = fAllHolidays[h].firstBetween(d, endOfMonth) ) != null) - { - if(d.after(endOfMonth)) { - throw new InternalError("Error: for " + fAllHolidays[h].getDisplayName()+ - " #" + h + "/"+fAllHolidays.length+": " + d +" is after end of month " + endOfMonth); + while ((d = fAllHolidays[h].firstBetween(d, endOfMonth)) != null) { + if (d.after(endOfMonth)) { + throw new InternalError( + "Error: for " + + fAllHolidays[h].getDisplayName() + + " #" + + h + + "/" + + fAllHolidays.length + + ": " + + d + + " is after end of month " + + endOfMonth); } c.setTime(d); - fHolidays.addElement( new HolidayInfo(c.get(Calendar.DATE), - fAllHolidays[h], - fAllHolidays[h].getDisplayName(fDisplayLocale) )); + fHolidays.addElement( + new HolidayInfo( + c.get(Calendar.DATE), + fAllHolidays[h], + fAllHolidays[h].getDisplayName(fDisplayLocale))); - d.setTime( d.getTime() + 1000 ); // "d++" + d.setTime(d.getTime() + 1000); // "d++" } } dirty = false; @@ -566,11 +532,10 @@ private void calculate() static final int INSET = 2; /* - * Convert from the day number within a month (1-based) - * to the cell coordinates on the calendar (0-based) - */ - private void dateToCell(int date, Point pos) - { + * Convert from the day number within a month (1-based) + * to the cell coordinates on the calendar (0-based) + */ + private void dateToCell(int date, Point pos) { int cell = (date + firstDayInMonth - firstDayOfWeek - minDay); if (firstDayInMonth < firstDayOfWeek) { cell += daysInWeek; @@ -579,8 +544,9 @@ private void dateToCell(int date, Point pos) pos.x = cell % daysInWeek; pos.y = cell / daysInWeek; } + private Point dateToCell(int date) { - Point p = new Point(0,0); + Point p = new Point(0, 0); dateToCell(date, p); return p; } @@ -591,11 +557,11 @@ public void paint(Graphics g) { calculate(); } - Point cellPos = new Point(0,0); // Temporary variable + Point cellPos = new Point(0, 0); // Temporary variable Dimension d = getSize(); g.setColor(DemoUtility.bgColor); - g.fillRect(0,0,d.width,d.height); + g.fillRect(0, 0, d.width, d.height); // Draw the day names at the top g.setColor(Color.black); @@ -615,7 +581,7 @@ public void paint(Graphics g) { } double cellHeight = (d.height - labelHeight - 1) / numWeeks; - double cellWidth = (double)(d.width - 1) / daysInWeek; + double cellWidth = (double) (d.width - 1) / daysInWeek; // Draw a white background in the part of the calendar // that displays this month. @@ -623,40 +589,44 @@ public void paint(Graphics g) { { g.setColor(Color.white); dateToCell(1, cellPos); - int width = (int)(cellPos.x*cellWidth); // Width of unshaded area + int width = (int) (cellPos.x * cellWidth); // Width of unshaded area - g.fillRect((int)(width), labelHeight , - (int)(d.width - width), (int)cellHeight); + g.fillRect((int) (width), labelHeight, (int) (d.width - width), (int) cellHeight); // All of the intermediate weeks get shaded completely - g.fillRect(0, (int)(labelHeight + cellHeight), - d.width, (int)(cellHeight * (numWeeks - 2))); + g.fillRect( + 0, + (int) (labelHeight + cellHeight), + d.width, + (int) (cellHeight * (numWeeks - 2))); // Now figure out the last week. dateToCell(daysInMonth, cellPos); - width = (int)((cellPos.x+1)*cellWidth); // Width of shaded area - - g.fillRect(0, (int)(labelHeight + (numWeeks-1) * cellHeight), - width, (int)(cellHeight)); + width = (int) ((cellPos.x + 1) * cellWidth); // Width of shaded area + g.fillRect( + 0, + (int) (labelHeight + (numWeeks - 1) * cellHeight), + width, + (int) (cellHeight)); } // Draw the X/Y grid lines g.setColor(Color.black); for (int i = 0; i <= numWeeks; i++) { - int y = (int)(labelHeight + i * cellHeight); + int y = (int) (labelHeight + i * cellHeight); g.drawLine(0, y, d.width - 1, y); } for (int i = 0; i <= daysInWeek; i++) { - int x = (int)(i * cellWidth); + int x = (int) (i * cellWidth); g.drawLine(x, labelHeight, x, d.height - 1); } // Now loop through all of the days in the month, figure out where // they go in the grid, and draw the day # for each one - Font numberFont = new Font("Helvetica",Font.PLAIN,12); + Font numberFont = new Font("Helvetica", Font.PLAIN, 12); // not used Font holidayFont = DemoUtility.creditFont; - Calendar c = (Calendar)fCalendar.clone(); + Calendar c = (Calendar) fCalendar.clone(); c.setTime(fStartOfMonth); for (int i = 1, h = 0; i <= daysInMonth; i++) { @@ -665,8 +635,8 @@ public void paint(Graphics g) { fm = g.getFontMetrics(); dateToCell(i, cellPos); - int x = (int)((cellPos.x + 1) * cellWidth); - int y = (int)(cellPos.y * cellHeight + labelHeight); + int x = (int) ((cellPos.x + 1) * cellWidth); + int y = (int) (cellPos.y * cellHeight + labelHeight); StringBuffer buffer = new StringBuffer(); buffer.append(i); @@ -681,18 +651,17 @@ public void paint(Graphics g) { HolidayInfo info = null; // Coordinates of lower-left corner of cell. - x = (int)((cellPos.x) * cellWidth); - y = (int)((cellPos.y+1) * cellHeight) + labelHeight; + x = (int) ((cellPos.x) * cellWidth); + y = (int) ((cellPos.y + 1) * cellHeight) + labelHeight; - while (h < fHolidays.size() && - (info = (HolidayInfo)fHolidays.elementAt(h)).date <= i) - { + while (h < fHolidays.size() + && (info = (HolidayInfo) fHolidays.elementAt(h)).date <= i) { if (info.date == i) { // Draw the holiday here. g.setFont(numberFont); g.setColor(Color.red); - DemoTextBox box = new DemoTextBox(g, info.name, (int)(cellWidth - INSET)); + DemoTextBox box = new DemoTextBox(g, info.name, (int) (cellWidth - INSET)); box.draw(g, x + INSET, y - INSET - box.getHeight()); y -= (box.getHeight() + INSET); @@ -703,24 +672,24 @@ public void paint(Graphics g) { } // Important state variables - private Locale fCalendarLocale; // Whose calendar - private Calendar fCalendar; // Calendar for calculations + private Locale fCalendarLocale; // Whose calendar + private Calendar fCalendar; // Calendar for calculations - private Locale fDisplayLocale; // How to display it - private DateFormatSymbols fSymbols; // Symbols for drawing + private Locale fDisplayLocale; // How to display it + private DateFormatSymbols fSymbols; // Symbols for drawing - private Date fStartOfMonth; // 00:00:00 on first day of month + private Date fStartOfMonth; // 00:00:00 on first day of month // Cached calculations to make drawing faster. - private transient int minDay; // Minimum legal day # - private transient int daysInWeek; // # of days in a week - private transient int firstDayOfWeek; // First day to display in week - private transient int numWeeks; // # full or partial weeks in month - private transient int daysInMonth; // # days in this month - private transient int firstDayInMonth; // Day of week of first day in month + private transient int minDay; // Minimum legal day # + private transient int daysInWeek; // # of days in a week + private transient int firstDayOfWeek; // First day to display in week + private transient int numWeeks; // # full or partial weeks in month + private transient int daysInMonth; // # days in this month + private transient int firstDayInMonth; // Day of week of first day in month private transient Holiday[] fAllHolidays; - private transient Vector fHolidays = new Vector(5,5); + private transient Vector fHolidays = new Vector(5, 5); private transient boolean dirty = true; } @@ -737,4 +706,3 @@ public HolidayInfo(int date, Holiday holiday, String name) { public String name; } } - diff --git a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/impl/AppletFrame.java b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/impl/AppletFrame.java index 42ee8172badd..5874558437a0 100644 --- a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/impl/AppletFrame.java +++ b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/impl/AppletFrame.java @@ -7,6 +7,7 @@ ******************************************************************************* */ package com.ibm.icu.dev.demo.impl; + import java.applet.Applet; import java.applet.AppletContext; import java.applet.AppletStub; @@ -39,17 +40,15 @@ */ public class AppletFrame extends Frame implements AppletStub, AppletContext { - /** - * For serialization - */ + /** For serialization */ private static final long serialVersionUID = 818828281190757725L; + Applet applet; /** - * Construct a Frame running the given Applet with the default size - * of 640 by 480. - * When the Frame is closed, the applet's stop() method is called, - * the Frame is dispose()d of, and System.exit(0) is called. + * Construct a Frame running the given Applet with the default size of 640 by 480. When the + * Frame is closed, the applet's stop() method is called, the Frame is dispose()d of, and + * System.exit(0) is called. * * @param name the Frame title * @param applet the applet to be run @@ -59,9 +58,8 @@ public AppletFrame(String name, Applet applet) { } /** - * Construct a Frame running the given Applet with the given size. - * When the Frame is closed, the applet's stop() method is called, - * the Frame is dispose()d of, and System.exit(0) is called. + * Construct a Frame running the given Applet with the given size. When the Frame is closed, the + * applet's stop() method is called, the Frame is dispose()d of, and System.exit(0) is called. * * @param name the Frame title * @param applet the applet to be run @@ -76,13 +74,14 @@ public AppletFrame(String name, Applet applet, int width, int height) { setSize(width, height); add("Center", applet); show(); - addWindowListener(new WindowAdapter() { - public void windowClosing(WindowEvent e) { - AppletFrame.this.applet.stop(); - dispose(); - System.exit(0); - } - }); + addWindowListener( + new WindowAdapter() { + public void windowClosing(WindowEvent e) { + AppletFrame.this.applet.stop(); + dispose(); + System.exit(0); + } + }); applet.init(); applet.start(); @@ -104,7 +103,7 @@ public URL getCodeBase() { public URL getDocumentBase() { return null; } - + public String getParameter(String name) { return "PARAMETER"; } @@ -112,8 +111,7 @@ public String getParameter(String name) { public boolean isActive() { return true; } - - + // AppletContext API public Applet getApplet(String name) { return applet; @@ -132,19 +130,19 @@ public Image getImage(URL url) { } public void showDocument(URL url) {} + public void showDocument(URL url, String target) {} public void showStatus(String status) { System.out.println(status); } - - public void setStream(String key, InputStream stream) throws IOException { - } - + + public void setStream(String key, InputStream stream) throws IOException {} + public InputStream getStream(String key) { return null; } - + public Iterator getStreamKeys() { return null; } diff --git a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/impl/DemoApplet.java b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/impl/DemoApplet.java index f9cbf6c2c3cb..4fa1177f4885 100644 --- a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/impl/DemoApplet.java +++ b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/impl/DemoApplet.java @@ -18,41 +18,41 @@ public abstract class DemoApplet extends java.applet.Applet { private static final long serialVersionUID = -8983602961925702071L; - private Button demoButton; - private Frame demoFrame; + private Button demoButton; + private Frame demoFrame; private static int demoFrameCount = 0; protected abstract Frame createDemoFrame(DemoApplet applet); + protected Dimension getDefaultFrameSize(DemoApplet applet, Frame f) { return new Dimension(700, 550); } - //Create a button that will display the demo - public void init() - { + // Create a button that will display the demo + public void init() { setBackground(Color.white); demoButton = new Button("Demo"); demoButton.setBackground(Color.yellow); - add( demoButton ); + add(demoButton); - demoButton.addActionListener( new ActionListener() { - public void actionPerformed(ActionEvent e) { - if (e.getID() == ActionEvent.ACTION_PERFORMED) { - demoButton.setLabel("loading"); + demoButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + if (e.getID() == ActionEvent.ACTION_PERFORMED) { + demoButton.setLabel("loading"); - if (demoFrame == null) { - demoFrame = createDemoFrame(DemoApplet.this); - showDemo(); - } + if (demoFrame == null) { + demoFrame = createDemoFrame(DemoApplet.this); + showDemo(); + } - demoButton.setLabel("Demo"); - } - } - } ); + demoButton.setLabel("Demo"); + } + } + }); } - public void showDemo() - { + public void showDemo() { demoFrame = createDemoFrame(this); demoFrame.doLayout(); Dimension d = getDefaultFrameSize(this, demoFrame); @@ -61,22 +61,21 @@ public void showDemo() demoFrameOpened(); } - public void demoClosed() - { + public void demoClosed() { demoFrame = null; demoFrameClosed(); } public static void demoFrameOpened() { demoFrameCount++; - System.err.println("DemoFrameOpened, now at:"+demoFrameCount); + System.err.println("DemoFrameOpened, now at:" + demoFrameCount); } + public static void demoFrameClosed() { if (--demoFrameCount == 0) { - System.err.println("DemoFrameClosed, now at:"+demoFrameCount + " - quitting"); + System.err.println("DemoFrameClosed, now at:" + demoFrameCount + " - quitting"); System.exit(0); } - System.err.println("DemoFrameClosed, now at:"+demoFrameCount); + System.err.println("DemoFrameClosed, now at:" + demoFrameCount); } } - diff --git a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/impl/DemoTextBox.java b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/impl/DemoTextBox.java index 89e894e8e8aa..a82299fa7c02 100644 --- a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/impl/DemoTextBox.java +++ b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/impl/DemoTextBox.java @@ -8,38 +8,34 @@ */ package com.ibm.icu.dev.demo.impl; - import java.awt.FontMetrics; import java.awt.Graphics; import java.text.BreakIterator; public class DemoTextBox { - public DemoTextBox(Graphics g, String text, int width) - { + public DemoTextBox(Graphics g, String text, int width) { this.text = text; this.chars = new char[text.length()]; text.getChars(0, text.length(), chars, 0); this.width = width; -// this.port = g; + // this.port = g; this.metrics = g.getFontMetrics(); breakText(); } - public int getHeight() { + public int getHeight() { return (nbreaks + 1) * metrics.getHeight(); } - public void draw(Graphics g, int x, int y) - { + public void draw(Graphics g, int x, int y) { int index = 0; y += metrics.getAscent(); - for (int i = 0; i < nbreaks; i++) - { + for (int i = 0; i < nbreaks; i++) { g.drawChars(chars, index, breakPos[i] - index, x, y); index = breakPos[i]; y += metrics.getHeight(); @@ -48,11 +44,8 @@ public void draw(Graphics g, int x, int y) g.drawChars(chars, index, chars.length - index, x, y); } - - private void breakText() - { - if (metrics.charsWidth(chars, 0, chars.length) > width) - { + private void breakText() { + if (metrics.charsWidth(chars, 0, chars.length) > width) { BreakIterator iter = BreakIterator.getWordInstance(); iter.setText(text); @@ -60,11 +53,9 @@ private void breakText() int end = start; int pos; - while ( (pos = iter.next()) != BreakIterator.DONE ) - { + while ((pos = iter.next()) != BreakIterator.DONE) { int w = metrics.charsWidth(chars, start, pos - start); - if (w > width) - { + if (w > width) { // We've gone past the maximum width, so break the line if (end > start) { // There was at least one break position before this point @@ -82,17 +73,16 @@ private void breakText() // tentative break position we have so far. end = pos; } - } } } - private String text; - private char[] chars; -// private Graphics port; - private FontMetrics metrics; - private int width; + private String text; + private char[] chars; + // private Graphics port; + private FontMetrics metrics; + private int width; - private int[] breakPos = new int[10]; // TODO: get real - private int nbreaks = 0; + private int[] breakPos = new int[10]; // TODO: get real + private int nbreaks = 0; } diff --git a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/impl/DemoUtility.java b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/impl/DemoUtility.java index 866de9058c08..61448fae6116 100644 --- a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/impl/DemoUtility.java +++ b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/impl/DemoUtility.java @@ -8,6 +8,7 @@ */ package com.ibm.icu.dev.demo.impl; +import com.ibm.icu.util.Calendar; import java.awt.Color; import java.awt.Component; import java.awt.Container; @@ -20,15 +21,12 @@ import java.awt.TextComponent; import java.util.Locale; -import com.ibm.icu.util.Calendar; - -public class DemoUtility -{ - public static final Font titleFont = new Font("TimesRoman",Font.BOLD,18); - public static final Font labelFont = new Font("TimesRoman",Font.BOLD,14); - public static final Font choiceFont = new Font("Helvetica",Font.BOLD,12); - public static final Font editFont = new Font("Helvetica",Font.PLAIN,14); - public static final Font creditFont = new Font("Helvetica",Font.PLAIN,10); +public class DemoUtility { + public static final Font titleFont = new Font("TimesRoman", Font.BOLD, 18); + public static final Font labelFont = new Font("TimesRoman", Font.BOLD, 14); + public static final Font choiceFont = new Font("Helvetica", Font.BOLD, 12); + public static final Font editFont = new Font("Helvetica", Font.PLAIN, 14); + public static final Font creditFont = new Font("Helvetica", Font.PLAIN, 10); public static final Font numberFont = new Font("sansserif", Font.PLAIN, 14); public static final Color bgColor = Color.lightGray; @@ -37,14 +35,17 @@ public class DemoUtility private static final int getCurrentYear() { return Calendar.getInstance().get(Calendar.YEAR); } + public static final String copyright1 = - "Copyright (C) IBM Corp and others. 1997 - "+getCurrentYear()+" All Rights Reserved"; + "Copyright (C) IBM Corp and others. 1997 - " + + getCurrentYear() + + " All Rights Reserved"; /** - Provides easy way to use basic functions of GridBagLayout, without - the complications. After building a panel, and inserting all the - * subcomponents, call this to lay it out in the desired number of columns. - */ + * Provides easy way to use basic functions of GridBagLayout, without the complications. After + * building a panel, and inserting all the subcomponents, call this to lay it out in the desired + * number of columns. + */ public static void fixGrid(Container cont, int columns) { GridBagLayout gridbag = new GridBagLayout(); cont.setLayout(gridbag); @@ -52,36 +53,40 @@ public static void fixGrid(Container cont, int columns) { GridBagConstraints c = new GridBagConstraints(); c.fill = GridBagConstraints.VERTICAL; c.weightx = 1.0; - c.insets = new Insets(2,2,2,2); + c.insets = new Insets(2, 2, 2, 2); Component[] components = cont.getComponents(); for (int i = 0; i < components.length; ++i) { // not used int colNumber = i%columns; - c.gridwidth = 1; // default - if ((i%columns) == columns - 1) - c.gridwidth = GridBagConstraints.REMAINDER; // last in grid + c.gridwidth = 1; // default + if ((i % columns) == columns - 1) + c.gridwidth = GridBagConstraints.REMAINDER; // last in grid if (components[i] instanceof Label) { - switch (((Label)components[i]).getAlignment()) { - case Label.CENTER: c.anchor = GridBagConstraints.CENTER; break; - case Label.LEFT: c.anchor = GridBagConstraints.WEST; break; - case Label.RIGHT: c.anchor = GridBagConstraints.EAST; break; + switch (((Label) components[i]).getAlignment()) { + case Label.CENTER: + c.anchor = GridBagConstraints.CENTER; + break; + case Label.LEFT: + c.anchor = GridBagConstraints.WEST; + break; + case Label.RIGHT: + c.anchor = GridBagConstraints.EAST; + break; } } gridbag.setConstraints(components[i], c); } - } /** - Provides easy way to change the spacing around an object in a GridBagLayout. - Call AFTER fixGridBag, passing in the container, the component, and the - new insets. - */ + * Provides easy way to change the spacing around an object in a GridBagLayout. Call AFTER + * fixGridBag, passing in the container, the component, and the new insets. + */ public static void setInsets(Container cont, Component comp, Insets insets) { - GridBagLayout gbl = (GridBagLayout)cont.getLayout(); + GridBagLayout gbl = (GridBagLayout) cont.getLayout(); GridBagConstraints g = gbl.getConstraints(comp); g.insets = insets; - gbl.setConstraints(comp,g); + gbl.setConstraints(comp, g); } public static Panel createSpacer() { @@ -97,38 +102,34 @@ public static void setText(TextComponent area, String newText) { if (foo.equals(newText)) return; area.setText(newText); } - + /** - * Compares two locals. Return value is negative - * if they're different, and more positive the more - * fields that match. + * Compares two locals. Return value is negative if they're different, and more positive the + * more fields that match. */ - - public static int compareLocales(Locale l1, Locale l2) - { + public static int compareLocales(Locale l1, Locale l2) { int result = -1; - + if (l1.getLanguage().equals(l2.getLanguage())) { result += 1; - + if (l1.getCountry().equals(l2.getCountry())) { result += 1; - + if (l1.getVariant().equals(l2.getVariant())) { result += 1; } } } - + return result; } - - /** - * Get the G7 locale list for demos. - */ + + /** Get the G7 locale list for demos. */ public static Locale[] getG7Locales() { return localeList; } + private static Locale[] localeList = { new Locale("DA", "DK", ""), new Locale("EN", "US", ""), @@ -138,6 +139,6 @@ public static Locale[] getG7Locales() { new Locale("FR", "CA", ""), new Locale("DE", "DE", ""), new Locale("IT", "IT", ""), - //new Locale("JA", "JP", ""), + // new Locale("JA", "JP", ""), }; } diff --git a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/impl/DumbTextComponent.java b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/impl/DumbTextComponent.java index 34351994e4d6..02706c53b899 100644 --- a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/impl/DumbTextComponent.java +++ b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/impl/DumbTextComponent.java @@ -7,6 +7,7 @@ ******************************************************************************* */ package com.ibm.icu.dev.demo.impl; + import java.awt.AWTEventMulticaster; import java.awt.Canvas; import java.awt.Color; @@ -37,17 +38,14 @@ // LIU: Changed from final to non-final public class DumbTextComponent extends Canvas - implements KeyListener, MouseListener, MouseMotionListener, FocusListener -{ - - /** - * For serialization - */ + implements KeyListener, MouseListener, MouseMotionListener, FocusListener { + + /** For serialization */ private static final long serialVersionUID = 8265547730738652151L; -// private transient static final String copyright = -// "Copyright \u00A9 1998, Mark Davis. All Rights Reserved."; - private transient static boolean DEBUG = false; + // private transient static final String copyright = + // "Copyright \u00A9 1998, Mark Davis. All Rights Reserved."; + private static transient boolean DEBUG = false; private String contents = ""; private Selection selection = new Selection(); @@ -82,8 +80,8 @@ public class DumbTextComponent extends Canvas private transient Point endPoint = new Point(); private transient Point caretPoint = new Point(); private transient Point activePoint = new Point(); - - //private transient static String clipBoard; + + // private transient static String clipBoard; private static final char CR = '\015'; // LIU @@ -95,10 +93,9 @@ public DumbTextComponent() { addKeyListener(this); addFocusListener(this); setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)); - } -// ================ Events ==================== + // ================ Events ==================== // public boolean isFocusTraversable() { return true; } @@ -123,7 +120,7 @@ public void removeTextListener(TextListener l) { public void mousePressed(MouseEvent e) { if (DEBUG) System.out.println("mousePressed"); if (pressed) { - select(e,false); + select(e, false); } else { doubleClick = e.getClickCount() > 1; requestFocus(); @@ -143,16 +140,16 @@ public void mouseReleased(MouseEvent e) { } public void mouseEntered(MouseEvent e) { - //if (pressed) select(e, false); + // if (pressed) select(e, false); } - public void mouseExited(MouseEvent e){ - //if (pressed) select(e, false); + public void mouseExited(MouseEvent e) { + // if (pressed) select(e, false); } public void mouseClicked(MouseEvent e) {} - public void mouseMoved(MouseEvent e) {} + public void mouseMoved(MouseEvent e) {} public void focusGained(FocusEvent e) { if (DEBUG) System.out.println("focusGained"); @@ -160,6 +157,7 @@ public void focusGained(FocusEvent e) { valid = false; repaint(16); } + public void focusLost(FocusEvent e) { if (DEBUG) System.out.println("focusLost"); focus = false; @@ -181,104 +179,105 @@ public void select(MouseEvent e, boolean first) { } select(tempSelection); } - + public void keyPressed(KeyEvent e) { int code = e.getKeyCode(); - if (DEBUG) System.out.println("keyPressed " - + hex((char)code) + ", " + hex((char)e.getModifiers())); + if (DEBUG) + System.out.println( + "keyPressed " + hex((char) code) + ", " + hex((char) e.getModifiers())); int start = selection.getStart(); int end = selection.getEnd(); boolean shift = (e.getModifiers() & InputEvent.SHIFT_MASK) != 0; boolean ctrl = (e.getModifiers() & InputEvent.CTRL_MASK) != 0; - + switch (code) { - case KeyEvent.VK_Q: - if (!ctrl || !editable) break; - setKeyStart(-1); - fixHex(); - break; - case KeyEvent.VK_V: - if (!ctrl) break; - if (!editable) { - this.getToolkit().beep(); - } else { - paste(); - } - break; - case KeyEvent.VK_C: - if (!ctrl) break; - copy(); - break; - case KeyEvent.VK_X: - if (!ctrl) break; - if (!editable) { - this.getToolkit().beep(); - } else { + case KeyEvent.VK_Q: + if (!ctrl || !editable) break; + setKeyStart(-1); + fixHex(); + break; + case KeyEvent.VK_V: + if (!ctrl) break; + if (!editable) { + this.getToolkit().beep(); + } else { + paste(); + } + break; + case KeyEvent.VK_C: + if (!ctrl) break; copy(); - insertText(""); - } - break; - case KeyEvent.VK_A: - if (!ctrl) break; - setKeyStart(-1); - select(Integer.MAX_VALUE, 0, false); - break; - case KeyEvent.VK_RIGHT: - setKeyStart(-1); - tempSelection.set(selection); - tempSelection.nextBound(ctrl ? wordBreaker : charBreaker, +1, shift); - select(tempSelection); - break; - case KeyEvent.VK_LEFT: - setKeyStart(-1); - tempSelection.set(selection); - tempSelection.nextBound(ctrl ? wordBreaker : charBreaker, -1, shift); - select(tempSelection); - break; - case KeyEvent.VK_UP: // LIU: Add support for up arrow - setKeyStart(-1); - tempSelection.set(selection); - tempSelection.caret = lineDelta(tempSelection.caret, -1); - if (!shift) { - tempSelection.anchor = tempSelection.caret; - } - select(tempSelection); - break; - case KeyEvent.VK_DOWN: // LIU: Add support for down arrow - setKeyStart(-1); - tempSelection.set(selection); - tempSelection.caret = lineDelta(tempSelection.caret, +1); - if (!shift) { - tempSelection.anchor = tempSelection.caret; - } - select(tempSelection); - break; - case KeyEvent.VK_DELETE: // LIU: Add delete key support - if (!editable) break; - setKeyStart(-1); - if (contents.length() == 0) break; - start = selection.getStart(); - end = selection.getEnd(); - if (start == end) { - ++end; - if (end > contents.length()) { - getToolkit().beep(); - return; + break; + case KeyEvent.VK_X: + if (!ctrl) break; + if (!editable) { + this.getToolkit().beep(); + } else { + copy(); + insertText(""); } - } - replaceRange("", start, end); - break; + break; + case KeyEvent.VK_A: + if (!ctrl) break; + setKeyStart(-1); + select(Integer.MAX_VALUE, 0, false); + break; + case KeyEvent.VK_RIGHT: + setKeyStart(-1); + tempSelection.set(selection); + tempSelection.nextBound(ctrl ? wordBreaker : charBreaker, +1, shift); + select(tempSelection); + break; + case KeyEvent.VK_LEFT: + setKeyStart(-1); + tempSelection.set(selection); + tempSelection.nextBound(ctrl ? wordBreaker : charBreaker, -1, shift); + select(tempSelection); + break; + case KeyEvent.VK_UP: // LIU: Add support for up arrow + setKeyStart(-1); + tempSelection.set(selection); + tempSelection.caret = lineDelta(tempSelection.caret, -1); + if (!shift) { + tempSelection.anchor = tempSelection.caret; + } + select(tempSelection); + break; + case KeyEvent.VK_DOWN: // LIU: Add support for down arrow + setKeyStart(-1); + tempSelection.set(selection); + tempSelection.caret = lineDelta(tempSelection.caret, +1); + if (!shift) { + tempSelection.anchor = tempSelection.caret; + } + select(tempSelection); + break; + case KeyEvent.VK_DELETE: // LIU: Add delete key support + if (!editable) break; + setKeyStart(-1); + if (contents.length() == 0) break; + start = selection.getStart(); + end = selection.getEnd(); + if (start == end) { + ++end; + if (end > contents.length()) { + getToolkit().beep(); + return; + } + } + replaceRange("", start, end); + break; } } void copy() { Clipboard cb = this.getToolkit().getSystemClipboard(); - StringSelection ss = new StringSelection( - contents.substring(selection.getStart(), selection.getEnd())); + StringSelection ss = + new StringSelection(contents.substring(selection.getStart(), selection.getEnd())); cb.setContents(ss, ss); } - - void paste () { + + void paste() { Clipboard cb = this.getToolkit().getSystemClipboard(); Transferable t = cb.getContents(this); if (t == null) { @@ -290,12 +289,12 @@ void paste () { insertText(temp); } catch (Exception e) { this.getToolkit().beep(); - } + } } /** - * LIU: Given an offset into contents, moves up or down by lines, - * according to lineStarts[]. + * LIU: Given an offset into contents, moves up or down by lines, according to lineStarts[]. + * * @param off the offset into contents * @param delta how many lines to move up (< 0) or down (> 0) * @return the new offset into contents @@ -311,62 +310,63 @@ private int lineDelta(int off, int delta) { return contents.length(); } off = lineStarts[line] + posInLine; - if (off >= lineStarts[line+1]) { - off = lineStarts[line+1] - 1; + if (off >= lineStarts[line + 1]) { + off = lineStarts[line + 1] - 1; } return off; } - + public void keyReleased(KeyEvent e) { int code = e.getKeyCode(); - if (DEBUG) System.out.println("keyReleased " - + hex((char)code) + ", " + hex((char)e.getModifiers())); + if (DEBUG) + System.out.println( + "keyReleased " + hex((char) code) + ", " + hex((char) e.getModifiers())); } public void keyTyped(KeyEvent e) { char ch = e.getKeyChar(); - if (DEBUG) System.out.println("keyTyped " - + hex((char)ch) + ", " + hex((char)e.getModifiers())); + if (DEBUG) + System.out.println("keyTyped " + hex((char) ch) + ", " + hex((char) e.getModifiers())); if ((e.getModifiers() & InputEvent.CTRL_MASK) != 0) return; int start, end; switch (ch) { - case KeyEvent.CHAR_UNDEFINED: - break; - case KeyEvent.VK_BACK_SPACE: - //setKeyStart(-1); - if (!editable) break; - if (contents.length() == 0) break; - start = selection.getStart(); - end = selection.getEnd(); - if (start == end) { - --start; - if (start < 0) { - getToolkit().beep(); // LIU: Add audio feedback of NOP - return; + case KeyEvent.CHAR_UNDEFINED: + break; + case KeyEvent.VK_BACK_SPACE: + // setKeyStart(-1); + if (!editable) break; + if (contents.length() == 0) break; + start = selection.getStart(); + end = selection.getEnd(); + if (start == end) { + --start; + if (start < 0) { + getToolkit().beep(); // LIU: Add audio feedback of NOP + return; + } } - } - replaceRange("", start, end); - break; - case KeyEvent.VK_DELETE: - //setKeyStart(-1); - if (!editable) break; - if (contents.length() == 0) break; - start = selection.getStart(); - end = selection.getEnd(); - if (start == end) { - ++end; - if (end > contents.length()) { - getToolkit().beep(); // LIU: Add audio feedback of NOP - return; + replaceRange("", start, end); + break; + case KeyEvent.VK_DELETE: + // setKeyStart(-1); + if (!editable) break; + if (contents.length() == 0) break; + start = selection.getStart(); + end = selection.getEnd(); + if (start == end) { + ++end; + if (end > contents.length()) { + getToolkit().beep(); // LIU: Add audio feedback of NOP + return; + } } - } - replaceRange("", start, end); - break; - default: - if (!editable) break; - // LIU: Dispatch to subclass API - handleKeyTyped(e); - break; + replaceRange("", start, end); + break; + default: + if (!editable) break; + // LIU: Dispatch to subclass API + handleKeyTyped(e); + break; } } @@ -374,26 +374,26 @@ public void keyTyped(KeyEvent e) { protected void handleKeyTyped(KeyEvent e) { insertText(String.valueOf(e.getKeyChar())); } - + protected void setKeyStart(int keyStart) { if (activeStart != keyStart) { activeStart = keyStart; repaint(10); } } - + protected void validateKeyStart() { if (activeStart > selection.getStart()) { activeStart = selection.getStart(); repaint(10); } } - + protected int getKeyStart() { return activeStart; } -// ===================== Control ====================== + // ===================== Control ====================== public synchronized void setEditable(boolean b) { editable = b; @@ -409,8 +409,8 @@ public void select(Selection newSelection) { selection.set(newSelection); if (selectionListener != null) { selectionListener.actionPerformed( - new ActionEvent(this, ActionEvent.ACTION_PERFORMED, - "Selection Changed", 0)); + new ActionEvent( + this, ActionEvent.ACTION_PERFORMED, "Selection Changed", 0)); } repaint(10); valid = false; @@ -435,20 +435,20 @@ public int getSelectionEnd() { } public void setBounds(int x, int y, int w, int h) { - super.setBounds(x,y,w,h); + super.setBounds(x, y, w, h); redoLines = true; } public Dimension getPreferredSize() { - return new Dimension(lastWidth,lastHeight); + return new Dimension(lastWidth, lastHeight); } public Dimension getMaximumSize() { - return new Dimension(lastWidth,lastHeight); + return new Dimension(lastWidth, lastHeight); } public Dimension getMinimumSize() { - return new Dimension(lastHeight,lastHeight); + return new Dimension(lastHeight, lastHeight); } public void setText(String text) { @@ -463,8 +463,7 @@ public void setText2(String text) { lineBreaker.setText(text); redoLines = true; if (textListener != null) - textListener.textValueChanged( - new TextEvent(this, TextEvent.TEXT_VALUE_CHANGED)); + textListener.textValueChanged(new TextEvent(this, TextEvent.TEXT_VALUE_CHANGED)); repaint(16); } @@ -474,10 +473,8 @@ public void insertText(String text) { } public void replaceRange(String s, int start, int end) { - setText2(contents.substring(0,start) + s - + contents.substring(end)); - select(tempSelection.set(selection). - fixAfterReplace(start, end, s.length())); + setText2(contents.substring(0, start) + s + contents.substring(end)); + select(tempSelection.set(selection).fixAfterReplace(start, end, s.length())); validateKeyStart(); } @@ -501,8 +498,8 @@ public void update(Graphics g) { public void paint(Graphics g) { mySize = getSize(); if (cacheImage == null - || cacheImage.getHeight(this) != mySize.height - || cacheImage.getWidth(this) != mySize.width) { + || cacheImage.getHeight(this) != mySize.height + || cacheImage.getWidth(this) != mySize.width) { cacheImage = createImage(mySize.width, mySize.height); valid = false; } @@ -511,12 +508,19 @@ public void paint(Graphics g) { paint2(cacheImage.getGraphics()); valid = true; } - //getToolkit().sync(); + // getToolkit().sync(); if (DEBUG) System.out.println("copying"); - g.drawImage(cacheImage, - 0, 0, mySize.width, mySize.height, - 0, 0, mySize.width, mySize.height, - this); + g.drawImage( + cacheImage, + 0, + 0, + mySize.width, + mySize.height, + 0, + 0, + mySize.width, + mySize.height, + this); } public void paint2(Graphics g) { @@ -524,9 +528,8 @@ public void paint2(Graphics g) { if (DEBUG) System.out.println("print"); if (focus) g.setColor(Color.black); else g.setColor(Color.gray); - g.drawRect(0,0,mySize.width-1,mySize.height-1); - g.setClip(1,1, - mySize.width-2,mySize.height-2); + g.drawRect(0, 0, mySize.width - 1, mySize.height - 1); + g.setClip(1, 1, mySize.width - 2, mySize.height - 2); g.setColor(Color.black); g.setFont(getFont()); fm = g.getFontMetrics(); @@ -535,25 +538,24 @@ public void paint2(Graphics g) { lineHeight = lineAscent + fm.getDescent() + lineLeading; int y = yInset + lineAscent; String lastSubstring = ""; - if (redoLines) fixLineStarts(mySize.width-xInset-xInset); + if (redoLines) fixLineStarts(mySize.width - xInset - xInset); for (int i = 0; i < lineCount; y += lineHeight, ++i) { // LIU: Don't display terminating ^M characters - int lim = lineStarts[i+1]; - if (lim > 0 && contents.length() > 0 && - contents.charAt(lim-1) == CR) --lim; - lastSubstring = contents.substring(lineStarts[i],lim); + int lim = lineStarts[i + 1]; + if (lim > 0 && contents.length() > 0 && contents.charAt(lim - 1) == CR) --lim; + lastSubstring = contents.substring(lineStarts[i], lim); g.drawString(lastSubstring, xInset, y); } drawSelection(g, lastSubstring); lastHeight = y + yInset - lineHeight + yInset; - lastWidth = mySize.width-xInset-xInset; + lastWidth = mySize.width - xInset - xInset; } void paintRect(Graphics g, int x, int y, int w, int h) { if (focus) { g.fillRect(x, y, w, h); } else { - g.drawRect(x, y, w-1, h-1); + g.drawRect(x, y, w - 1, h - 1); } } @@ -572,19 +574,30 @@ public void drawSelection(Graphics g, String lastSubstring) { else g.setColor(Color.yellow); offset2Point(selection.getStart(), true, startPoint); offset2Point(selection.getEnd(), false, endPoint); - if (selection.getStart() == selection.caret) - caretPoint.setLocation(startPoint); + if (selection.getStart() == selection.caret) caretPoint.setLocation(startPoint); else caretPoint.setLocation(endPoint); if (startPoint.y == endPoint.y) { - paintRect(g, startPoint.x, startPoint.y, - Math.max(1,endPoint.x-startPoint.x), lineHeight); + paintRect( + g, + startPoint.x, + startPoint.y, + Math.max(1, endPoint.x - startPoint.x), + lineHeight); } else { - paintRect(g, startPoint.x, startPoint.y, - (mySize.width-xInset)-startPoint.x, lineHeight); + paintRect( + g, + startPoint.x, + startPoint.y, + (mySize.width - xInset) - startPoint.x, + lineHeight); if (startPoint.y + lineHeight < endPoint.y) - paintRect(g, xInset, startPoint.y + lineHeight, - (mySize.width-xInset)-xInset, endPoint.y - startPoint.y - lineHeight); - paintRect(g, xInset, endPoint.y, endPoint.x-xInset, lineHeight); + paintRect( + g, + xInset, + startPoint.y + lineHeight, + (mySize.width - xInset) - xInset, + endPoint.y - startPoint.y - lineHeight); + paintRect(g, xInset, endPoint.y, endPoint.x - xInset, lineHeight); } } if (focus || selection.isCaret()) { @@ -592,7 +605,7 @@ public void drawSelection(Graphics g, String lastSubstring) { else g.setColor(Color.red); int line = caretPoint.x - (selection.clickAfter ? 0 : 1); g.fillRect(line, caretPoint.y, 1, lineHeight); - int w = lineHeight/12 + 1; + int w = lineHeight / 12 + 1; int braces = line - (selection.clickAfter ? -1 : w); g.fillRect(braces, caretPoint.y, w, 1); g.fillRect(braces, caretPoint.y + lineHeight - 1, w, 1); @@ -603,14 +616,12 @@ public Point offset2Point(int off, boolean start, Point p) { int line = findLine(off, start); int width = 0; try { - width = fm.stringWidth( - contents.substring(lineStarts[line], off)); + width = fm.stringWidth(contents.substring(lineStarts[line], off)); } catch (Exception e) { System.out.println(e); } p.x = width + xInset; - if (p.x > mySize.width - xInset) - p.x = mySize.width - xInset; + if (p.x > mySize.width - xInset) p.x = mySize.width - xInset; p.y = lineHeight * line + yInset; return p; } @@ -621,14 +632,16 @@ private int findLine(int off, boolean start) { for (int i = 1; i < lineCount; ++i) { // LIU: This was <= ; changed to < to make caret after // final CR in line appear at START of next line. - if (off < lineStarts[i]) return i-1; + if (off < lineStarts[i]) return i - 1; } // LIU: Check for special case; after CR at end of the last line - if (off == lineStarts[lineCount] && - off > 0 && contents.length() > 0 && contents.charAt(off-1) == CR) { + if (off == lineStarts[lineCount] + && off > 0 + && contents.length() > 0 + && contents.charAt(off - 1) == CR) { return lineCount; } - return lineCount-1; + return lineCount - 1; } // offsets on any line will go from start,true to end,false @@ -639,7 +652,7 @@ public Selection point2Offset(Point p, Selection o) { o.clickAfter = true; return o; } - int line = (p.y - yInset)/lineHeight; + int line = (p.y - yInset) / lineHeight; if (line >= lineCount) { o.caret = contents.length(); o.clickAfter = false; @@ -653,16 +666,16 @@ public Selection point2Offset(Point p, Selection o) { } int lowGuess = lineStarts[line]; int lowWidth = 0; - int highGuess = lineStarts[line+1]; - int highWidth = fm.stringWidth(contents.substring(lineStarts[line],highGuess)); + int highGuess = lineStarts[line + 1]; + int highWidth = fm.stringWidth(contents.substring(lineStarts[line], highGuess)); if (target >= highWidth) { - o.caret = lineStarts[line+1]; + o.caret = lineStarts[line + 1]; o.clickAfter = false; return o; } while (lowGuess < highGuess - 1) { - int guess = (lowGuess + highGuess)/2; - int width = fm.stringWidth(contents.substring(lineStarts[line],guess)); + int guess = (lowGuess + highGuess) / 2; + int width = fm.stringWidth(contents.substring(lineStarts[line], guess)); if (width <= target) { lowGuess = guess; lowWidth = width; @@ -677,9 +690,9 @@ public Selection point2Offset(Point p, Selection o) { int lowBound = charBreaker.previous(); // we are now at character boundaries if (lowBound != lowGuess) - lowWidth = fm.stringWidth(contents.substring(lineStarts[line],lowBound)); + lowWidth = fm.stringWidth(contents.substring(lineStarts[line], lowBound)); if (highBound != highGuess) - highWidth = fm.stringWidth(contents.substring(lineStarts[line],highBound)); + highWidth = fm.stringWidth(contents.substring(lineStarts[line], highBound)); // we now have the right widths if (target - lowWidth < highWidth - target) { o.caret = lowBound; @@ -701,8 +714,7 @@ private void fixLineStarts(int width) { } int end = 0; // LIU: Add check for MAX_LINES - for (int start = 0; start < contents.length() && lineCount < MAX_LINES; - start = end) { + for (int start = 0; start < contents.length() && lineCount < MAX_LINES; start = end) { end = nextLine(fm, start, width); lineStarts[lineCount++] = end; if (end == start) { // LIU: Assertion @@ -721,14 +733,13 @@ public int nextLine(FontMetrics fMtr, int start, int width) { char ch = (contents.charAt(i)); if (ch >= 0x000A && ch <= 0x000D || ch == 0x2028 || ch == 0x2029) { len = i + 1; - if (ch == 0x000D && i+1 < len && contents.charAt(i+1) == 0x000A) // crlf - ++len; // grab extra char + if (ch == 0x000D && i + 1 < len && contents.charAt(i + 1) == 0x000A) // crlf + ++len; // grab extra char break; } } - String subject = contents.substring(start,len); - if (visibleWidth(fMtr, subject) <= width) - return len; + String subject = contents.substring(start, len); + if (visibleWidth(fMtr, subject) <= width) return len; // LIU: Remainder of this method rewritten to accommodate lines // longer than the component width by first trying to break @@ -744,23 +755,21 @@ public int nextLine(FontMetrics fMtr, int start, int width) { } /** - * LIU: Finds the longest substring that fits a given width - * composed of subunits returned by a BreakIterator. If the smallest - * subunit is too long, returns 0. + * LIU: Finds the longest substring that fits a given width composed of subunits returned by a + * BreakIterator. If the smallest subunit is too long, returns 0. + * * @param fMtr metrics to use * @param line the string to be fix into width * @param width line.substring(0, result) must be <= width * @param breaker the BreakIterator that will be used to find subunits - * @return maximum characters, at boundaries returned by breaker, - * that fit into width, or zero on failure + * @return maximum characters, at boundaries returned by breaker, that fit into width, or zero + * on failure */ - private int findFittingBreak(FontMetrics fMtr, String line, int width, - BreakIterator breaker) { + private int findFittingBreak(FontMetrics fMtr, String line, int width, BreakIterator breaker) { breaker.setText(line); int last = breaker.first(); int end = breaker.next(); - while (end != BreakIterator.DONE && - visibleWidth(fMtr, line.substring(0, end)) <= width) { + while (end != BreakIterator.DONE && visibleWidth(fMtr, line.substring(0, end)) <= width) { last = end; end = breaker.next(); } @@ -769,24 +778,24 @@ private int findFittingBreak(FontMetrics fMtr, String line, int width, public int visibleWidth(FontMetrics fMtr, String s) { int i; - for (i = s.length()-1; i >= 0; --i) { + for (i = s.length() - 1; i >= 0; --i) { char ch = s.charAt(i); if (!(ch == ' ' || ch >= 0x000A && ch <= 0x000D || ch == 0x2028 || ch == 0x2029)) - return fMtr.stringWidth(s.substring(0,i+1)); + return fMtr.stringWidth(s.substring(0, i + 1)); } return 0; } -// =============== Utility ==================== + // =============== Utility ==================== private void fixHex() { if (selection.getEnd() == 0) return; int store = 0; int places = 1; int count = 0; - int min = Math.min(8,selection.getEnd()); + int min = Math.min(8, selection.getEnd()); for (int i = 0; i < min; ++i) { - char ch = contents.charAt(selection.getEnd()-1-i); + char ch = contents.charAt(selection.getEnd() - 1 - i); int value = Character.getNumericValue(ch); if (value < 0 || value > 15) break; store += places * value; @@ -795,35 +804,39 @@ private void fixHex() { } String add = ""; int bottom = store & 0xFFFF; - if (store >= 0xD8000000 && store < 0xDC000000 - && bottom >= 0xDC00 && bottom < 0xE000) { // surrogates - add = "" + (char)(store >> 16) + (char)bottom; + if (store >= 0xD8000000 + && store < 0xDC000000 + && bottom >= 0xDC00 + && bottom < 0xE000) { // surrogates + add = "" + (char) (store >> 16) + (char) bottom; } else if (store > 0xFFFF && store <= 0x10FFFF) { store -= 0x10000; - add = "" + (char)(((store >> 10) & 0x3FF) + 0xD800) - + (char)((store & 0x3FF) + 0xDC00); - + add = + "" + + (char) (((store >> 10) & 0x3FF) + 0xD800) + + (char) ((store & 0x3FF) + 0xDC00); + } else if (count >= 4) { count = 4; - add = ""+(char)(store & 0xFFFF); + add = "" + (char) (store & 0xFFFF); } else { count = 1; - char ch = contents.charAt(selection.getEnd()-1); + char ch = contents.charAt(selection.getEnd() - 1); add = hex(ch); if (ch >= 0xDC00 && ch <= 0xDFFF && selection.getEnd() > 1) { - ch = contents.charAt(selection.getEnd()-2); + ch = contents.charAt(selection.getEnd() - 2); if (ch >= 0xD800 && ch <= 0xDBFF) { count = 2; add = hex(ch) + add; } } } - replaceRange(add, selection.getEnd()-count, selection.getEnd()); + replaceRange(add, selection.getEnd() - count, selection.getEnd()); } public static String hex(char ch) { - String result = Integer.toString(ch,16).toUpperCase(); - result = "0000".substring(result.length(),4) + result; + String result = Integer.toString(ch, 16).toUpperCase(); + result = "0000".substring(result.length(), 4) + result; return result; } } diff --git a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/impl/Selection.java b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/impl/Selection.java index bc8db130d30a..bae502c6cf90 100644 --- a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/impl/Selection.java +++ b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/impl/Selection.java @@ -7,6 +7,7 @@ ******************************************************************************* */ package com.ibm.icu.dev.demo.impl; + import java.text.BreakIterator; public final class Selection { @@ -42,10 +43,8 @@ public Selection set(int anchor, int caret, boolean clickAfter) { } public boolean equals(Object other) { - Selection other2 = (Selection)other; - return anchor == other2.anchor - && caret == other2.caret - && clickAfter == other2.clickAfter; + Selection other2 = (Selection) other; + return anchor == other2.anchor && caret == other2.caret && clickAfter == other2.clickAfter; } public boolean isLessThan(Selection other) { @@ -93,21 +92,20 @@ public Selection fixAfterReplace(int start, int end, int len) { return this; } - // Mac & Windows considerably different - // Mac: end++. If start!=end, start=end - // SHIFT: move end right - // CTL: no different - // Windows: - // UNSHIFTED: if start!=end, start = end, else start=end=end+1; - // anchor = tip = start - // SHIFT: tip++ - // CTL: if start!=end, start = end = nextbound(end-1), - // else start=end=nextbound(end) - // anchor = tip = start - // CTL/SHIFT: tip = nextbound(tip) - - public Selection nextBound(BreakIterator breaker, - int direction, boolean extend) { + // Mac & Windows considerably different + // Mac: end++. If start!=end, start=end + // SHIFT: move end right + // CTL: no different + // Windows: + // UNSHIFTED: if start!=end, start = end, else start=end=end+1; + // anchor = tip = start + // SHIFT: tip++ + // CTL: if start!=end, start = end = nextbound(end-1), + // else start=end=nextbound(end) + // anchor = tip = start + // CTL/SHIFT: tip = nextbound(tip) + + public Selection nextBound(BreakIterator breaker, int direction, boolean extend) { if (!extend && anchor != caret) caret -= direction; caret = next(caret, breaker, direction, true); if (!extend) anchor = caret; @@ -118,8 +116,8 @@ public Selection nextBound(BreakIterator breaker, // expand start and end to word breaks--if they are not already on one public void expand(BreakIterator breaker) { if (anchor <= caret) { - anchor = next(anchor,breaker,-1,false); - caret = next(caret,breaker,1,false); + anchor = next(anchor, breaker, -1, false); + caret = next(caret, breaker, 1, false); /* try { breaker.following(anchor); @@ -130,8 +128,8 @@ public void expand(BreakIterator breaker) { } catch (Exception e) {} */ } else { - anchor = next(anchor,breaker,1,false); - caret = next(caret,breaker,-1,false); + anchor = next(anchor, breaker, 1, false); + caret = next(caret, breaker, -1, false); /* try { breaker.following(caret); @@ -146,18 +144,17 @@ public void expand(BreakIterator breaker) { // different = false - move to next boundary, unless on one // true - move to next boundary, even if on one - public static int next(int position, BreakIterator breaker, - int direction, boolean different) { + public static int next(int position, BreakIterator breaker, int direction, boolean different) { if (!different) position -= direction; try { if (direction > 0) { position = breaker.following(position); } else { - breaker.following(position-1); + breaker.following(position - 1); position = breaker.previous(); } - } catch (Exception e) {} + } catch (Exception e) { + } return position; } } - diff --git a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/number/CurrencyDemo.java b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/number/CurrencyDemo.java index a53363dfe24f..66a13abb4c9f 100644 --- a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/number/CurrencyDemo.java +++ b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/number/CurrencyDemo.java @@ -1,29 +1,30 @@ // © 2016 and later: Unicode, Inc. and others. // License & terms of use: http://www.unicode.org/copyright.html /* -********************************************************************** -* Copyright (c) 2003-2010, International Business Machines -* Corporation and others. All Rights Reserved. -********************************************************************** -* Author: Mark Davis -* Created: May 22 2003 -* Since: ICU 2.6 -********************************************************************** -*/ + ********************************************************************** + * Copyright (c) 2003-2010, International Business Machines + * Corporation and others. All Rights Reserved. + ********************************************************************** + * Author: Mark Davis + * Created: May 22 2003 + * Since: ICU 2.6 + ********************************************************************** + */ package com.ibm.icu.dev.demo.number; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; import com.ibm.icu.impl.Utility; import com.ibm.icu.text.DecimalFormat; import com.ibm.icu.text.DecimalFormatSymbols; import com.ibm.icu.text.NumberFormat; import com.ibm.icu.util.Currency; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; /** - * Demonstration code to illustrate how to obtain ICU 2.6-like currency - * behavior using pre-ICU 2.6 ICU4J. + * Demonstration code to illustrate how to obtain ICU 2.6-like currency behavior using pre-ICU 2.6 + * ICU4J. + * * @author Mark Davis */ public class CurrencyDemo { @@ -32,9 +33,7 @@ public static void main(String[] args) { testFormatHack(true); } - static NumberFormat getCurrencyFormat(Currency currency, - Locale displayLocale, - boolean ICU26) { + static NumberFormat getCurrencyFormat(Currency currency, Locale displayLocale, boolean ICU26) { // code for ICU 2.6 if (ICU26) { NumberFormat result = NumberFormat.getCurrencyInstance(displayLocale); @@ -43,8 +42,8 @@ static NumberFormat getCurrencyFormat(Currency currency, } // ugly work-around for 2.4 - DecimalFormat result = (DecimalFormat)NumberFormat.getCurrencyInstance(displayLocale); - HackCurrencyInfo hack = (HackCurrencyInfo)(hackData.get(currency.getCurrencyCode())); + DecimalFormat result = (DecimalFormat) NumberFormat.getCurrencyInstance(displayLocale); + HackCurrencyInfo hack = (HackCurrencyInfo) (hackData.get(currency.getCurrencyCode())); result.setMinimumFractionDigits(hack.decimals); result.setMaximumFractionDigits(hack.decimals); result.setRoundingIncrement(hack.rounding); @@ -53,18 +52,21 @@ static NumberFormat getCurrencyFormat(Currency currency, result.setDecimalFormatSymbols(symbols); return result; } - + static Map hackData = new HashMap(); + static class HackCurrencyInfo { int decimals; double rounding; String symbol; + HackCurrencyInfo(int decimals, double rounding, String symbol) { this.decimals = decimals; this.rounding = rounding; this.symbol = symbol; } } + static { hackData.put("USD", new HackCurrencyInfo(2, 0, "$")); hackData.put("GBP", new HackCurrencyInfo(2, 0, "\u00A3")); @@ -73,13 +75,13 @@ static class HackCurrencyInfo { } /** - * Walk through all locales and compare the output of the ICU26 - * currency format with the "hacked" currency format. - * @param quiet if true, only display discrepancies. Otherwise, - * display all results. + * Walk through all locales and compare the output of the ICU26 currency format with the + * "hacked" currency format. + * + * @param quiet if true, only display discrepancies. Otherwise, display all results. */ static void testFormatHack(boolean quiet) { - String[] testCurrencies = {"USD","GBP","JPY","EUR"}; + String[] testCurrencies = {"USD", "GBP", "JPY", "EUR"}; Locale[] testLocales = NumberFormat.getAvailableLocales(); for (int i = 0; i < testLocales.length; ++i) { // since none of this should vary by country, we'll just do by language @@ -90,12 +92,16 @@ static void testFormatHack(boolean quiet) { noOutput = false; } for (int j = 0; j < testCurrencies.length; ++j) { - NumberFormat nf26 = getCurrencyFormat(Currency.getInstance(testCurrencies[j]), testLocales[i], true); + NumberFormat nf26 = + getCurrencyFormat( + Currency.getInstance(testCurrencies[j]), testLocales[i], true); String str26 = nf26.format(1234.567); if (!quiet) { System.out.print("\t" + Utility.escape(str26)); } - NumberFormat nf24 = getCurrencyFormat(Currency.getInstance(testCurrencies[j]), testLocales[i], false); + NumberFormat nf24 = + getCurrencyFormat( + Currency.getInstance(testCurrencies[j]), testLocales[i], false); String str24 = nf24.format(1234.567); if (!str24.equals(str26)) { if (noOutput) { diff --git a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/rbnf/RbnfDemo.java b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/rbnf/RbnfDemo.java index 36d25cb9bb37..4262d3f378c6 100644 --- a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/rbnf/RbnfDemo.java +++ b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/rbnf/RbnfDemo.java @@ -8,6 +8,9 @@ */ package com.ibm.icu.dev.demo.rbnf; +import com.ibm.icu.dev.demo.impl.DemoApplet; +import com.ibm.icu.math.BigDecimal; +import com.ibm.icu.text.RuleBasedNumberFormat; import java.awt.BorderLayout; import java.awt.Button; import java.awt.CardLayout; @@ -44,21 +47,13 @@ import java.text.ParsePosition; import java.util.Locale; -import com.ibm.icu.dev.demo.impl.DemoApplet; -import com.ibm.icu.math.BigDecimal; -import com.ibm.icu.text.RuleBasedNumberFormat; - public class RbnfDemo extends DemoApplet { - /** - * For serialization - */ + /** For serialization */ private static final long serialVersionUID = -9119861296873763536L; - /** - * Puts a copyright in the .class file - */ -// private static final String copyrightNotice -// = "Copyright \u00a91997-1998 IBM Corp. All rights reserved."; + /** Puts a copyright in the .class file */ + // private static final String copyrightNotice + // = "Copyright \u00a91997-1998 IBM Corp. All rights reserved."; /* * code to run the demo as an application @@ -69,7 +64,7 @@ public static void main(String[] argv) { @Override protected Dimension getDefaultFrameSize(DemoApplet applet, Frame f) { - return new Dimension(430,270); + return new Dimension(430, 270); } @Override @@ -79,7 +74,7 @@ protected Frame createDemoFrame(DemoApplet applet) { window.setLayout(new BorderLayout()); Panel mainPanel = new Panel(); - mainPanel.setLayout(new GridLayout(1,2)); + mainPanel.setLayout(new GridLayout(1, 2)); commentaryField = new TextArea("", 0, 0, TextArea.SCROLLBARS_VERTICAL_ONLY); commentaryField.setSize(800, 50); @@ -102,150 +97,174 @@ protected Frame createDemoFrame(DemoApplet applet) { rulesField.setFont(new Font("Serif", Font.PLAIN, 14)); lenientParseButton = new Checkbox("Lenient parse", lenientParse); - numberField.addTextListener(new TextListener() { - @Override - public void textValueChanged(TextEvent e) { - if (!numberFieldHasFocus) - return; - - String fieldText = ((TextComponent)(e.getSource())).getText(); - parsePosition.setIndex(0); - Number temp = numberFormatter.parse(fieldText, parsePosition); - if (temp == null || parsePosition.getIndex() == 0) { - theNumber = BigDecimal.ZERO; - textField.setText("PARSE ERROR"); - } - else { - theNumber = new BigDecimal(temp instanceof Long ? temp.longValue() : temp.doubleValue()); - textField.setText(spelloutFormatter.format( - theNumber.scale() == 0 ? theNumber.longValue() : theNumber.doubleValue(), ruleSetName)); - } - } - } ); + numberField.addTextListener( + new TextListener() { + @Override + public void textValueChanged(TextEvent e) { + if (!numberFieldHasFocus) return; + + String fieldText = ((TextComponent) (e.getSource())).getText(); + parsePosition.setIndex(0); + Number temp = numberFormatter.parse(fieldText, parsePosition); + if (temp == null || parsePosition.getIndex() == 0) { + theNumber = BigDecimal.ZERO; + textField.setText("PARSE ERROR"); + } else { + theNumber = + new BigDecimal( + temp instanceof Long + ? temp.longValue() + : temp.doubleValue()); + textField.setText( + spelloutFormatter.format( + theNumber.scale() == 0 + ? theNumber.longValue() + : theNumber.doubleValue(), + ruleSetName)); + } + } + }); - numberField.addFocusListener(new FocusAdapter() { - @Override - public void focusLost(FocusEvent e) { - numberFieldHasFocus = false; - numberField.setText(numberFormatter.format(theNumber)); - } + numberField.addFocusListener( + new FocusAdapter() { + @Override + public void focusLost(FocusEvent e) { + numberFieldHasFocus = false; + numberField.setText(numberFormatter.format(theNumber)); + } - @Override - public void focusGained(FocusEvent e) { - numberFieldHasFocus = true; - numberField.selectAll(); - } - } ); - - textField.addKeyListener(new KeyAdapter() { - @Override - public void keyTyped(KeyEvent e) { - if (e.getKeyChar() == '\t') { - String fieldText = ((TextComponent)(e.getSource())).getText(); - parsePosition.setIndex(0); - theNumber = new BigDecimal(spelloutFormatter.parse(fieldText, parsePosition) - .doubleValue()); - if (parsePosition.getIndex() == 0) { - theNumber = BigDecimal.ZERO; - numberField.setText("PARSE ERROR"); - textField.selectAll(); + @Override + public void focusGained(FocusEvent e) { + numberFieldHasFocus = true; + numberField.selectAll(); } - else if (parsePosition.getIndex() < fieldText.length()) { - textField.select(parsePosition.getIndex(), fieldText.length()); - numberField.setText(numberFormatter.format(theNumber)); + }); + + textField.addKeyListener( + new KeyAdapter() { + @Override + public void keyTyped(KeyEvent e) { + if (e.getKeyChar() == '\t') { + String fieldText = ((TextComponent) (e.getSource())).getText(); + parsePosition.setIndex(0); + theNumber = + new BigDecimal( + spelloutFormatter + .parse(fieldText, parsePosition) + .doubleValue()); + if (parsePosition.getIndex() == 0) { + theNumber = BigDecimal.ZERO; + numberField.setText("PARSE ERROR"); + textField.selectAll(); + } else if (parsePosition.getIndex() < fieldText.length()) { + textField.select(parsePosition.getIndex(), fieldText.length()); + numberField.setText(numberFormatter.format(theNumber)); + } else { + textField.selectAll(); + numberField.setText(numberFormatter.format(theNumber)); + } + e.consume(); + } + } + }); + + textField.addFocusListener( + new FocusAdapter() { + @Override + public void focusLost(FocusEvent e) { + String fieldText = ((TextComponent) (e.getSource())).getText(); + parsePosition.setIndex(0); + theNumber = + new BigDecimal( + spelloutFormatter + .parse(fieldText, parsePosition) + .doubleValue()); + if (parsePosition.getIndex() == 0) numberField.setText("PARSE ERROR"); + else numberField.setText(numberFormatter.format(theNumber)); + textField.setText( + textField.getText()); // textField.repaint() didn't work right } - else { + + @Override + public void focusGained(FocusEvent e) { textField.selectAll(); - numberField.setText(numberFormatter.format(theNumber)); } - e.consume(); - } - } - } ); - - textField.addFocusListener(new FocusAdapter() { - @Override - public void focusLost(FocusEvent e) { - String fieldText = ((TextComponent)(e.getSource())).getText(); - parsePosition.setIndex(0); - theNumber = new BigDecimal(spelloutFormatter.parse(fieldText, parsePosition) - .doubleValue()); - if (parsePosition.getIndex() == 0) - numberField.setText("PARSE ERROR"); - else - numberField.setText(numberFormatter.format(theNumber)); - textField.setText(textField.getText()); // textField.repaint() didn't work right - } + }); - @Override - public void focusGained(FocusEvent e) { - textField.selectAll(); - } - } ); - - rulesField.addKeyListener(new KeyAdapter() { - @Override - public void keyTyped(KeyEvent e) { - if (e.getKeyChar() == '\t') { - String fieldText = ((TextComponent)(e.getSource())).getText(); - if (formatterMenu.getSelectedItem().equals("Custom") || !fieldText.equals( - RbnfSampleRuleSets.sampleRuleSets[formatterMenu.getSelectedIndex()])) { - try { - RuleBasedNumberFormat temp = new RuleBasedNumberFormat(fieldText); - temp.setLenientParseMode(lenientParse); - populateRuleSetMenu(); - spelloutFormatter = temp; - customRuleSet = fieldText; - formatterMenu.select("Custom"); - commentaryField.setText(RbnfSampleRuleSets. - sampleRuleSetCommentary[RbnfSampleRuleSets. - sampleRuleSetCommentary.length - 1]); - redisplay(); - } - catch (Exception x) { - textField.setText(x.toString()); + rulesField.addKeyListener( + new KeyAdapter() { + @Override + public void keyTyped(KeyEvent e) { + if (e.getKeyChar() == '\t') { + String fieldText = ((TextComponent) (e.getSource())).getText(); + if (formatterMenu.getSelectedItem().equals("Custom") + || !fieldText.equals( + RbnfSampleRuleSets.sampleRuleSets[ + formatterMenu.getSelectedIndex()])) { + try { + RuleBasedNumberFormat temp = + new RuleBasedNumberFormat(fieldText); + temp.setLenientParseMode(lenientParse); + populateRuleSetMenu(); + spelloutFormatter = temp; + customRuleSet = fieldText; + formatterMenu.select("Custom"); + commentaryField.setText( + RbnfSampleRuleSets.sampleRuleSetCommentary[ + RbnfSampleRuleSets.sampleRuleSetCommentary + .length + - 1]); + redisplay(); + } catch (Exception x) { + textField.setText(x.toString()); + } + } + e.consume(); } } - e.consume(); - } - } - } ); - - rulesField.addFocusListener(new FocusAdapter() { - @Override - public void focusLost(FocusEvent e) { - String fieldText = ((TextComponent)(e.getSource())).getText(); - if (formatterMenu.getSelectedItem().equals("Custom") || !fieldText.equals( - RbnfSampleRuleSets.sampleRuleSets[formatterMenu.getSelectedIndex()])) { - try { - RuleBasedNumberFormat temp = new RuleBasedNumberFormat(fieldText); - temp.setLenientParseMode(lenientParse); - populateRuleSetMenu(); - spelloutFormatter = temp; - customRuleSet = fieldText; - formatterMenu.select("Custom"); - redisplay(); - } - catch (Exception x) { - textField.setText(x.toString()); + }); + + rulesField.addFocusListener( + new FocusAdapter() { + @Override + public void focusLost(FocusEvent e) { + String fieldText = ((TextComponent) (e.getSource())).getText(); + if (formatterMenu.getSelectedItem().equals("Custom") + || !fieldText.equals( + RbnfSampleRuleSets.sampleRuleSets[ + formatterMenu.getSelectedIndex()])) { + try { + RuleBasedNumberFormat temp = new RuleBasedNumberFormat(fieldText); + temp.setLenientParseMode(lenientParse); + populateRuleSetMenu(); + spelloutFormatter = temp; + customRuleSet = fieldText; + formatterMenu.select("Custom"); + redisplay(); + } catch (Exception x) { + textField.setText(x.toString()); + } + } + rulesField.setText( + rulesField.getText()); // rulesField.repaint() didn't work right } - } - rulesField.setText(rulesField.getText()); // rulesField.repaint() didn't work right - } - } ); + }); - lenientParseButton.addItemListener(new ItemListener() { - @Override - public void itemStateChanged(ItemEvent e) { - lenientParse = lenientParseButton.getState(); - spelloutFormatter.setLenientParseMode(lenientParse); - } - } ); + lenientParseButton.addItemListener( + new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + lenientParse = lenientParseButton.getState(); + spelloutFormatter.setLenientParseMode(lenientParse); + } + }); numberField.setText(numberFormatter.format(theNumber)); numberField.selectAll(); - textField.setText(spelloutFormatter - .format(theNumber.scale() == 0 ? theNumber.longValue() : theNumber.doubleValue(), ruleSetName)); + textField.setText( + spelloutFormatter.format( + theNumber.scale() == 0 ? theNumber.longValue() : theNumber.doubleValue(), + ruleSetName)); Panel leftPanel = new Panel(); leftPanel.setLayout(new BorderLayout()); @@ -260,71 +279,82 @@ public void itemStateChanged(ItemEvent e) { Panel panel2 = new Panel(); panel2.setLayout(new GridLayout(3, 3)); Button button = new Button("+100"); - button.addActionListener( new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - roll(100); - } - } ); + button.addActionListener( + new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + roll(100); + } + }); panel2.add(button); button = new Button("+10"); - button.addActionListener( new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - roll(10); - } - } ); + button.addActionListener( + new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + roll(10); + } + }); panel2.add(button); button = new Button("+1"); - button.addActionListener( new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - roll(1); - } - } ); + button.addActionListener( + new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + roll(1); + } + }); panel2.add(button); button = new Button("<"); - button.addActionListener( new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - theNumber = new BigDecimal(theNumber.toString()).multiply(new BigDecimal("10")); - redisplay(); - } - } ); + button.addActionListener( + new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + theNumber = + new BigDecimal(theNumber.toString()).multiply(new BigDecimal("10")); + redisplay(); + } + }); panel2.add(button); panel2.add(new Panel()); button = new Button(">"); - button.addActionListener( new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - theNumber = new BigDecimal(theNumber.toString()).multiply(new BigDecimal("0.1")); - redisplay(); - } - } ); + button.addActionListener( + new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + theNumber = + new BigDecimal(theNumber.toString()) + .multiply(new BigDecimal("0.1")); + redisplay(); + } + }); panel2.add(button); button = new Button("-100"); - button.addActionListener( new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - roll(-100); - } - } ); + button.addActionListener( + new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + roll(-100); + } + }); panel2.add(button); button = new Button("-10"); - button.addActionListener( new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - roll(-10); - } - } ); + button.addActionListener( + new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + roll(-10); + } + }); panel2.add(button); button = new Button("-1"); - button.addActionListener( new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - roll(-1); - } - } ); + button.addActionListener( + new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + roll(-1); + } + }); panel2.add(button); panel.add(panel2, "East"); leftPanel.add(panel, "North"); @@ -336,43 +366,45 @@ public void actionPerformed(ActionEvent e) { for (int i = 0; i < RbnfSampleRuleSets.sampleRuleSetNames.length; i++) formatterMenu.addItem(RbnfSampleRuleSets.sampleRuleSetNames[i]); formatterMenu.addItem("Custom"); - formatterMenu.addItemListener(new ItemListener() { - @Override - public void itemStateChanged(ItemEvent e) { - Choice source = (Choice)(e.getSource()); - int item = source.getSelectedIndex(); - Locale locale = RbnfSampleRuleSets.sampleRuleSetLocales[item]; - - commentaryField.setText(RbnfSampleRuleSets. - sampleRuleSetCommentary[item]); - - if (locale != null && (locale.getLanguage().equals("iw") - || locale.getLanguage().equals("ru") || locale.getLanguage().equals("ja") - || locale.getLanguage().equals("el") - || locale.getLanguage().equals("zh"))) { - textField.togglePanes(false); - rulesField.togglePanes(false); - } - else { - textField.togglePanes(true); - rulesField.togglePanes(true); - } - - makeNewSpelloutFormatter(); - redisplay(); - } - } ); + formatterMenu.addItemListener( + new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + Choice source = (Choice) (e.getSource()); + int item = source.getSelectedIndex(); + Locale locale = RbnfSampleRuleSets.sampleRuleSetLocales[item]; + + commentaryField.setText(RbnfSampleRuleSets.sampleRuleSetCommentary[item]); + + if (locale != null + && (locale.getLanguage().equals("iw") + || locale.getLanguage().equals("ru") + || locale.getLanguage().equals("ja") + || locale.getLanguage().equals("el") + || locale.getLanguage().equals("zh"))) { + textField.togglePanes(false); + rulesField.togglePanes(false); + } else { + textField.togglePanes(true); + rulesField.togglePanes(true); + } + + makeNewSpelloutFormatter(); + redisplay(); + } + }); ruleSetMenu = new Choice(); populateRuleSetMenu(); - ruleSetMenu.addItemListener(new ItemListener() { - @Override - public void itemStateChanged(ItemEvent e) { - ruleSetName = ruleSetMenu.getSelectedItem(); - redisplay(); - } - } ); + ruleSetMenu.addItemListener( + new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + ruleSetName = ruleSetMenu.getSelectedItem(); + redisplay(); + } + }); Panel menuPanel = new Panel(); menuPanel.setLayout(new GridLayout(1, 2)); @@ -403,7 +435,7 @@ public void windowClosing(WindowEvent e) { theApplet.demoClosed(); } else System.exit(0); } - } ); + }); return window; } @@ -414,8 +446,10 @@ void roll(int delta) { void redisplay() { numberField.setText(numberFormatter.format(theNumber)); - textField.setText(spelloutFormatter - .format(theNumber.scale() == 0 ? theNumber.longValue() : theNumber.doubleValue(), ruleSetName)); + textField.setText( + spelloutFormatter.format( + theNumber.scale() == 0 ? theNumber.longValue() : theNumber.doubleValue(), + ruleSetName)); } void makeNewSpelloutFormatter() { @@ -425,16 +459,14 @@ void makeNewSpelloutFormatter() { if (formatterMenuItem.equals("Custom")) { rulesField.setText(customRuleSet); spelloutFormatter = new RuleBasedNumberFormat(customRuleSet); - } - else { + } else { rulesField.setText(RbnfSampleRuleSets.sampleRuleSets[item]); Locale locale = RbnfSampleRuleSets.sampleRuleSetLocales[item]; - if (locale == null) - locale = Locale.getDefault(); + if (locale == null) locale = Locale.getDefault(); - spelloutFormatter = new RuleBasedNumberFormat(RbnfSampleRuleSets. - sampleRuleSets[item], locale); + spelloutFormatter = + new RuleBasedNumberFormat(RbnfSampleRuleSets.sampleRuleSets[item], locale); } spelloutFormatter.setLenientParseMode(lenientParse); populateRuleSetMenu(); @@ -445,16 +477,13 @@ void populateRuleSetMenu() { if (ruleSetMenu != null) { ruleSetMenu.removeAll(); - for (int i = 0; i < ruleSetNames.length; i++) - ruleSetMenu.addItem(ruleSetNames[i]); + for (int i = 0; i < ruleSetNames.length; i++) ruleSetMenu.addItem(ruleSetNames[i]); ruleSetName = ruleSetMenu.getSelectedItem(); - } - else - ruleSetName = ruleSetNames[0]; + } else ruleSetName = ruleSetNames[0]; } -// private Frame demoWindow = null; + // private Frame demoWindow = null; private TextComponent numberField; private DemoTextFieldHolder textField; @@ -471,7 +500,7 @@ void populateRuleSetMenu() { private boolean lenientParse = true; private BigDecimal theNumber = BigDecimal.ZERO; -// private boolean canEdit = true; + // private boolean canEdit = true; private Choice formatterMenu; private Choice ruleSetMenu; @@ -481,12 +510,10 @@ void populateRuleSetMenu() { } class DemoTextField extends Component { - /** - * For serialization - */ + /** For serialization */ private static final long serialVersionUID = -7947090021239472658L; - public DemoTextField() { - } + + public DemoTextField() {} public void setText(String text) { this.text = text; @@ -516,46 +543,40 @@ public void paint(Graphics g) { while (lineStart < txt.length()) { maxLineEnd = txt.indexOf('\n', lineStart); - if (maxLineEnd == -1) - maxLineEnd = Integer.MAX_VALUE; - while (tempLineEnd != BreakIterator.DONE && fm.stringWidth(txt.substring( - lineStart, tempLineEnd)) < width) { + if (maxLineEnd == -1) maxLineEnd = Integer.MAX_VALUE; + while (tempLineEnd != BreakIterator.DONE + && fm.stringWidth(txt.substring(lineStart, tempLineEnd)) < width) { lineEnd = tempLineEnd; tempLineEnd = bi.next(); } if (lineStart >= lineEnd) { - if (tempLineEnd == BreakIterator.DONE) - lineEnd = txt.length(); - else - lineEnd = tempLineEnd; + if (tempLineEnd == BreakIterator.DONE) lineEnd = txt.length(); + else lineEnd = tempLineEnd; } - if (lineEnd > maxLineEnd) - lineEnd = maxLineEnd; + if (lineEnd > maxLineEnd) lineEnd = maxLineEnd; g.drawString(txt.substring(lineStart, lineEnd), 0, penY); penY += lineHeight; totalHeight += lineHeight; lineStart = lineEnd; - if (lineStart < txt.length() && txt.charAt(lineStart) == '\n') - ++lineStart; + if (lineStart < txt.length() && txt.charAt(lineStart) == '\n') ++lineStart; } } -/* - public Dimension getPreferredSize() { - Dimension size = getParent().getSize(); - return new Dimension(size.width, totalHeight); - } -*/ + /* + public Dimension getPreferredSize() { + Dimension size = getParent().getSize(); + return new Dimension(size.width, totalHeight); + } + */ private String text; private int totalHeight; } class DemoTextFieldHolder extends Panel { - /** - * For serialization - */ + /** For serialization */ private static final long serialVersionUID = 7514498764062569858L; + public DemoTextFieldHolder() { tf1 = new TextArea("", 0, 0, TextArea.SCROLLBARS_VERTICAL_ONLY); tf2 = new DemoTextField(); @@ -598,7 +619,7 @@ public void selectAll() { public void togglePanes(boolean canShowRealTextField) { if (canShowRealTextField != showingRealTextField) { - CardLayout layout = (CardLayout)(getLayout()); + CardLayout layout = (CardLayout) (getLayout()); layout.next(this); showingRealTextField = canShowRealTextField; } diff --git a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/rbnf/RbnfSampleRuleSets.java b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/rbnf/RbnfSampleRuleSets.java index 3bdf1aad7ccb..aa364ebed03b 100644 --- a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/rbnf/RbnfSampleRuleSets.java +++ b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/rbnf/RbnfSampleRuleSets.java @@ -11,27 +11,22 @@ import java.util.Locale; /** - * A collection of example rule sets for use with RuleBasedNumberFormat. - * These examples are intended to serve both as demonstrations of what can - * be done with this framework, and as starting points for designing new - * rule sets. + * A collection of example rule sets for use with RuleBasedNumberFormat. These examples are intended + * to serve both as demonstrations of what can be done with this framework, and as starting points + * for designing new rule sets. * - * For those that claim to represent number-spellout rules for languages - * other than U.S. English, we make no claims of either accuracy or - * completeness. In fact, we know them to be incomplete, and suspect - * most have mistakes in them. If you see something that you know is wrong, - * please tell us! + *

For those that claim to represent number-spellout rules for languages other than U.S. English, + * we make no claims of either accuracy or completeness. In fact, we know them to be incomplete, and + * suspect most have mistakes in them. If you see something that you know is wrong, please tell us! * * @author Richard Gillam */ public class RbnfSampleRuleSets { - /** - * Puts a copyright in the .class file - */ -// private static final String copyrightNotice -// = "Copyright \u00a91997-1998 IBM Corp. All rights reserved."; + /** Puts a copyright in the .class file */ + // private static final String copyrightNotice + // = "Copyright \u00a91997-1998 IBM Corp. All rights reserved."; - //======================================================================== + // ======================================================================== // Spellout rules for various languages // // The following RuleBasedNumberFormat descriptions show the rules for @@ -42,300 +37,295 @@ public class RbnfSampleRuleSets { // missing information in any of these rule sets, or if you find errors, // or if you can supply spellout rules for languages that aren't shown // here, we want to hear from you! - //======================================================================== + // ======================================================================== /** - * Spellout rules for U.S. English. This demonstration version of the - * U.S. English spellout rules has four variants: 1) %simplified is a - * set of rules showing the simple method of spelling out numbers in - * English: 289 is formatted as "two hundred eighty-nine". 2) %alt-teens - * is the same as %simplified, except that values between 1,000 and 9,999 - * whose hundreds place isn't zero are formatted in hundreds. For example, - * 1,983 is formatted as "nineteen hundred eighty-three," and 2,183 is - * formatted as "twenty-one hundred eighty-three," but 2,083 is still - * formatted as "two thousand eighty-three." 3) %ordinal formats the - * values as ordinal numbers in English (e.g., 289 is "two hundred eighty- - * ninth"). 4) %default uses a more complicated algorithm to format - * numbers in a more natural way: 289 is formatted as "two hundred AND - * eighty-nine" and commas are inserted between the thousands groups for - * values above 100,000. + * Spellout rules for U.S. English. This demonstration version of the U.S. English spellout + * rules has four variants: 1) %simplified is a set of rules showing the simple method of + * spelling out numbers in English: 289 is formatted as "two hundred eighty-nine". 2) %alt-teens + * is the same as %simplified, except that values between 1,000 and 9,999 whose hundreds place + * isn't zero are formatted in hundreds. For example, 1,983 is formatted as "nineteen hundred + * eighty-three," and 2,183 is formatted as "twenty-one hundred eighty-three," but 2,083 is + * still formatted as "two thousand eighty-three." 3) %ordinal formats the values as ordinal + * numbers in English (e.g., 289 is "two hundred eighty- ninth"). 4) %default uses a more + * complicated algorithm to format numbers in a more natural way: 289 is formatted as "two + * hundred AND eighty-nine" and commas are inserted between the thousands groups for values + * above 100,000. */ public static final String usEnglish = - // This rule set shows the normal simple formatting rules for English - "%simplified:\n" - // negative number rule. This rule is used to format negative - // numbers. The result of formatting the number's absolute - // value is placed where the >> is. - + " -x: minus >>;\n" - // faction rule. This rule is used for formatting numbers - // with fractional parts. The result of formatting the - // number's integral part is substituted for the <<, and - // the result of formatting the number's fractional part - // (one digit at a time, e.g., 0.123 is "zero point one two - // three") replaces the >>. - + " x.x: << point >>;\n" - // the rules for the values from 0 to 19 are simply the - // words for those numbers - + " zero; one; two; three; four; five; six; seven; eight; nine;\n" - + " ten; eleven; twelve; thirteen; fourteen; fifteen; sixteen;\n" - + " seventeen; eighteen; nineteen;\n" - // beginning at 20, we use the >> to mark the position where - // the result of formatting the number's ones digit. Thus, - // we only need a new rule at every multiple of 10. Text in - // brackets is omitted if the value being formatted is an - // even multiple of 10. - + " 20: twenty[->>];\n" - + " 30: thirty[->>];\n" - + " 40: forty[->>];\n" - + " 50: fifty[->>];\n" - + " 60: sixty[->>];\n" - + " 70: seventy[->>];\n" - + " 80: eighty[->>];\n" - + " 90: ninety[->>];\n" - // beginning at 100, we can use << to mark the position where - // the result of formatting the multiple of 100 is to be - // inserted. Notice also that the meaning of >> has shifted: - // here, it refers to both the ones place and the tens place. - // The meanings of the << and >> tokens depend on the base value - // of the rule. A rule's divisor is (usually) the highest - // power of 10 that is less than or equal to the rule's base - // value. The value being formatted is divided by the rule's - // divisor, and the integral quotient is used to get the text - // for <<, while the remainder is used to produce the text - // for >>. Again, text in brackets is omitted if the value - // being formatted is an even multiple of the rule's divisor - // (in this case, an even multiple of 100) - + " 100: << hundred[ >>];\n" - // The rules for the higher numbers work the same way as the - // rule for 100: Again, the << and >> tokens depend on the - // rule's divisor, which for all these rules is also the rule's - // base value. To group by thousand, we simply don't have any - // rules between 1,000 and 1,000,000. - + " 1000: << thousand[ >>];\n" - + " 1,000,000: << million[ >>];\n" - + " 1,000,000,000: << billion[ >>];\n" - + " 1,000,000,000,000: << trillion[ >>];\n" - // overflow rule. This rule specifies that values of a - // quadrillion or more are shown in numerals rather than words. - // The == token means to format (with new rules) the value - // being formatted by this rule and place the result where - // the == is. The #,##0 inside the == signs is a - // DecimalFormat pattern. It specifies that the value should - // be formatted with a DecimalFormat object, and that it - // should be formatted with no decimal places, at least one - // digit, and a thousands separator. - + " 1,000,000,000,000,000: =#,##0=;\n" - - // This rule set formats numbers between 1,000 and 9,999 somewhat - // differently: If the hundreds digit is not zero, the first two - // digits are treated as a number of hundreds. For example, 2,197 - // would come out as "twenty-one hundred ninety-seven." - + "%alt-teens:\n" - // just use %simplified to format values below 1,000 - + " =%simplified=;\n" - // values between 1,000 and 9,999 are delegated to %%alt-hundreds - // for formatting. The > after "1000" decreases the exponent - // of the rule's radix by one, causing the rule's divisor - // to be 100 instead of 1,000. This causes the first TWO - // digits of the number, instead of just the first digit, - // to be sent to %%alt-hundreds - + " 1000>: <%%alt-hundreds<[ >>];\n" - // for values of 10,000 and more, we again just use %simplified - + " 10,000: =%simplified=;\n" - // This rule set uses some obscure voodoo of the description language - // to format the first two digits of a value in the thousands. - // The rule at 10 formats the first two digits as a multiple of 1,000 - // and the rule at 11 formats the first two digits as a multiple of - // 100. This works because of something known as the "rollback rule": - // if the rule applicable to the value being formatted has two - // substitutions, the value being formatted is an even multiple of - // the rule's divisor, and the rule's base value ISN'T an even multiple - // if the rule's divisor, then the rule that precedes this one in the - // list is used instead. (The [] notation is implemented internally - // using this notation: a rule containing [] is split into two rules, - // and the right one is chosen using the rollback rule.) In this case, - // it means that if the first two digits are an even multiple of 10, - // they're formatted with the 10 rule (containing "thousand"), and if - // they're not, they're formatted with the 11 rule (containing - // "hundred"). %%empty is a hack to cause the rollback rule to be - // invoked: it makes the 11 rule have two substitutions, even though - // the second substitution (calling %%empty) doesn't actually do - // anything. - + "%%alt-hundreds:\n" - + " 0: SHOULD NEVER GET HERE!;\n" - + " 10: <%simplified< thousand;\n" - + " 11: =%simplified= hundred>%%empty>;\n" - + "%%empty:\n" - + " 0:;" - - // this rule set is the same as %simplified, except that it formats - // the value as an ordinal number: 234 is formatted as "two hundred - // thirty-fourth". Notice the calls to ^simplified: we have to - // call %simplified to avoid getting "second hundred thirty-fourth." - + "%ordinal:\n" - + " zeroth; first; second; third; fourth; fifth; sixth; seventh;\n" - + " eighth; ninth;\n" - + " tenth; eleventh; twelfth; thirteenth; fourteenth;\n" - + " fifteenth; sixteenth; seventeenth; eighteenth;\n" - + " nineteenth;\n" - + " twentieth; twenty->>;\n" - + " 30: thirtieth; thirty->>;\n" - + " 40: fortieth; forty->>;\n" - + " 50: fiftieth; fifty->>;\n" - + " 60: sixtieth; sixty->>;\n" - + " 70: seventieth; seventy->>;\n" - + " 80: eightieth; eighty->>;\n" - + " 90: ninetieth; ninety->>;\n" - + " 100: <%simplified< hundredth; <%simplified< hundred >>;\n" - + " 1000: <%simplified< thousandth; <%simplified< thousand >>;\n" - + " 1,000,000: <%simplified< millionth; <%simplified< million >>;\n" - + " 1,000,000,000: <%simplified< billionth;\n" - + " <%simplified< billion >>;\n" - + " 1,000,000,000,000: <%simplified< trillionth;\n" - + " <%simplified< trillion >>;\n" - + " 1,000,000,000,000,000: =#,##0=;" - - // %default is a more elaborate form of %simplified; It is basically - // the same, except that it introduces "and" before the ones digit - // when appropriate (basically, between the tens and ones digits) and - // separates the thousands groups with commas in values over 100,000. - + "%default:\n" - // negative-number and fraction rules. These are the same - // as those for %simplified, but ave to be stated here too - // because this is an entry point - + " -x: minus >>;\n" - + " x.x: << point >>;\n" - // just use %simplified for values below 100 - + " =%simplified=;\n" - // for values from 100 to 9,999 use %%and to decide whether or - // not to interpose the "and" - + " 100: << hundred[ >%%and>];\n" - + " 1000: << thousand[ >%%and>];\n" - // for values of 100,000 and up, use %%commas to interpose the - // commas in the right places (and also to interpose the "and") - + " 100,000>>: << thousand[>%%commas>];\n" - + " 1,000,000: << million[>%%commas>];\n" - + " 1,000,000,000: << billion[>%%commas>];\n" - + " 1,000,000,000,000: << trillion[>%%commas>];\n" - + " 1,000,000,000,000,000: =#,##0=;\n" - // if the value passed to this rule set is greater than 100, don't - // add the "and"; if it's less than 100, add "and" before the last - // digits - + "%%and:\n" - + " and =%default=;\n" - + " 100: =%default=;\n" - // this rule set is used to place the commas - + "%%commas:\n" - // for values below 100, add "and" (the apostrophe at the - // beginning is ignored, but causes the space that follows it - // to be significant: this is necessary because the rules - // calling %%commas don't put a space before it) - + " ' and =%default=;\n" - // put a comma after the thousands (or whatever preceded the - // hundreds) - + " 100: , =%default=;\n" - // put a comma after the millions (or whatever precedes the - // thousands) - + " 1000: , <%default< thousand, >%default>;\n" - // and so on... - + " 1,000,000: , =%default=;" - // %%lenient-parse isn't really a set of number formatting rules; - // it's a set of collation rules. Lenient-parse mode uses a Collator - // object to compare fragments of the text being parsed to the text - // in the rules, allowing more leeway in the matching text. This set - // of rules tells the formatter to ignore commas when parsing (it - // already ignores spaces, which is why we refer to the space; it also - // ignores hyphens, making "twenty one" and "twenty-one" parse - // identically) - + "%%lenient-parse:\n" - + " & ' ' , ',' ;\n"; + // This rule set shows the normal simple formatting rules for English + "%simplified:\n" + // negative number rule. This rule is used to format negative + // numbers. The result of formatting the number's absolute + // value is placed where the >> is. + + " -x: minus >>;\n" + // faction rule. This rule is used for formatting numbers + // with fractional parts. The result of formatting the + // number's integral part is substituted for the <<, and + // the result of formatting the number's fractional part + // (one digit at a time, e.g., 0.123 is "zero point one two + // three") replaces the >>. + + " x.x: << point >>;\n" + // the rules for the values from 0 to 19 are simply the + // words for those numbers + + " zero; one; two; three; four; five; six; seven; eight; nine;\n" + + " ten; eleven; twelve; thirteen; fourteen; fifteen; sixteen;\n" + + " seventeen; eighteen; nineteen;\n" + // beginning at 20, we use the >> to mark the position where + // the result of formatting the number's ones digit. Thus, + // we only need a new rule at every multiple of 10. Text in + // brackets is omitted if the value being formatted is an + // even multiple of 10. + + " 20: twenty[->>];\n" + + " 30: thirty[->>];\n" + + " 40: forty[->>];\n" + + " 50: fifty[->>];\n" + + " 60: sixty[->>];\n" + + " 70: seventy[->>];\n" + + " 80: eighty[->>];\n" + + " 90: ninety[->>];\n" + // beginning at 100, we can use << to mark the position where + // the result of formatting the multiple of 100 is to be + // inserted. Notice also that the meaning of >> has shifted: + // here, it refers to both the ones place and the tens place. + // The meanings of the << and >> tokens depend on the base value + // of the rule. A rule's divisor is (usually) the highest + // power of 10 that is less than or equal to the rule's base + // value. The value being formatted is divided by the rule's + // divisor, and the integral quotient is used to get the text + // for <<, while the remainder is used to produce the text + // for >>. Again, text in brackets is omitted if the value + // being formatted is an even multiple of the rule's divisor + // (in this case, an even multiple of 100) + + " 100: << hundred[ >>];\n" + // The rules for the higher numbers work the same way as the + // rule for 100: Again, the << and >> tokens depend on the + // rule's divisor, which for all these rules is also the rule's + // base value. To group by thousand, we simply don't have any + // rules between 1,000 and 1,000,000. + + " 1000: << thousand[ >>];\n" + + " 1,000,000: << million[ >>];\n" + + " 1,000,000,000: << billion[ >>];\n" + + " 1,000,000,000,000: << trillion[ >>];\n" + // overflow rule. This rule specifies that values of a + // quadrillion or more are shown in numerals rather than words. + // The == token means to format (with new rules) the value + // being formatted by this rule and place the result where + // the == is. The #,##0 inside the == signs is a + // DecimalFormat pattern. It specifies that the value should + // be formatted with a DecimalFormat object, and that it + // should be formatted with no decimal places, at least one + // digit, and a thousands separator. + + " 1,000,000,000,000,000: =#,##0=;\n" + + // This rule set formats numbers between 1,000 and 9,999 somewhat + // differently: If the hundreds digit is not zero, the first two + // digits are treated as a number of hundreds. For example, 2,197 + // would come out as "twenty-one hundred ninety-seven." + + "%alt-teens:\n" + // just use %simplified to format values below 1,000 + + " =%simplified=;\n" + // values between 1,000 and 9,999 are delegated to %%alt-hundreds + // for formatting. The > after "1000" decreases the exponent + // of the rule's radix by one, causing the rule's divisor + // to be 100 instead of 1,000. This causes the first TWO + // digits of the number, instead of just the first digit, + // to be sent to %%alt-hundreds + + " 1000>: <%%alt-hundreds<[ >>];\n" + // for values of 10,000 and more, we again just use %simplified + + " 10,000: =%simplified=;\n" + // This rule set uses some obscure voodoo of the description language + // to format the first two digits of a value in the thousands. + // The rule at 10 formats the first two digits as a multiple of 1,000 + // and the rule at 11 formats the first two digits as a multiple of + // 100. This works because of something known as the "rollback rule": + // if the rule applicable to the value being formatted has two + // substitutions, the value being formatted is an even multiple of + // the rule's divisor, and the rule's base value ISN'T an even multiple + // if the rule's divisor, then the rule that precedes this one in the + // list is used instead. (The [] notation is implemented internally + // using this notation: a rule containing [] is split into two rules, + // and the right one is chosen using the rollback rule.) In this case, + // it means that if the first two digits are an even multiple of 10, + // they're formatted with the 10 rule (containing "thousand"), and if + // they're not, they're formatted with the 11 rule (containing + // "hundred"). %%empty is a hack to cause the rollback rule to be + // invoked: it makes the 11 rule have two substitutions, even though + // the second substitution (calling %%empty) doesn't actually do + // anything. + + "%%alt-hundreds:\n" + + " 0: SHOULD NEVER GET HERE!;\n" + + " 10: <%simplified< thousand;\n" + + " 11: =%simplified= hundred>%%empty>;\n" + + "%%empty:\n" + + " 0:;" + + // this rule set is the same as %simplified, except that it formats + // the value as an ordinal number: 234 is formatted as "two hundred + // thirty-fourth". Notice the calls to ^simplified: we have to + // call %simplified to avoid getting "second hundred thirty-fourth." + + "%ordinal:\n" + + " zeroth; first; second; third; fourth; fifth; sixth; seventh;\n" + + " eighth; ninth;\n" + + " tenth; eleventh; twelfth; thirteenth; fourteenth;\n" + + " fifteenth; sixteenth; seventeenth; eighteenth;\n" + + " nineteenth;\n" + + " twentieth; twenty->>;\n" + + " 30: thirtieth; thirty->>;\n" + + " 40: fortieth; forty->>;\n" + + " 50: fiftieth; fifty->>;\n" + + " 60: sixtieth; sixty->>;\n" + + " 70: seventieth; seventy->>;\n" + + " 80: eightieth; eighty->>;\n" + + " 90: ninetieth; ninety->>;\n" + + " 100: <%simplified< hundredth; <%simplified< hundred >>;\n" + + " 1000: <%simplified< thousandth; <%simplified< thousand >>;\n" + + " 1,000,000: <%simplified< millionth; <%simplified< million >>;\n" + + " 1,000,000,000: <%simplified< billionth;\n" + + " <%simplified< billion >>;\n" + + " 1,000,000,000,000: <%simplified< trillionth;\n" + + " <%simplified< trillion >>;\n" + + " 1,000,000,000,000,000: =#,##0=;" + + // %default is a more elaborate form of %simplified; It is basically + // the same, except that it introduces "and" before the ones digit + // when appropriate (basically, between the tens and ones digits) and + // separates the thousands groups with commas in values over 100,000. + + "%default:\n" + // negative-number and fraction rules. These are the same + // as those for %simplified, but ave to be stated here too + // because this is an entry point + + " -x: minus >>;\n" + + " x.x: << point >>;\n" + // just use %simplified for values below 100 + + " =%simplified=;\n" + // for values from 100 to 9,999 use %%and to decide whether or + // not to interpose the "and" + + " 100: << hundred[ >%%and>];\n" + + " 1000: << thousand[ >%%and>];\n" + // for values of 100,000 and up, use %%commas to interpose the + // commas in the right places (and also to interpose the "and") + + " 100,000>>: << thousand[>%%commas>];\n" + + " 1,000,000: << million[>%%commas>];\n" + + " 1,000,000,000: << billion[>%%commas>];\n" + + " 1,000,000,000,000: << trillion[>%%commas>];\n" + + " 1,000,000,000,000,000: =#,##0=;\n" + // if the value passed to this rule set is greater than 100, don't + // add the "and"; if it's less than 100, add "and" before the last + // digits + + "%%and:\n" + + " and =%default=;\n" + + " 100: =%default=;\n" + // this rule set is used to place the commas + + "%%commas:\n" + // for values below 100, add "and" (the apostrophe at the + // beginning is ignored, but causes the space that follows it + // to be significant: this is necessary because the rules + // calling %%commas don't put a space before it) + + " ' and =%default=;\n" + // put a comma after the thousands (or whatever preceded the + // hundreds) + + " 100: , =%default=;\n" + // put a comma after the millions (or whatever precedes the + // thousands) + + " 1000: , <%default< thousand, >%default>;\n" + // and so on... + + " 1,000,000: , =%default=;" + // %%lenient-parse isn't really a set of number formatting rules; + // it's a set of collation rules. Lenient-parse mode uses a Collator + // object to compare fragments of the text being parsed to the text + // in the rules, allowing more leeway in the matching text. This set + // of rules tells the formatter to ignore commas when parsing (it + // already ignores spaces, which is why we refer to the space; it also + // ignores hyphens, making "twenty one" and "twenty-one" parse + // identically) + + "%%lenient-parse:\n" + + " & ' ' , ',' ;\n"; /** - * Spellout rules for U.K. English. U.K. English has one significant - * difference from U.S. English: the names for values of 1,000,000,000 - * and higher. In American English, each successive "-illion" is 1,000 - * times greater than the preceding one: 1,000,000,000 is "one billion" - * and 1,000,000,000,000 is "one trillion." In British English, each - * successive "-illion" is one million times greater than the one before: - * "one billion" is 1,000,000,000,000 (or what Americans would call a - * "trillion"), and "one trillion" is 1,000,000,000,000,000,000. - * 1,000,000,000 in British English is "one thousand million." (This - * value is sometimes called a "milliard," but this word seems to have - * fallen into disuse.) + * Spellout rules for U.K. English. U.K. English has one significant difference from U.S. + * English: the names for values of 1,000,000,000 and higher. In American English, each + * successive "-illion" is 1,000 times greater than the preceding one: 1,000,000,000 is "one + * billion" and 1,000,000,000,000 is "one trillion." In British English, each successive + * "-illion" is one million times greater than the one before: "one billion" is + * 1,000,000,000,000 (or what Americans would call a "trillion"), and "one trillion" is + * 1,000,000,000,000,000,000. 1,000,000,000 in British English is "one thousand million." (This + * value is sometimes called a "milliard," but this word seems to have fallen into disuse.) */ public static final String ukEnglish = - "%simplified:\n" - + " -x: minus >>;\n" - + " x.x: << point >>;\n" - + " zero; one; two; three; four; five; six; seven; eight; nine;\n" - + " ten; eleven; twelve; thirteen; fourteen; fifteen; sixteen;\n" - + " seventeen; eighteen; nineteen;\n" - + " 20: twenty[->>];\n" - + " 30: thirty[->>];\n" - + " 40: forty[->>];\n" - + " 50: fifty[->>];\n" - + " 60: sixty[->>];\n" - + " 70: seventy[->>];\n" - + " 80: eighty[->>];\n" - + " 90: ninety[->>];\n" - + " 100: << hundred[ >>];\n" - + " 1000: << thousand[ >>];\n" - + " 1,000,000: << million[ >>];\n" - + " 1,000,000,000,000: << billion[ >>];\n" - + " 1,000,000,000,000,000: =#,##0=;\n" - + "%alt-teens:\n" - + " =%simplified=;\n" - + " 1000>: <%%alt-hundreds<[ >>];\n" - + " 10,000: =%simplified=;\n" - + " 1,000,000: << million[ >%simplified>];\n" - + " 1,000,000,000,000: << billion[ >%simplified>];\n" - + " 1,000,000,000,000,000: =#,##0=;\n" - + "%%alt-hundreds:\n" - + " 0: SHOULD NEVER GET HERE!;\n" - + " 10: <%simplified< thousand;\n" - + " 11: =%simplified= hundred>%%empty>;\n" - + "%%empty:\n" - + " 0:;" - + "%ordinal:\n" - + " zeroth; first; second; third; fourth; fifth; sixth; seventh;\n" - + " eighth; ninth;\n" - + " tenth; eleventh; twelfth; thirteenth; fourteenth;\n" - + " fifteenth; sixteenth; seventeenth; eighteenth;\n" - + " nineteenth;\n" - + " twentieth; twenty->>;\n" - + " 30: thirtieth; thirty->>;\n" - + " 40: fortieth; forty->>;\n" - + " 50: fiftieth; fifty->>;\n" - + " 60: sixtieth; sixty->>;\n" - + " 70: seventieth; seventy->>;\n" - + " 80: eightieth; eighty->>;\n" - + " 90: ninetieth; ninety->>;\n" - + " 100: <%simplified< hundredth; <%simplified< hundred >>;\n" - + " 1000: <%simplified< thousandth; <%simplified< thousand >>;\n" - + " 1,000,000: <%simplified< millionth; <%simplified< million >>;\n" - + " 1,000,000,000,000: <%simplified< billionth;\n" - + " <%simplified< billion >>;\n" - + " 1,000,000,000,000,000: =#,##0=;" - + "%default:\n" - + " -x: minus >>;\n" - + " x.x: << point >>;\n" - + " =%simplified=;\n" - + " 100: << hundred[ >%%and>];\n" - + " 1000: << thousand[ >%%and>];\n" - + " 100,000>>: << thousand[>%%commas>];\n" - + " 1,000,000: << million[>%%commas>];\n" - + " 1,000,000,000,000: << billion[>%%commas>];\n" - + " 1,000,000,000,000,000: =#,##0=;\n" - + "%%and:\n" - + " and =%default=;\n" - + " 100: =%default=;\n" - + "%%commas:\n" - + " ' and =%default=;\n" - + " 100: , =%default=;\n" - + " 1000: , <%default< thousand, >%default>;\n" - + " 1,000,000: , =%default=;" - + "%%lenient-parse:\n" - + " & ' ' , ',' ;\n"; + "%simplified:\n" + + " -x: minus >>;\n" + + " x.x: << point >>;\n" + + " zero; one; two; three; four; five; six; seven; eight; nine;\n" + + " ten; eleven; twelve; thirteen; fourteen; fifteen; sixteen;\n" + + " seventeen; eighteen; nineteen;\n" + + " 20: twenty[->>];\n" + + " 30: thirty[->>];\n" + + " 40: forty[->>];\n" + + " 50: fifty[->>];\n" + + " 60: sixty[->>];\n" + + " 70: seventy[->>];\n" + + " 80: eighty[->>];\n" + + " 90: ninety[->>];\n" + + " 100: << hundred[ >>];\n" + + " 1000: << thousand[ >>];\n" + + " 1,000,000: << million[ >>];\n" + + " 1,000,000,000,000: << billion[ >>];\n" + + " 1,000,000,000,000,000: =#,##0=;\n" + + "%alt-teens:\n" + + " =%simplified=;\n" + + " 1000>: <%%alt-hundreds<[ >>];\n" + + " 10,000: =%simplified=;\n" + + " 1,000,000: << million[ >%simplified>];\n" + + " 1,000,000,000,000: << billion[ >%simplified>];\n" + + " 1,000,000,000,000,000: =#,##0=;\n" + + "%%alt-hundreds:\n" + + " 0: SHOULD NEVER GET HERE!;\n" + + " 10: <%simplified< thousand;\n" + + " 11: =%simplified= hundred>%%empty>;\n" + + "%%empty:\n" + + " 0:;" + + "%ordinal:\n" + + " zeroth; first; second; third; fourth; fifth; sixth; seventh;\n" + + " eighth; ninth;\n" + + " tenth; eleventh; twelfth; thirteenth; fourteenth;\n" + + " fifteenth; sixteenth; seventeenth; eighteenth;\n" + + " nineteenth;\n" + + " twentieth; twenty->>;\n" + + " 30: thirtieth; thirty->>;\n" + + " 40: fortieth; forty->>;\n" + + " 50: fiftieth; fifty->>;\n" + + " 60: sixtieth; sixty->>;\n" + + " 70: seventieth; seventy->>;\n" + + " 80: eightieth; eighty->>;\n" + + " 90: ninetieth; ninety->>;\n" + + " 100: <%simplified< hundredth; <%simplified< hundred >>;\n" + + " 1000: <%simplified< thousandth; <%simplified< thousand >>;\n" + + " 1,000,000: <%simplified< millionth; <%simplified< million >>;\n" + + " 1,000,000,000,000: <%simplified< billionth;\n" + + " <%simplified< billion >>;\n" + + " 1,000,000,000,000,000: =#,##0=;" + + "%default:\n" + + " -x: minus >>;\n" + + " x.x: << point >>;\n" + + " =%simplified=;\n" + + " 100: << hundred[ >%%and>];\n" + + " 1000: << thousand[ >%%and>];\n" + + " 100,000>>: << thousand[>%%commas>];\n" + + " 1,000,000: << million[>%%commas>];\n" + + " 1,000,000,000,000: << billion[>%%commas>];\n" + + " 1,000,000,000,000,000: =#,##0=;\n" + + "%%and:\n" + + " and =%default=;\n" + + " 100: =%default=;\n" + + "%%commas:\n" + + " ' and =%default=;\n" + + " 100: , =%default=;\n" + + " 1000: , <%default< thousand, >%default>;\n" + + " 1,000,000: , =%default=;" + + "%%lenient-parse:\n" + + " & ' ' , ',' ;\n"; + // Could someone please correct me if I'm wrong about "milliard" falling // into disuse, or have missed any other details of how large numbers // are rendered. Also, could someone please provide me with information @@ -345,162 +335,158 @@ public class RbnfSampleRuleSets { // someone out there confirm this? /** - * Spellout rules for Spanish. The Spanish rules are quite similar to - * the English rules, but there are some important differences: - * First, we have to provide separate rules for most of the twenties - * because the ones digit frequently picks up an accent mark that it - * doesn't have when standing alone. Second, each multiple of 100 has - * to be specified separately because the multiplier on 100 very often - * changes form in the contraction: 500 is "quinientos," not - * "cincocientos." In addition, the word for 100 is "cien" when - * standing alone, but changes to "ciento" when followed by more digits. - * There also some other differences. + * Spellout rules for Spanish. The Spanish rules are quite similar to the English rules, but + * there are some important differences: First, we have to provide separate rules for most of + * the twenties because the ones digit frequently picks up an accent mark that it doesn't have + * when standing alone. Second, each multiple of 100 has to be specified separately because the + * multiplier on 100 very often changes form in the contraction: 500 is "quinientos," not + * "cincocientos." In addition, the word for 100 is "cien" when standing alone, but changes to + * "ciento" when followed by more digits. There also some other differences. */ public static final String spanish = - // negative-number and fraction rules - "-x: menos >>;\n" - + "x.x: << punto >>;\n" - // words for values from 0 to 19 - + "cero; uno; dos; tres; cuatro; cinco; seis; siete; ocho; nueve;\n" - + "diez; once; doce; trece; catorce; quince; diecis\u00e9is;\n" - + " diecisiete; dieciocho; diecinueve;\n" - // words for values from 20 to 29 (necessary because the ones digit - // often picks up an accent mark it doesn't have when standing alone) - + "veinte; veintiuno; veintid\u00f3s; veintitr\u00e9s; veinticuatro;\n" - + " veinticinco; veintis\u00e9is; veintisiete; veintiocho;\n" - + " veintinueve;\n" - // words for multiples of 10 (notice that the tens digit is separated - // from the ones digit by the word "y".) - + "30: treinta[ y >>];\n" - + "40: cuarenta[ y >>];\n" - + "50: cincuenta[ y >>];\n" - + "60: sesenta[ y >>];\n" - + "70: setenta[ y >>];\n" - + "80: ochenta[ y >>];\n" - + "90: noventa[ y >>];\n" - // 100 by itself is "cien," but 100 followed by something is "cineto" - + "100: cien;\n" - + "101: ciento >>;\n" - // words for multiples of 100 (must be stated because they're - // rarely simple concatenations) - + "200: doscientos[ >>];\n" - + "300: trescientos[ >>];\n" - + "400: cuatrocientos[ >>];\n" - + "500: quinientos[ >>];\n" - + "600: seiscientos[ >>];\n" - + "700: setecientos[ >>];\n" - + "800: ochocientos[ >>];\n" - + "900: novecientos[ >>];\n" - // for 1,000, the multiplier on "mil" is omitted: 2,000 is "dos mil," - // but 1,000 is just "mil." - + "1000: mil[ >>];\n" - + "2000: << mil[ >>];\n" - // 1,000,000 is "un millon," not "uno millon" - + "1,000,000: un mill\u00f3n[ >>];\n" - + "2,000,000: << mill\u00f3n[ >>];\n" - // overflow rule - + "1,000,000,000: =#,##0= (incomplete data);"; + // negative-number and fraction rules + "-x: menos >>;\n" + + "x.x: << punto >>;\n" + // words for values from 0 to 19 + + "cero; uno; dos; tres; cuatro; cinco; seis; siete; ocho; nueve;\n" + + "diez; once; doce; trece; catorce; quince; diecis\u00e9is;\n" + + " diecisiete; dieciocho; diecinueve;\n" + // words for values from 20 to 29 (necessary because the ones digit + // often picks up an accent mark it doesn't have when standing alone) + + "veinte; veintiuno; veintid\u00f3s; veintitr\u00e9s; veinticuatro;\n" + + " veinticinco; veintis\u00e9is; veintisiete; veintiocho;\n" + + " veintinueve;\n" + // words for multiples of 10 (notice that the tens digit is separated + // from the ones digit by the word "y".) + + "30: treinta[ y >>];\n" + + "40: cuarenta[ y >>];\n" + + "50: cincuenta[ y >>];\n" + + "60: sesenta[ y >>];\n" + + "70: setenta[ y >>];\n" + + "80: ochenta[ y >>];\n" + + "90: noventa[ y >>];\n" + // 100 by itself is "cien," but 100 followed by something is "cineto" + + "100: cien;\n" + + "101: ciento >>;\n" + // words for multiples of 100 (must be stated because they're + // rarely simple concatenations) + + "200: doscientos[ >>];\n" + + "300: trescientos[ >>];\n" + + "400: cuatrocientos[ >>];\n" + + "500: quinientos[ >>];\n" + + "600: seiscientos[ >>];\n" + + "700: setecientos[ >>];\n" + + "800: ochocientos[ >>];\n" + + "900: novecientos[ >>];\n" + // for 1,000, the multiplier on "mil" is omitted: 2,000 is "dos mil," + // but 1,000 is just "mil." + + "1000: mil[ >>];\n" + + "2000: << mil[ >>];\n" + // 1,000,000 is "un millon," not "uno millon" + + "1,000,000: un mill\u00f3n[ >>];\n" + + "2,000,000: << mill\u00f3n[ >>];\n" + // overflow rule + + "1,000,000,000: =#,##0= (incomplete data);"; + // The Spanish rules are incomplete. I'm missing information on negative // numbers and numbers with fractional parts. I also don't have // information on numbers higher than the millions /** - * Spellout rules for French. French adds some interesting quirks of its - * own: 1) The word "et" is interposed between the tens and ones digits, - * but only if the ones digit if 1: 20 is "vingt," and 2 is "vingt-deux," - * but 21 is "vingt-et-un." 2) There are no words for 70, 80, or 90. - * "quatre-vingts" ("four twenties") is used for 80, and values proceed - * by score from 60 to 99 (e.g., 73 is "soixante-treize" ["sixty-thirteen"]). - * Numbers from 1,100 to 1,199 are rendered as hundreds rather than - * thousands: 1,100 is "onze cents" ("eleven hundred"), rather than - * "mille cent" ("one thousand one hundred") + * Spellout rules for French. French adds some interesting quirks of its own: 1) The word "et" + * is interposed between the tens and ones digits, but only if the ones digit if 1: 20 is + * "vingt," and 2 is "vingt-deux," but 21 is "vingt-et-un." 2) There are no words for 70, 80, or + * 90. "quatre-vingts" ("four twenties") is used for 80, and values proceed by score from 60 to + * 99 (e.g., 73 is "soixante-treize" ["sixty-thirteen"]). Numbers from 1,100 to 1,199 are + * rendered as hundreds rather than thousands: 1,100 is "onze cents" ("eleven hundred"), rather + * than "mille cent" ("one thousand one hundred") */ public static final String french = - // the main rule set - "%main:\n" - // negative-number and fraction rules - + " -x: moins >>;\n" - + " x.x: << virgule >>;\n" - // words for numbers from 0 to 10 - + " z\u00e9ro; un; deux; trois; quatre; cinq; six; sept; huit; neuf;\n" - + " dix; onze; douze; treize; quatorze; quinze; seize;\n" - + " dix-sept; dix-huit; dix-neuf;\n" - // ords for the multiples of 10: %%alt-ones inserts "et" - // when needed - + " 20: vingt[->%%alt-ones>];\n" - + " 30: trente[->%%alt-ones>];\n" - + " 40: quarante[->%%alt-ones>];\n" - + " 50: cinquante[->%%alt-ones>];\n" - // rule for 60. The /20 causes this rule's multiplier to be - // 20 rather than 10, allowing us to recurse for all values - // from 60 to 79... - + " 60/20: soixante[->%%alt-ones>];\n" - // ...except for 71, which must be special-cased - + " 71: soixante et onze;\n" - // at 72, we have to repeat the rule for 60 to get us to 79 - + " 72/20: soixante->%%alt-ones>;\n" - // at 80, we state a new rule with the phrase for 80. Since - // it changes form when there's a ones digit, we need a second - // rule at 81. This rule also includes "/20," allowing it to - // be used correctly for all values up to 99 - + " 80: quatre-vingts; 81/20: quatre-vingt->>;\n" - // "cent" becomes plural when preceded by a multiplier, and - // the multiplier is omitted from the singular form - + " 100: cent[ >>];\n" - + " 200: << cents[ >>];\n" - + " 1000: mille[ >>];\n" - // values from 1,100 to 1,199 are rendered as "onze cents..." - // instead of "mille cent..." The > after "1000" decreases - // the rule's exponent, causing its multiplier to be 100 instead - // of 1,000. This prevents us from getting "onze cents cent - // vingt-deux" ("eleven hundred one hundred twenty-two"). - + " 1100>: onze cents[ >>];\n" - // at 1,200, we go back to formatting in thousands, so we - // repeat the rule for 1,000 - + " 1200: mille >>;\n" - // at 2,000, the multiplier is added - + " 2000: << mille[ >>];\n" - + " 1,000,000: << million[ >>];\n" - + " 1,000,000,000: << milliarde[ >>];\n" - + " 1,000,000,000,000: << billion[ >>];\n" - + " 1,000,000,000,000,000: =#,##0=;\n" - // %%alt-ones is used to insert "et" when the ones digit is 1 - + "%%alt-ones:\n" - + " ; et-un; =%main=;"; + // the main rule set + "%main:\n" + // negative-number and fraction rules + + " -x: moins >>;\n" + + " x.x: << virgule >>;\n" + // words for numbers from 0 to 10 + + " z\u00e9ro; un; deux; trois; quatre; cinq; six; sept; huit; neuf;\n" + + " dix; onze; douze; treize; quatorze; quinze; seize;\n" + + " dix-sept; dix-huit; dix-neuf;\n" + // ords for the multiples of 10: %%alt-ones inserts "et" + // when needed + + " 20: vingt[->%%alt-ones>];\n" + + " 30: trente[->%%alt-ones>];\n" + + " 40: quarante[->%%alt-ones>];\n" + + " 50: cinquante[->%%alt-ones>];\n" + // rule for 60. The /20 causes this rule's multiplier to be + // 20 rather than 10, allowing us to recurse for all values + // from 60 to 79... + + " 60/20: soixante[->%%alt-ones>];\n" + // ...except for 71, which must be special-cased + + " 71: soixante et onze;\n" + // at 72, we have to repeat the rule for 60 to get us to 79 + + " 72/20: soixante->%%alt-ones>;\n" + // at 80, we state a new rule with the phrase for 80. Since + // it changes form when there's a ones digit, we need a second + // rule at 81. This rule also includes "/20," allowing it to + // be used correctly for all values up to 99 + + " 80: quatre-vingts; 81/20: quatre-vingt->>;\n" + // "cent" becomes plural when preceded by a multiplier, and + // the multiplier is omitted from the singular form + + " 100: cent[ >>];\n" + + " 200: << cents[ >>];\n" + + " 1000: mille[ >>];\n" + // values from 1,100 to 1,199 are rendered as "onze cents..." + // instead of "mille cent..." The > after "1000" decreases + // the rule's exponent, causing its multiplier to be 100 instead + // of 1,000. This prevents us from getting "onze cents cent + // vingt-deux" ("eleven hundred one hundred twenty-two"). + + " 1100>: onze cents[ >>];\n" + // at 1,200, we go back to formatting in thousands, so we + // repeat the rule for 1,000 + + " 1200: mille >>;\n" + // at 2,000, the multiplier is added + + " 2000: << mille[ >>];\n" + + " 1,000,000: << million[ >>];\n" + + " 1,000,000,000: << milliarde[ >>];\n" + + " 1,000,000,000,000: << billion[ >>];\n" + + " 1,000,000,000,000,000: =#,##0=;\n" + // %%alt-ones is used to insert "et" when the ones digit is 1 + + "%%alt-ones:\n" + + " ; et-un; =%main=;"; /** - * Spellout rules for Swiss French. Swiss French differs from French French - * in that it does have words for 70, 80, and 90. This rule set shows them, - * and is simpler as a result. + * Spellout rules for Swiss French. Swiss French differs from French French in that it does have + * words for 70, 80, and 90. This rule set shows them, and is simpler as a result. */ public static final String swissFrench = - "%main:\n" - + " -x: moins >>;\n" - + " x.x: << virgule >>;\n" - + " z\u00e9ro; un; deux; trois; quatre; cinq; six; sept; huit; neuf;\n" - + " dix; onze; douze; treize; quatorze; quinze; seize;\n" - + " dix-sept; dix-huit; dix-neuf;\n" - + " 20: vingt[->%%alt-ones>];\n" - + " 30: trente[->%%alt-ones>];\n" - + " 40: quarante[->%%alt-ones>];\n" - + " 50: cinquante[->%%alt-ones>];\n" - + " 60: soixante[->%%alt-ones>];\n" - // notice new words for 70, 80, and 90 - + " 70: septante[->%%alt-ones>];\n" - + " 80: octante[->%%alt-ones>];\n" - + " 90: nonante[->%%alt-ones>];\n" - + " 100: cent[ >>];\n" - + " 200: << cents[ >>];\n" - + " 1000: mille[ >>];\n" - + " 1100>: onze cents[ >>];\n" - + " 1200: mille >>;\n" - + " 2000: << mille[ >>];\n" - + " 1,000,000: << million[ >>];\n" - + " 1,000,000,000: << milliarde[ >>];\n" - + " 1,000,000,000,000: << billion[ >>];\n" - + " 1,000,000,000,000,000: =#,##0=;\n" - + "%%alt-ones:\n" - + " ; et-un; =%main=;"; + "%main:\n" + + " -x: moins >>;\n" + + " x.x: << virgule >>;\n" + + " z\u00e9ro; un; deux; trois; quatre; cinq; six; sept; huit; neuf;\n" + + " dix; onze; douze; treize; quatorze; quinze; seize;\n" + + " dix-sept; dix-huit; dix-neuf;\n" + + " 20: vingt[->%%alt-ones>];\n" + + " 30: trente[->%%alt-ones>];\n" + + " 40: quarante[->%%alt-ones>];\n" + + " 50: cinquante[->%%alt-ones>];\n" + + " 60: soixante[->%%alt-ones>];\n" + // notice new words for 70, 80, and 90 + + " 70: septante[->%%alt-ones>];\n" + + " 80: octante[->%%alt-ones>];\n" + + " 90: nonante[->%%alt-ones>];\n" + + " 100: cent[ >>];\n" + + " 200: << cents[ >>];\n" + + " 1000: mille[ >>];\n" + + " 1100>: onze cents[ >>];\n" + + " 1200: mille >>;\n" + + " 2000: << mille[ >>];\n" + + " 1,000,000: << million[ >>];\n" + + " 1,000,000,000: << milliarde[ >>];\n" + + " 1,000,000,000,000: << billion[ >>];\n" + + " 1,000,000,000,000,000: =#,##0=;\n" + + "%%alt-ones:\n" + + " ; et-un; =%main=;"; + // I'm not 100% sure about Swiss French. Is // this correct? Is "onze cents" commonly used for 1,100 in both France // and Switzerland? Can someone fill me in on the rules for the other @@ -510,43 +496,43 @@ public class RbnfSampleRuleSets { // what those words are or where they're used. /** - * Spellout rules for German. German also adds some interesting - * characteristics. For values below 1,000,000, numbers are customarily - * written out as a single word. And the ones digit PRECEDES the tens - * digit (e.g., 23 is "dreiundzwanzig," not "zwanzigunddrei"). + * Spellout rules for German. German also adds some interesting characteristics. For values + * below 1,000,000, numbers are customarily written out as a single word. And the ones digit + * PRECEDES the tens digit (e.g., 23 is "dreiundzwanzig," not "zwanzigunddrei"). */ public static final String german = - // 1 is "eins" when by itself, but turns into "ein" in most - // combinations - "%alt-ones:\n" - + " null; eins; =%%main=;\n" - + "%%main:\n" - // words for numbers from 0 to 12. Notice that the values - // from 13 to 19 can derived algorithmically, unlike in most - // other languages - + " null; ein; zwei; drei; vier; f\u00fcnf; sechs; sieben; acht; neun;\n" - + " zehn; elf; zw\u00f6lf; >>zehn;\n" - // rules for the multiples of 10. Notice that the ones digit - // goes on the front - + " 20: [>>und]zwanzig;\n" - + " 30: [>>und]drei\u00dfig;\n" - + " 40: [>>und]vierzig;\n" - + " 50: [>>und]f\u00fcnfzig;\n" - + " 60: [>>und]sechzig;\n" - + " 70: [>>und]siebzig;\n" - + " 80: [>>und]achtzig;\n" - + " 90: [>>und]neunzig;\n" - + " 100: hundert[>%alt-ones>];\n" - + " 200: <%alt-ones>];\n" - + " 1000: tausend[>%alt-ones>];\n" - + " 2000: <%alt-ones>];\n" - + " 1,000,000: eine Million[ >%alt-ones>];\n" - + " 2,000,000: << Millionen[ >%alt-ones>];\n" - + " 1,000,000,000: eine Milliarde[ >%alt-ones>];\n" - + " 2,000,000,000: << Milliarden[ >%alt-ones>];\n" - + " 1,000,000,000,000: eine Billion[ >%alt-ones>];\n" - + " 2,000,000,000,000: << Billionen[ >%alt-ones>];\n" - + " 1,000,000,000,000,000: =#,##0=;"; + // 1 is "eins" when by itself, but turns into "ein" in most + // combinations + "%alt-ones:\n" + + " null; eins; =%%main=;\n" + + "%%main:\n" + // words for numbers from 0 to 12. Notice that the values + // from 13 to 19 can derived algorithmically, unlike in most + // other languages + + " null; ein; zwei; drei; vier; f\u00fcnf; sechs; sieben; acht; neun;\n" + + " zehn; elf; zw\u00f6lf; >>zehn;\n" + // rules for the multiples of 10. Notice that the ones digit + // goes on the front + + " 20: [>>und]zwanzig;\n" + + " 30: [>>und]drei\u00dfig;\n" + + " 40: [>>und]vierzig;\n" + + " 50: [>>und]f\u00fcnfzig;\n" + + " 60: [>>und]sechzig;\n" + + " 70: [>>und]siebzig;\n" + + " 80: [>>und]achtzig;\n" + + " 90: [>>und]neunzig;\n" + + " 100: hundert[>%alt-ones>];\n" + + " 200: <%alt-ones>];\n" + + " 1000: tausend[>%alt-ones>];\n" + + " 2000: <%alt-ones>];\n" + + " 1,000,000: eine Million[ >%alt-ones>];\n" + + " 2,000,000: << Millionen[ >%alt-ones>];\n" + + " 1,000,000,000: eine Milliarde[ >%alt-ones>];\n" + + " 2,000,000,000: << Milliarden[ >%alt-ones>];\n" + + " 1,000,000,000,000: eine Billion[ >%alt-ones>];\n" + + " 2,000,000,000,000: << Billionen[ >%alt-ones>];\n" + + " 1,000,000,000,000,000: =#,##0=;"; + // again, I'm not 100% sure of these rules. I think both "hundert" and // "einhundert" are correct or 100, but I'm not sure which is preferable // in situations where this framework is likely to be used. Also, is it @@ -555,1389 +541,1336 @@ public class RbnfSampleRuleSets { // decimals. /** - * Spellout rules for Italian. Like German, most Italian numbers are - * written as single words. What makes these rules complicated is the rule - * that says that when a word ending in a vowel and a word beginning with - * a vowel are combined into a compound, the vowel is dropped from the - * end of the first word: 180 is "centottanta," not "centoottanta." - * The complexity of this rule set is to produce this behavior. + * Spellout rules for Italian. Like German, most Italian numbers are written as single words. + * What makes these rules complicated is the rule that says that when a word ending in a vowel + * and a word beginning with a vowel are combined into a compound, the vowel is dropped from the + * end of the first word: 180 is "centottanta," not "centoottanta." The complexity of this rule + * set is to produce this behavior. */ public static final String italian = - // main rule set. Follows the patterns of the preceding rule sets, - // except that the final vowel is omitted from words ending in - // vowels when they are followed by another word; instead, we have - // separate rule sets that are identical to this one, except that - // all the words that don't begin with a vowel have a vowel tacked - // onto them at the front. A word ending in a vowel calls a - // substitution that will supply that vowel, unless that vowel is to - // be elided. - "%main:\n" - + " -x: meno >>;\n" - + " x.x: << virgola >>;\n" - + " zero; uno; due; tre; quattro; cinque; sei; sette; otto;\n" - + " nove;\n" - + " dieci; undici; dodici; tredici; quattordici; quindici; sedici;\n" - + " diciasette; diciotto; diciannove;\n" - + " 20: venti; vent>%%with-i>;\n" - + " 30: trenta; trent>%%with-i>;\n" - + " 40: quaranta; quarant>%%with-a>;\n" - + " 50: cinquanta; cinquant>%%with-a>;\n" - + " 60: sessanta; sessant>%%with-a>;\n" - + " 70: settanta; settant>%%with-a>;\n" - + " 80: ottanta; ottant>%%with-a>;\n" - + " 90: novanta; novant>%%with-a>;\n" - + " 100: cento; cent[>%%with-o>];\n" - + " 200: <%%with-o>];\n" - + " 1000: mille; mill[>%%with-i>];\n" - + " 2000: <%%with-a>];\n" - + " 100,000>>: <>];\n" - + " 1,000,000: =#,##0= (incomplete data);\n" - + "%%with-a:\n" - + " azero; uno; adue; atre; aquattro; acinque; asei; asette; otto;\n" - + " anove;\n" - + " adieci; undici; adodici; atredici; aquattordici; aquindici; asedici;\n" - + " adiciasette; adiciotto; adiciannove;\n" - + " 20: aventi; avent>%%with-i>;\n" - + " 30: atrenta; atrent>%%with-i>;\n" - + " 40: aquaranta; aquarant>%%with-a>;\n" - + " 50: acinquanta; acinquant>%%with-a>;\n" - + " 60: asessanta; asessant>%%with-a>;\n" - + " 70: asettanta; asettant>%%with-a>;\n" - + " 80: ottanta; ottant>%%with-a>;\n" - + " 90: anovanta; anovant>%%with-a>;\n" - + " 100: acento; acent[>%%with-o>];\n" - + " 200: <%%with-a%%with-o>];\n" - + " 1000: amille; amill[>%%with-i>];\n" - + " 2000: <%%with-a%%with-a>];\n" - + " 100,000: =%main=;\n" - + "%%with-i:\n" - + " izero; uno; idue; itre; iquattro; icinque; isei; isette; otto;\n" - + " inove;\n" - + " idieci; undici; idodici; itredici; iquattordici; iquindici; isedici;\n" - + " idiciasette; idiciotto; idiciannove;\n" - + " 20: iventi; ivent>%%with-i>;\n" - + " 30: itrenta; itrent>%%with-i>;\n" - + " 40: iquaranta; iquarant>%%with-a>;\n" - + " 50: icinquanta; icinquant>%%with-a>;\n" - + " 60: isessanta; isessant>%%with-a>;\n" - + " 70: isettanta; isettant>%%with-a>;\n" - + " 80: ottanta; ottant>%%with-a>;\n" - + " 90: inovanta; inovant>%%with-a>;\n" - + " 100: icento; icent[>%%with-o>];\n" - + " 200: <%%with-i%%with-o>];\n" - + " 1000: imille; imill[>%%with-i>];\n" - + " 2000: <%%with-i%%with-a>];\n" - + " 100,000: =%main=;\n" - + "%%with-o:\n" - + " ozero; uno; odue; otre; oquattro; ocinque; osei; osette; otto;\n" - + " onove;\n" - + " odieci; undici; ododici; otredici; oquattordici; oquindici; osedici;\n" - + " odiciasette; odiciotto; odiciannove;\n" - + " 20: oventi; ovent>%%with-i>;\n" - + " 30: otrenta; otrent>%%with-i>;\n" - + " 40: oquaranta; oquarant>%%with-a>;\n" - + " 50: ocinquanta; ocinquant>%%with-a>;\n" - + " 60: osessanta; osessant>%%with-a>;\n" - + " 70: osettanta; osettant>%%with-a>;\n" - + " 80: ottanta; ottant>%%with-a>;\n" - + " 90: onovanta; onovant>%%with-a>;\n" - + " 100: ocento; ocent[>%%with-o>];\n" - + " 200: <%%with-o%%with-o>];\n" - + " 1000: omille; omill[>%%with-i>];\n" - + " 2000: <%%with-o%%with-a>];\n" - + " 100,000: =%main=;\n"; + // main rule set. Follows the patterns of the preceding rule sets, + // except that the final vowel is omitted from words ending in + // vowels when they are followed by another word; instead, we have + // separate rule sets that are identical to this one, except that + // all the words that don't begin with a vowel have a vowel tacked + // onto them at the front. A word ending in a vowel calls a + // substitution that will supply that vowel, unless that vowel is to + // be elided. + "%main:\n" + + " -x: meno >>;\n" + + " x.x: << virgola >>;\n" + + " zero; uno; due; tre; quattro; cinque; sei; sette; otto;\n" + + " nove;\n" + + " dieci; undici; dodici; tredici; quattordici; quindici; sedici;\n" + + " diciasette; diciotto; diciannove;\n" + + " 20: venti; vent>%%with-i>;\n" + + " 30: trenta; trent>%%with-i>;\n" + + " 40: quaranta; quarant>%%with-a>;\n" + + " 50: cinquanta; cinquant>%%with-a>;\n" + + " 60: sessanta; sessant>%%with-a>;\n" + + " 70: settanta; settant>%%with-a>;\n" + + " 80: ottanta; ottant>%%with-a>;\n" + + " 90: novanta; novant>%%with-a>;\n" + + " 100: cento; cent[>%%with-o>];\n" + + " 200: <%%with-o>];\n" + + " 1000: mille; mill[>%%with-i>];\n" + + " 2000: <%%with-a>];\n" + + " 100,000>>: <>];\n" + + " 1,000,000: =#,##0= (incomplete data);\n" + + "%%with-a:\n" + + " azero; uno; adue; atre; aquattro; acinque; asei; asette; otto;\n" + + " anove;\n" + + " adieci; undici; adodici; atredici; aquattordici; aquindici; asedici;\n" + + " adiciasette; adiciotto; adiciannove;\n" + + " 20: aventi; avent>%%with-i>;\n" + + " 30: atrenta; atrent>%%with-i>;\n" + + " 40: aquaranta; aquarant>%%with-a>;\n" + + " 50: acinquanta; acinquant>%%with-a>;\n" + + " 60: asessanta; asessant>%%with-a>;\n" + + " 70: asettanta; asettant>%%with-a>;\n" + + " 80: ottanta; ottant>%%with-a>;\n" + + " 90: anovanta; anovant>%%with-a>;\n" + + " 100: acento; acent[>%%with-o>];\n" + + " 200: <%%with-a%%with-o>];\n" + + " 1000: amille; amill[>%%with-i>];\n" + + " 2000: <%%with-a%%with-a>];\n" + + " 100,000: =%main=;\n" + + "%%with-i:\n" + + " izero; uno; idue; itre; iquattro; icinque; isei; isette; otto;\n" + + " inove;\n" + + " idieci; undici; idodici; itredici; iquattordici; iquindici; isedici;\n" + + " idiciasette; idiciotto; idiciannove;\n" + + " 20: iventi; ivent>%%with-i>;\n" + + " 30: itrenta; itrent>%%with-i>;\n" + + " 40: iquaranta; iquarant>%%with-a>;\n" + + " 50: icinquanta; icinquant>%%with-a>;\n" + + " 60: isessanta; isessant>%%with-a>;\n" + + " 70: isettanta; isettant>%%with-a>;\n" + + " 80: ottanta; ottant>%%with-a>;\n" + + " 90: inovanta; inovant>%%with-a>;\n" + + " 100: icento; icent[>%%with-o>];\n" + + " 200: <%%with-i%%with-o>];\n" + + " 1000: imille; imill[>%%with-i>];\n" + + " 2000: <%%with-i%%with-a>];\n" + + " 100,000: =%main=;\n" + + "%%with-o:\n" + + " ozero; uno; odue; otre; oquattro; ocinque; osei; osette; otto;\n" + + " onove;\n" + + " odieci; undici; ododici; otredici; oquattordici; oquindici; osedici;\n" + + " odiciasette; odiciotto; odiciannove;\n" + + " 20: oventi; ovent>%%with-i>;\n" + + " 30: otrenta; otrent>%%with-i>;\n" + + " 40: oquaranta; oquarant>%%with-a>;\n" + + " 50: ocinquanta; ocinquant>%%with-a>;\n" + + " 60: osessanta; osessant>%%with-a>;\n" + + " 70: osettanta; osettant>%%with-a>;\n" + + " 80: ottanta; ottant>%%with-a>;\n" + + " 90: onovanta; onovant>%%with-a>;\n" + + " 100: ocento; ocent[>%%with-o>];\n" + + " 200: <%%with-o%%with-o>];\n" + + " 1000: omille; omill[>%%with-i>];\n" + + " 2000: <%%with-o%%with-a>];\n" + + " 100,000: =%main=;\n"; + // Can someone confirm that I did the vowel-eliding thing right? I'm // not 100% sure I'm doing it in all the right places, or completely // correctly. Also, I don't have information for negatives and decimals, // and I lack words fror values from 1,000,000 on up. - /** - * Spellout rules for Swedish. - */ + /** Spellout rules for Swedish. */ public static final String swedish = - "noll; ett; tv\u00e5; tre; fyra; fem; sex; sjo; \u00e5tta; nio;\n" - + "tio; elva; tolv; tretton; fjorton; femton; sexton; sjutton; arton; nitton;\n" - + "20: tjugo[>>];\n" - + "30: trettio[>>];\n" - + "40: fyrtio[>>];\n" - + "50: femtio[>>];\n" - + "60: sextio[>>];\n" - + "70: sjuttio[>>];\n" - + "80: \u00e5ttio[>>];\n" - + "90: nittio[>>];\n" - + "100: hundra[>>];\n" - + "200: <>];\n" - + "1000: tusen[ >>];\n" - + "2000: << tusen[ >>];\n" - + "1,000,000: en miljon[ >>];\n" - + "2,000,000: << miljon[ >>];\n" - + "1,000,000,000: en miljard[ >>];\n" - + "2,000,000,000: << miljard[ >>];\n" - + "1,000,000,000,000: en biljon[ >>];\n" - + "2,000,000,000,000: << biljon[ >>];\n" - + "1,000,000,000,000,000: =#,##0="; + "noll; ett; tv\u00e5; tre; fyra; fem; sex; sjo; \u00e5tta; nio;\n" + + "tio; elva; tolv; tretton; fjorton; femton; sexton; sjutton; arton; nitton;\n" + + "20: tjugo[>>];\n" + + "30: trettio[>>];\n" + + "40: fyrtio[>>];\n" + + "50: femtio[>>];\n" + + "60: sextio[>>];\n" + + "70: sjuttio[>>];\n" + + "80: \u00e5ttio[>>];\n" + + "90: nittio[>>];\n" + + "100: hundra[>>];\n" + + "200: <>];\n" + + "1000: tusen[ >>];\n" + + "2000: << tusen[ >>];\n" + + "1,000,000: en miljon[ >>];\n" + + "2,000,000: << miljon[ >>];\n" + + "1,000,000,000: en miljard[ >>];\n" + + "2,000,000,000: << miljard[ >>];\n" + + "1,000,000,000,000: en biljon[ >>];\n" + + "2,000,000,000,000: << biljon[ >>];\n" + + "1,000,000,000,000,000: =#,##0="; + // can someone supply me with information on negatives and decimals? /** - * Spellout rules for Dutch. Notice that in Dutch, as in German, - * the ones digit precedes the tens digit. + * Spellout rules for Dutch. Notice that in Dutch, as in German, the ones digit precedes the + * tens digit. */ public static final String dutch = - " -x: min >>;\n" - + "x.x: << komma >>;\n" - + "(zero?); een; twee; drie; vier; vijf; zes; zeven; acht; negen;\n" - + "tien; elf; twaalf; dertien; veertien; vijftien; zestien;\n" - + "zeventien; achtien; negentien;\n" - + "20: [>> en ]twintig;\n" - + "30: [>> en ]dertig;\n" - + "40: [>> en ]veertig;\n" - + "50: [>> en ]vijftig;\n" - + "60: [>> en ]zestig;\n" - + "70: [>> en ]zeventig;\n" - + "80: [>> en ]tachtig;\n" - + "90: [>> en ]negentig;\n" - + "100: << honderd[ >>];\n" - + "1000: << duizend[ >>];\n" - + "1,000,000: << miljoen[ >>];\n" - + "1,000,000,000: << biljoen[ >>];\n" - + "1,000,000,000,000: =#,##0="; + " -x: min >>;\n" + + "x.x: << komma >>;\n" + + "(zero?); een; twee; drie; vier; vijf; zes; zeven; acht; negen;\n" + + "tien; elf; twaalf; dertien; veertien; vijftien; zestien;\n" + + "zeventien; achtien; negentien;\n" + + "20: [>> en ]twintig;\n" + + "30: [>> en ]dertig;\n" + + "40: [>> en ]veertig;\n" + + "50: [>> en ]vijftig;\n" + + "60: [>> en ]zestig;\n" + + "70: [>> en ]zeventig;\n" + + "80: [>> en ]tachtig;\n" + + "90: [>> en ]negentig;\n" + + "100: << honderd[ >>];\n" + + "1000: << duizend[ >>];\n" + + "1,000,000: << miljoen[ >>];\n" + + "1,000,000,000: << biljoen[ >>];\n" + + "1,000,000,000,000: =#,##0="; /** - * Spellout rules for Japanese. In Japanese, there really isn't any - * distinction between a number written out in digits and a number - * written out in words: the ideographic characters are both digits - * and words. This rule set provides two variants: %traditional - * uses the traditional CJK numerals (which are also used in China - * and Korea). %financial uses alternate ideographs for many numbers - * that are harder to alter than the traditional numerals (one could - * fairly easily change a one to - * a three just by adding two strokes, for example). This is also done in - * the other countries using Chinese ideographs, but different ideographs - * are used in those places. + * Spellout rules for Japanese. In Japanese, there really isn't any distinction between a number + * written out in digits and a number written out in words: the ideographic characters are both + * digits and words. This rule set provides two variants: %traditional uses the traditional CJK + * numerals (which are also used in China and Korea). %financial uses alternate ideographs for + * many numbers that are harder to alter than the traditional numerals (one could fairly easily + * change a one to a three just by adding two strokes, for example). This is also done in the + * other countries using Chinese ideographs, but different ideographs are used in those places. */ public static final String japanese = - "%financial:\n" - + " \u96f6; \u58f1; \u5f10; \u53c2; \u56db; \u4f0d; \u516d; \u4e03; \u516b; \u4e5d;\n" - + " \u62fe[>>];\n" - + " 20: <<\u62fe[>>];\n" - + " 100: <<\u767e[>>];\n" - + " 1000: <<\u5343[>>];\n" - + " 10,000: <<\u4e07[>>];\n" - + " 100,000,000: <<\u5104[>>];\n" - + " 1,000,000,000,000: <<\u5146[>>];\n" - + " 10,000,000,000,000,000: =#,##0=;\n" - + "%traditional:\n" - + " \u96f6; \u4e00; \u4e8c; \u4e09; \u56db; \u4e94; \u516d; \u4e03; \u516b; \u4e5d;\n" - + " \u5341[>>];\n" - + " 20: <<\u5341[>>];\n" - + " 100: <<\u767e[>>];\n" - + " 1000: <<\u5343[>>];\n" - + " 10,000: <<\u4e07[>>];\n" - + " 100,000,000: <<\u5104[>>];\n" - + " 1,000,000,000,000: <<\u5146[>>];\n" - + " 10,000,000,000,000,000: =#,##0=;"; + "%financial:\n" + + " \u96f6; \u58f1; \u5f10; \u53c2; \u56db; \u4f0d; \u516d; \u4e03; \u516b; \u4e5d;\n" + + " \u62fe[>>];\n" + + " 20: <<\u62fe[>>];\n" + + " 100: <<\u767e[>>];\n" + + " 1000: <<\u5343[>>];\n" + + " 10,000: <<\u4e07[>>];\n" + + " 100,000,000: <<\u5104[>>];\n" + + " 1,000,000,000,000: <<\u5146[>>];\n" + + " 10,000,000,000,000,000: =#,##0=;\n" + + "%traditional:\n" + + " \u96f6; \u4e00; \u4e8c; \u4e09; \u56db; \u4e94; \u516d; \u4e03; \u516b; \u4e5d;\n" + + " \u5341[>>];\n" + + " 20: <<\u5341[>>];\n" + + " 100: <<\u767e[>>];\n" + + " 1000: <<\u5343[>>];\n" + + " 10,000: <<\u4e07[>>];\n" + + " 100,000,000: <<\u5104[>>];\n" + + " 1,000,000,000,000: <<\u5146[>>];\n" + + " 10,000,000,000,000,000: =#,##0=;"; + // Can someone supply me with the right fraud-proof ideographs for // Simplified and Traditional Chinese, and for Korean? Can someone // supply me with information on negatives and decimals? /** - * Spellout rules for Greek. Again in Greek we have to supply the words - * for the multiples of 100 because they can't be derived algorithmically. - * Also, the tens dgit changes form when followed by a ones digit: an - * accent mark disappears from the tens digit and moves to the ones digit. - * Therefore, instead of using the [] notation, we actually have to use - * two separate rules for each multiple of 10 to show the two forms of - * the word. + * Spellout rules for Greek. Again in Greek we have to supply the words for the multiples of 100 + * because they can't be derived algorithmically. Also, the tens dgit changes form when followed + * by a ones digit: an accent mark disappears from the tens digit and moves to the ones digit. + * Therefore, instead of using the [] notation, we actually have to use two separate rules for + * each multiple of 10 to show the two forms of the word. */ public static final String greek = - "zero (incomplete data); \u03ad\u03bd\u03b1; \u03b4\u03cd\u03bf; \u03b4\u03c1\u03af\u03b1; " - + "\u03c4\u03ad\u03c3\u03c3\u03b5\u03c1\u03b1; \u03c0\u03ad\u03bd\u03c4\u03b5; " - + "\u03ad\u03be\u03b9; \u03b5\u03c0\u03c4\u03ac; \u03bf\u03ba\u03c4\u03ce; " - + "\u03b5\u03bd\u03bd\u03ad\u03b1;\n" - + "10: \u03b4\u03ad\u03ba\u03b1; " - + "\u03ad\u03bd\u03b4\u03b5\u03ba\u03b1; \u03b4\u03ce\u03b4\u03b5\u03ba\u03b1; " - + "\u03b4\u03b5\u03ba\u03b1>>;\n" - + "20: \u03b5\u03af\u03ba\u03bf\u03c3\u03b9; \u03b5\u03b9\u03ba\u03bf\u03c3\u03b9>>;\n" - + "30: \u03c4\u03c1\u03b9\u03ac\u03bd\u03c4\u03b1; \u03c4\u03c1\u03b9\u03b1\u03bd\u03c4\u03b1>>;\n" - + "40: \u03c3\u03b1\u03c1\u03ac\u03bd\u03c4\u03b1; \u03c3\u03b1\u03c1\u03b1\u03bd\u03c4\u03b1>>;\n" - + "50: \u03c0\u03b5\u03bd\u03ae\u03bd\u03c4\u03b1; \u03c0\u03b5\u03bd\u03b7\u03bd\u03c4\u03b1>>;\n" - + "60: \u03b5\u03be\u03ae\u03bd\u03c4\u03b1; \u03b5\u03be\u03b7\u03bd\u03c4\u03b1>>;\n" - + "70: \u03b5\u03b2\u03b4\u03bf\u03bc\u03ae\u03bd\u03c4\u03b1; " - + "\u03b5\u03b2\u03b4\u03bf\u03bc\u03b7\u03bd\u03c4\u03b1>>;\n" - + "80: \u03bf\u03b3\u03b4\u03cc\u03bd\u03c4\u03b1; \u03bf\u03b3\u03b4\u03bf\u03bd\u03c4\u03b1>>;\n" - + "90: \u03b5\u03bd\u03bd\u03b5\u03bd\u03ae\u03bd\u03c4\u03b1; " - + "\u03b5\u03bd\u03bd\u03b5\u03bd\u03b7\u03bd\u03c4\u03b1>>;\n" - + "100: \u03b5\u03ba\u03b1\u03c4\u03cc[\u03bd >>];\n" - + "200: \u03b4\u03b9\u03b1\u03ba\u03cc\u03c3\u03b9\u03b1[ >>];\n" - + "300: \u03c4\u03c1\u03b9\u03b1\u03ba\u03cc\u03c3\u03b9\u03b1[ >>];\n" - + "400: \u03c4\u03b5\u03c4\u03c1\u03b1\u03ba\u03cc\u03c3\u03b9\u03b1[ >>];\n" - + "500: \u03c0\u03b5\u03bd\u03c4\u03b1\u03ba\u03cc\u03c3\u03b9\u03b1[ >>];\n" - + "600: \u03b5\u03be\u03b1\u03ba\u03cc\u03c3\u03b9\u03b1[ >>];\n" - + "700: \u03b5\u03c0\u03c4\u03b1\u03ba\u03cc\u03c3\u03b9\u03b1[ >>];\n" - + "800: \u03bf\u03ba\u03c4\u03b1\u03ba\u03cc\u03c3\u03b9\u03b1[ >>];\n" - + "900: \u03b5\u03bd\u03bd\u03b9\u03b1\u03ba\u03cc\u03c3\u03b9\u03b1[ >>];\n" - + "1000: \u03c7\u03af\u03bb\u03b9\u03b1[ >>];\n" - + "2000: << \u03c7\u03af\u03bb\u03b9\u03b1[ >>];\n" - + "1,000,000: << \u03b5\u03ba\u03b1\u03c4\u03bf\u03bc\u03bc\u03b9\u03cc\u03c1\u03b9\u03bf[ >>];\n" - + "1,000,000,000: << \u03b4\u03b9\u03c3\u03b5\u03ba\u03b1\u03c4\u03bf\u03bc\u03bc\u03b9\u03cc\u03c1\u03b9\u03bf[ >>];\n" - + "1,000,000,000,000: =#,##0="; + "zero (incomplete data); \u03ad\u03bd\u03b1; \u03b4\u03cd\u03bf; \u03b4\u03c1\u03af\u03b1; " + + "\u03c4\u03ad\u03c3\u03c3\u03b5\u03c1\u03b1; \u03c0\u03ad\u03bd\u03c4\u03b5; " + + "\u03ad\u03be\u03b9; \u03b5\u03c0\u03c4\u03ac; \u03bf\u03ba\u03c4\u03ce; " + + "\u03b5\u03bd\u03bd\u03ad\u03b1;\n" + + "10: \u03b4\u03ad\u03ba\u03b1; " + + "\u03ad\u03bd\u03b4\u03b5\u03ba\u03b1; \u03b4\u03ce\u03b4\u03b5\u03ba\u03b1; " + + "\u03b4\u03b5\u03ba\u03b1>>;\n" + + "20: \u03b5\u03af\u03ba\u03bf\u03c3\u03b9; \u03b5\u03b9\u03ba\u03bf\u03c3\u03b9>>;\n" + + "30: \u03c4\u03c1\u03b9\u03ac\u03bd\u03c4\u03b1; \u03c4\u03c1\u03b9\u03b1\u03bd\u03c4\u03b1>>;\n" + + "40: \u03c3\u03b1\u03c1\u03ac\u03bd\u03c4\u03b1; \u03c3\u03b1\u03c1\u03b1\u03bd\u03c4\u03b1>>;\n" + + "50: \u03c0\u03b5\u03bd\u03ae\u03bd\u03c4\u03b1; \u03c0\u03b5\u03bd\u03b7\u03bd\u03c4\u03b1>>;\n" + + "60: \u03b5\u03be\u03ae\u03bd\u03c4\u03b1; \u03b5\u03be\u03b7\u03bd\u03c4\u03b1>>;\n" + + "70: \u03b5\u03b2\u03b4\u03bf\u03bc\u03ae\u03bd\u03c4\u03b1; " + + "\u03b5\u03b2\u03b4\u03bf\u03bc\u03b7\u03bd\u03c4\u03b1>>;\n" + + "80: \u03bf\u03b3\u03b4\u03cc\u03bd\u03c4\u03b1; \u03bf\u03b3\u03b4\u03bf\u03bd\u03c4\u03b1>>;\n" + + "90: \u03b5\u03bd\u03bd\u03b5\u03bd\u03ae\u03bd\u03c4\u03b1; " + + "\u03b5\u03bd\u03bd\u03b5\u03bd\u03b7\u03bd\u03c4\u03b1>>;\n" + + "100: \u03b5\u03ba\u03b1\u03c4\u03cc[\u03bd >>];\n" + + "200: \u03b4\u03b9\u03b1\u03ba\u03cc\u03c3\u03b9\u03b1[ >>];\n" + + "300: \u03c4\u03c1\u03b9\u03b1\u03ba\u03cc\u03c3\u03b9\u03b1[ >>];\n" + + "400: \u03c4\u03b5\u03c4\u03c1\u03b1\u03ba\u03cc\u03c3\u03b9\u03b1[ >>];\n" + + "500: \u03c0\u03b5\u03bd\u03c4\u03b1\u03ba\u03cc\u03c3\u03b9\u03b1[ >>];\n" + + "600: \u03b5\u03be\u03b1\u03ba\u03cc\u03c3\u03b9\u03b1[ >>];\n" + + "700: \u03b5\u03c0\u03c4\u03b1\u03ba\u03cc\u03c3\u03b9\u03b1[ >>];\n" + + "800: \u03bf\u03ba\u03c4\u03b1\u03ba\u03cc\u03c3\u03b9\u03b1[ >>];\n" + + "900: \u03b5\u03bd\u03bd\u03b9\u03b1\u03ba\u03cc\u03c3\u03b9\u03b1[ >>];\n" + + "1000: \u03c7\u03af\u03bb\u03b9\u03b1[ >>];\n" + + "2000: << \u03c7\u03af\u03bb\u03b9\u03b1[ >>];\n" + + "1,000,000: << \u03b5\u03ba\u03b1\u03c4\u03bf\u03bc\u03bc\u03b9\u03cc\u03c1\u03b9\u03bf[ >>];\n" + + "1,000,000,000: << \u03b4\u03b9\u03c3\u03b5\u03ba\u03b1\u03c4\u03bf\u03bc\u03bc\u03b9\u03cc\u03c1\u03b9\u03bf[ >>];\n" + + "1,000,000,000,000: =#,##0="; + // Can someone supply me with information on negatives and decimals? // I'm also missing the word for zero. Can someone clue me in? - /** - * Spellout rules for Russian. - */ + /** Spellout rules for Russian. */ public static final String russian = - "\u043d\u043e\u043b\u044c; \u043e\u0434\u0438\u043d; \u0434\u0432\u0430; \u0442\u0440\u0438; " - + "\u0447\u0435\u0442\u044b\u0440\u0435; \u043f\u044f\u0442; \u0448\u0435\u0441\u0442; " - + "\u0441\u0435\u043c\u044c; \u0432\u043e\u0441\u0435\u043c\u044c; \u0434\u0435\u0432\u044f\u0442;\n" - + "10: \u0434\u0435\u0441\u044f\u0442; " - + "\u043e\u0434\u0438\u043d\u043d\u0430\u0434\u0446\u0430\u0442\u044c;\n" - + "\u0434\u0432\u0435\u043d\u043d\u0430\u0434\u0446\u0430\u0442\u044c; " - + "\u0442\u0440\u0438\u043d\u0430\u0434\u0446\u0430\u0442\u044c; " - + "\u0447\u0435\u0442\u044b\u0440\u043d\u0430\u0434\u0446\u0430\u0442\u044c;\n" - + "15: \u043f\u044f\u0442\u043d\u0430\u0434\u0446\u0430\u0442\u044c; " - + "\u0448\u0435\u0441\u0442\u043d\u0430\u0434\u0446\u0430\u0442\u044c; " - + "\u0441\u0435\u043c\u043d\u0430\u0434\u0446\u0430\u0442\u044c; " - + "\u0432\u043e\u0441\u0435\u043c\u043d\u0430\u0434\u0446\u0430\u0442\u044c; " - + "\u0434\u0435\u0432\u044f\u0442\u043d\u0430\u0434\u0446\u0430\u0442\u044c;\n" - + "20: \u0434\u0432\u0430\u0434\u0446\u0430\u0442\u044c[ >>];\n" - + "30: \u0442\u0440\u043b\u0434\u0446\u0430\u0442\u044c[ >>];\n" - + "40: \u0441\u043e\u0440\u043e\u043a[ >>];\n" - + "50: \u043f\u044f\u0442\u044c\u0434\u0435\u0441\u044f\u0442[ >>];\n" - + "60: \u0448\u0435\u0441\u0442\u044c\u0434\u0435\u0441\u044f\u0442[ >>];\n" - + "70: \u0441\u0435\u043c\u044c\u0434\u0435\u0441\u044f\u0442[ >>];\n" - + "80: \u0432\u043e\u0441\u0435\u043c\u044c\u0434\u0435\u0441\u044f\u0442[ >>];\n" - + "90: \u0434\u0435\u0432\u044f\u043d\u043e\u0441\u0442\u043e[ >>];\n" - + "100: \u0441\u0442\u043e[ >>];\n" - + "200: << \u0441\u0442\u043e[ >>];\n" - + "1000: \u0442\u044b\u0441\u044f\u0447\u0430[ >>];\n" - + "2000: << \u0442\u044b\u0441\u044f\u0447\u0430[ >>];\n" - + "1,000,000: \u043c\u0438\u043b\u043b\u0438\u043e\u043d[ >>];\n" - + "2,000,000: << \u043c\u0438\u043b\u043b\u0438\u043e\u043d[ >>];\n" - + "1,000,000,000: =#,##0=;"; + "\u043d\u043e\u043b\u044c; \u043e\u0434\u0438\u043d; \u0434\u0432\u0430; \u0442\u0440\u0438; " + + "\u0447\u0435\u0442\u044b\u0440\u0435; \u043f\u044f\u0442; \u0448\u0435\u0441\u0442; " + + "\u0441\u0435\u043c\u044c; \u0432\u043e\u0441\u0435\u043c\u044c; \u0434\u0435\u0432\u044f\u0442;\n" + + "10: \u0434\u0435\u0441\u044f\u0442; " + + "\u043e\u0434\u0438\u043d\u043d\u0430\u0434\u0446\u0430\u0442\u044c;\n" + + "\u0434\u0432\u0435\u043d\u043d\u0430\u0434\u0446\u0430\u0442\u044c; " + + "\u0442\u0440\u0438\u043d\u0430\u0434\u0446\u0430\u0442\u044c; " + + "\u0447\u0435\u0442\u044b\u0440\u043d\u0430\u0434\u0446\u0430\u0442\u044c;\n" + + "15: \u043f\u044f\u0442\u043d\u0430\u0434\u0446\u0430\u0442\u044c; " + + "\u0448\u0435\u0441\u0442\u043d\u0430\u0434\u0446\u0430\u0442\u044c; " + + "\u0441\u0435\u043c\u043d\u0430\u0434\u0446\u0430\u0442\u044c; " + + "\u0432\u043e\u0441\u0435\u043c\u043d\u0430\u0434\u0446\u0430\u0442\u044c; " + + "\u0434\u0435\u0432\u044f\u0442\u043d\u0430\u0434\u0446\u0430\u0442\u044c;\n" + + "20: \u0434\u0432\u0430\u0434\u0446\u0430\u0442\u044c[ >>];\n" + + "30: \u0442\u0440\u043b\u0434\u0446\u0430\u0442\u044c[ >>];\n" + + "40: \u0441\u043e\u0440\u043e\u043a[ >>];\n" + + "50: \u043f\u044f\u0442\u044c\u0434\u0435\u0441\u044f\u0442[ >>];\n" + + "60: \u0448\u0435\u0441\u0442\u044c\u0434\u0435\u0441\u044f\u0442[ >>];\n" + + "70: \u0441\u0435\u043c\u044c\u0434\u0435\u0441\u044f\u0442[ >>];\n" + + "80: \u0432\u043e\u0441\u0435\u043c\u044c\u0434\u0435\u0441\u044f\u0442[ >>];\n" + + "90: \u0434\u0435\u0432\u044f\u043d\u043e\u0441\u0442\u043e[ >>];\n" + + "100: \u0441\u0442\u043e[ >>];\n" + + "200: << \u0441\u0442\u043e[ >>];\n" + + "1000: \u0442\u044b\u0441\u044f\u0447\u0430[ >>];\n" + + "2000: << \u0442\u044b\u0441\u044f\u0447\u0430[ >>];\n" + + "1,000,000: \u043c\u0438\u043b\u043b\u0438\u043e\u043d[ >>];\n" + + "2,000,000: << \u043c\u0438\u043b\u043b\u0438\u043e\u043d[ >>];\n" + + "1,000,000,000: =#,##0=;"; + // Can someone supply me with information on negatives and decimals? // How about words for billions and trillions? /** - * Spellout rules for Hebrew. Hebrew actually has inflected forms for - * most of the lower-order numbers. The masculine forms are shown - * here. + * Spellout rules for Hebrew. Hebrew actually has inflected forms for most of the lower-order + * numbers. The masculine forms are shown here. */ public static final String hebrew = - "zero (incomplete data); \u05d0\u05d4\u05d3; \u05e9\u05d2\u05d9\u05d9\u05dd; \u05e9\u05dc\u05d5\u05e9\u05d4;\n" - + "4: \u05d0\u05d3\u05d1\u05e6\u05d4; \u05d7\u05d2\u05d5\u05d9\u05e9\u05d4; \u05e9\u05e9\u05d4;\n" - + "7: \u05e9\u05d1\u05e6\u05d4; \u05e9\u05de\u05d5\u05d2\u05d4; \u05ea\u05e9\u05e6\u05d4;\n" - + "10: \u05e6\u05e9\u05d3\u05d4[ >>];\n" - + "20: \u05e6\u05e9\u05d3\u05d9\u05dd[ >>];\n" - + "30: \u05e9\u05dc\u05d5\u05e9\u05d9\u05dd[ >>];\n" - + "40: \u05d0\u05d3\u05d1\u05e6\u05d9\u05dd[ >>];\n" - + "50: \u05d7\u05de\u05d9\u05e9\u05d9\u05dd[ >>];\n" - + "60: \u05e9\u05e9\u05d9\u05dd[ >>];\n" - + "70: \u05e9\u05d1\u05e6\u05d9\u05dd[ >>];\n" - + "80: \u05e9\u05de\u05d5\u05d2\u05d9\u05dd[ >>];\n" - + "90: \u05ea\u05e9\u05e6\u05d9\u05dd[ >>];\n" - + "100: \u05de\u05d0\u05d4[ >>];\n" - + "200: << \u05de\u05d0\u05d4[ >>];\n" - + "1000: \u05d0\u05dc\u05e3[ >>];\n" - + "2000: << \u05d0\u05dc\u05e3[ >>];\n" - + "1,000,000: =#,##0= (incomplete data);"; + "zero (incomplete data); \u05d0\u05d4\u05d3; \u05e9\u05d2\u05d9\u05d9\u05dd; \u05e9\u05dc\u05d5\u05e9\u05d4;\n" + + "4: \u05d0\u05d3\u05d1\u05e6\u05d4; \u05d7\u05d2\u05d5\u05d9\u05e9\u05d4; \u05e9\u05e9\u05d4;\n" + + "7: \u05e9\u05d1\u05e6\u05d4; \u05e9\u05de\u05d5\u05d2\u05d4; \u05ea\u05e9\u05e6\u05d4;\n" + + "10: \u05e6\u05e9\u05d3\u05d4[ >>];\n" + + "20: \u05e6\u05e9\u05d3\u05d9\u05dd[ >>];\n" + + "30: \u05e9\u05dc\u05d5\u05e9\u05d9\u05dd[ >>];\n" + + "40: \u05d0\u05d3\u05d1\u05e6\u05d9\u05dd[ >>];\n" + + "50: \u05d7\u05de\u05d9\u05e9\u05d9\u05dd[ >>];\n" + + "60: \u05e9\u05e9\u05d9\u05dd[ >>];\n" + + "70: \u05e9\u05d1\u05e6\u05d9\u05dd[ >>];\n" + + "80: \u05e9\u05de\u05d5\u05d2\u05d9\u05dd[ >>];\n" + + "90: \u05ea\u05e9\u05e6\u05d9\u05dd[ >>];\n" + + "100: \u05de\u05d0\u05d4[ >>];\n" + + "200: << \u05de\u05d0\u05d4[ >>];\n" + + "1000: \u05d0\u05dc\u05e3[ >>];\n" + + "2000: << \u05d0\u05dc\u05e3[ >>];\n" + + "1,000,000: =#,##0= (incomplete data);"; + // This data is woefully incomplete. Can someone fill me in on the // various inflected forms of the numbers, which seem to be necessary // to do Hebrew correctly? Can somone supply me with data for values // from 1,000,000 on up? What about the word for zero? What about // information on negatives and decimals? - //======================================================================== + // ======================================================================== // Simple examples - //======================================================================== + // ======================================================================== /** - * This rule set adds an English ordinal abbreviation to the end of a - * number. For example, 2 is formatted as "2nd". Parsing doesn't work with - * this rule set. To parse, use DecimalFormat on the numeral. + * This rule set adds an English ordinal abbreviation to the end of a number. For example, 2 is + * formatted as "2nd". Parsing doesn't work with this rule set. To parse, use DecimalFormat on + * the numeral. */ public static final String ordinal = - // this rule set formats the numeral and calls %%abbrev to - // supply the abbreviation - "%main:\n" - + " =#,##0==%%abbrev=;\n" - // this rule set supplies the abbreviation - + "%%abbrev:\n" - // the abbreviations. Everything from 4 to 19 ends in "th" - + " th; st; nd; rd; th;\n" - // at 20, we begin repeating the cycle every 10 (13 is "13th", - // but 23 and 33 are "23rd" and "33rd") We do this by - // ignoring all bug the ones digit in selecting the abbreviation - + " 20: >>;\n" - // at 100, we repeat the whole cycle by considering only the - // tens and ones digits in picking an abbreviation - + " 100: >>;\n"; + // this rule set formats the numeral and calls %%abbrev to + // supply the abbreviation + "%main:\n" + + " =#,##0==%%abbrev=;\n" + // this rule set supplies the abbreviation + + "%%abbrev:\n" + // the abbreviations. Everything from 4 to 19 ends in "th" + + " th; st; nd; rd; th;\n" + // at 20, we begin repeating the cycle every 10 (13 is "13th", + // but 23 and 33 are "23rd" and "33rd") We do this by + // ignoring all bug the ones digit in selecting the abbreviation + + " 20: >>;\n" + // at 100, we repeat the whole cycle by considering only the + // tens and ones digits in picking an abbreviation + + " 100: >>;\n"; /** - * This is a simple message-formatting example. Normally one would - * use ChoiceFormat and MessageFormat to do something this simple, - * but this shows it could be done with RuleBasedNumberFormat too. - * A message-formatting example that might work better with + * This is a simple message-formatting example. Normally one would use ChoiceFormat and + * MessageFormat to do something this simple, but this shows it could be done with + * RuleBasedNumberFormat too. A message-formatting example that might work better with * RuleBasedNumberFormat appears later. */ public static final String message1 = - // this rule surrounds whatever the other rules produce with the - // rest of the sentence - "x.0: The search found <<.;\n" - // use words for values below 10 (and change to "file" for 1) - + "no files; one file; two files; three files; four files; five files;\n" - + " six files; seven files; eight files; nine files;\n" - // use numerals for values higher than 10 - + "=#,##0= files;"; - - //======================================================================== + // this rule surrounds whatever the other rules produce with the + // rest of the sentence + "x.0: The search found <<.;\n" + // use words for values below 10 (and change to "file" for 1) + + "no files; one file; two files; three files; four files; five files;\n" + + " six files; seven files; eight files; nine files;\n" + // use numerals for values higher than 10 + + "=#,##0= files;"; + + // ======================================================================== // Fraction handling // // The next few examples show how RuleBasedNumberFormat can be used for // more flexible handling of fractions - //======================================================================== + // ======================================================================== /** - * This example formats a number in one of the two styles often used - * on checks. %dollars-and-hundredths formats cents as hundredths of - * a dollar (23.40 comes out as "twenty-three and 40/100 dollars"). - * %dollars-and-cents formats in dollars and cents (23.40 comes out as - * "twenty-three dollars and forty cents") + * This example formats a number in one of the two styles often used on checks. + * %dollars-and-hundredths formats cents as hundredths of a dollar (23.40 comes out as + * "twenty-three and 40/100 dollars"). %dollars-and-cents formats in dollars and cents (23.40 + * comes out as "twenty-three dollars and forty cents") */ public static final String dollarsAndCents = - // this rule set formats numbers as dollars and cents - "%dollars-and-cents:\n" - // if the value is 1 or more, put "xx dollars and yy cents". - // the "and y cents" part is suppressed if the value is an - // even number of dollars - + " x.0: << [and >%%cents>];\n" - // if the value is between 0 and 1, put "xx cents" - + " 0.x: >%%cents>;\n" - // these three rules take care of the singular and plural - // forms of "dollar" and use %%main to format the number - + " 0: zero dollars; one dollar; =%%main= dollars;\n" - // these are the regular U.S. English number spellout rules - + "%%main:\n" - + " zero; one; two; three; four; five; six; seven; eight; nine;\n" - + " ten; eleven; twelve; thirteen; fourteen; fifteen; sixteen;\n" - + " seventeen; eighteen; nineteen;\n" - + " 20: twenty[->>];\n" - + " 30: thirty[->>];\n" - + " 40: forty[->>];\n" - + " 50: fifty[->>];\n" - + " 60: sixty[->>];\n" - + " 70: seventy[->>];\n" - + " 80: eighty[->>];\n" - + " 90: ninety[->>];\n" - + " 100: << hundred[ >>];\n" - + " 1000: << thousand[ >>];\n" - + " 1,000,000: << million[ >>];\n" - + " 1,000,000,000: << billion[ >>];\n" - + " 1,000,000,000,000: << trillion[ >>];\n" - + " 1,000,000,000,000,000: =#,##0=;\n" - // this rule takes care of the fractional part of the value. It - // multiplies the fractional part of the number being formatted by - // 100, formats it with %%main, and then addes the word "cent" or - // "cents" to the end. (The text in brackets is omitted if the - // numerator of the fraction is 1.) - + "%%cents:\n" - + " 100: <%%main< cent[s];\n" - - // this rule set formats numbers as dollars and hundredths of dollars - + "%dollars-and-hundredths:\n" - // this rule takes care of the general shell of the output - // string. We always show the cents, even when there aren't - // any. Because of this, the word is always "dollars"-- - // we don't have to worry about the singular form. We use - // %%main to format the number of dollars and %%hundredths to - // format the number of cents - + " x.0: <%%main< and >%%hundredths>/100 dollars;\n" - // this rule set formats the cents for %dollars-and-hundredths. - // It multiplies the fractional part of the number by 100 and formats - // the result using a DecimalFormat ("00" tells the DecimalFormat to - // always use two digits, even for numbers under 10) - + "%%hundredths:\n" - + " 100: <00<;\n"; + // this rule set formats numbers as dollars and cents + "%dollars-and-cents:\n" + // if the value is 1 or more, put "xx dollars and yy cents". + // the "and y cents" part is suppressed if the value is an + // even number of dollars + + " x.0: << [and >%%cents>];\n" + // if the value is between 0 and 1, put "xx cents" + + " 0.x: >%%cents>;\n" + // these three rules take care of the singular and plural + // forms of "dollar" and use %%main to format the number + + " 0: zero dollars; one dollar; =%%main= dollars;\n" + // these are the regular U.S. English number spellout rules + + "%%main:\n" + + " zero; one; two; three; four; five; six; seven; eight; nine;\n" + + " ten; eleven; twelve; thirteen; fourteen; fifteen; sixteen;\n" + + " seventeen; eighteen; nineteen;\n" + + " 20: twenty[->>];\n" + + " 30: thirty[->>];\n" + + " 40: forty[->>];\n" + + " 50: fifty[->>];\n" + + " 60: sixty[->>];\n" + + " 70: seventy[->>];\n" + + " 80: eighty[->>];\n" + + " 90: ninety[->>];\n" + + " 100: << hundred[ >>];\n" + + " 1000: << thousand[ >>];\n" + + " 1,000,000: << million[ >>];\n" + + " 1,000,000,000: << billion[ >>];\n" + + " 1,000,000,000,000: << trillion[ >>];\n" + + " 1,000,000,000,000,000: =#,##0=;\n" + // this rule takes care of the fractional part of the value. It + // multiplies the fractional part of the number being formatted by + // 100, formats it with %%main, and then addes the word "cent" or + // "cents" to the end. (The text in brackets is omitted if the + // numerator of the fraction is 1.) + + "%%cents:\n" + + " 100: <%%main< cent[s];\n" + + // this rule set formats numbers as dollars and hundredths of dollars + + "%dollars-and-hundredths:\n" + // this rule takes care of the general shell of the output + // string. We always show the cents, even when there aren't + // any. Because of this, the word is always "dollars"-- + // we don't have to worry about the singular form. We use + // %%main to format the number of dollars and %%hundredths to + // format the number of cents + + " x.0: <%%main< and >%%hundredths>/100 dollars;\n" + // this rule set formats the cents for %dollars-and-hundredths. + // It multiplies the fractional part of the number by 100 and formats + // the result using a DecimalFormat ("00" tells the DecimalFormat to + // always use two digits, even for numbers under 10) + + "%%hundredths:\n" + + " 100: <00<;\n"; /** - * This rule set shows the fractional part of the number as a fraction - * with a power of 10 as the denominator. Some languages don't spell - * out the fractional part of a number as "point one two three," but - * always render it as a fraction. If we still want to treat the fractional - * part of the number as a decimal, then the fraction's denominator - * is always a power of 10. This example does that: 23.125 is formatted - * as "twenty-three and one hundred twenty-five thousandths" (as opposed - * to "twenty-three point one two five" or "twenty-three and one eighth"). + * This rule set shows the fractional part of the number as a fraction with a power of 10 as the + * denominator. Some languages don't spell out the fractional part of a number as "point one two + * three," but always render it as a fraction. If we still want to treat the fractional part of + * the number as a decimal, then the fraction's denominator is always a power of 10. This + * example does that: 23.125 is formatted as "twenty-three and one hundred twenty-five + * thousandths" (as opposed to "twenty-three point one two five" or "twenty-three and one + * eighth"). */ public static final String decimalAsFraction = - // the regular U.S. English spellout rules, with one difference - "%main:\n" - + " -x: minus >>;\n" - // the difference. This rule uses %%frac to show the fractional - // part of the number. Text in brackets is omitted when the - // value is between 0 and 1 (causing 0.3 to come out as "three - // tenths" instead of "zero and three tenths"). - + " x.x: [<< and ]>%%frac>;\n" - + " zero; one; two; three; four; five; six; seven; eight; nine;\n" - + " ten; eleven; twelve; thirteen; fourteen; fifteen; sixteen;\n" - + " seventeen; eighteen; nineteen;\n" - + " twenty[->>];\n" - + " 30: thirty[->>];\n" - + " 40: forty[->>];\n" - + " 50: fifty[->>];\n" - + " 60: sixty[->>];\n" - + " 70: seventy[->>];\n" - + " 80: eighty[->>];\n" - + " 90: ninety[->>];\n" - + " 100: << hundred[ >>];\n" - + " 1000: << thousand[ >>];\n" - + " 1,000,000: << million[ >>];\n" - + " 1,000,000,000: << billion[ >>];\n" - + " 1,000,000,000,000: << trillion[ >>];\n" - + " 1,000,000,000,000,000: =#,##0=;\n" - // the rule set that formats the fractional part of the number. - // The rule that is used is the one that, when its base value is - // multiplied by the fractional part of the number being formatted, - // produces the result closest to zero. Thus, the base values are - // prospective denominators of the fraction. The << marks the place - // where the numerator of the fraction (the result of multiplying the - // fractional part of the number by the rule's base value) is - // placed. Text in brackets is omitted when the numerator is 1, giving - // us the singular and plural forms of the words. - // [In languages where the singular and plural are completely different - // words, the rule can just be stated twice: the second time with - // the plural form.] - + "%%frac:\n" - + " 10: << tenth[s];\n" - + " 100: << hundredth[s];\n" - + " 1000: << thousandth[s];\n" - + " 10,000: << ten-thousandth[s];\n" - + " 100,000: << hundred-thousandth[s];\n" - + " 1,000,000: << millionth[s];"; + // the regular U.S. English spellout rules, with one difference + "%main:\n" + + " -x: minus >>;\n" + // the difference. This rule uses %%frac to show the fractional + // part of the number. Text in brackets is omitted when the + // value is between 0 and 1 (causing 0.3 to come out as "three + // tenths" instead of "zero and three tenths"). + + " x.x: [<< and ]>%%frac>;\n" + + " zero; one; two; three; four; five; six; seven; eight; nine;\n" + + " ten; eleven; twelve; thirteen; fourteen; fifteen; sixteen;\n" + + " seventeen; eighteen; nineteen;\n" + + " twenty[->>];\n" + + " 30: thirty[->>];\n" + + " 40: forty[->>];\n" + + " 50: fifty[->>];\n" + + " 60: sixty[->>];\n" + + " 70: seventy[->>];\n" + + " 80: eighty[->>];\n" + + " 90: ninety[->>];\n" + + " 100: << hundred[ >>];\n" + + " 1000: << thousand[ >>];\n" + + " 1,000,000: << million[ >>];\n" + + " 1,000,000,000: << billion[ >>];\n" + + " 1,000,000,000,000: << trillion[ >>];\n" + + " 1,000,000,000,000,000: =#,##0=;\n" + // the rule set that formats the fractional part of the number. + // The rule that is used is the one that, when its base value is + // multiplied by the fractional part of the number being formatted, + // produces the result closest to zero. Thus, the base values are + // prospective denominators of the fraction. The << marks the place + // where the numerator of the fraction (the result of multiplying the + // fractional part of the number by the rule's base value) is + // placed. Text in brackets is omitted when the numerator is 1, giving + // us the singular and plural forms of the words. + // [In languages where the singular and plural are completely different + // words, the rule can just be stated twice: the second time with + // the plural form.] + + "%%frac:\n" + + " 10: << tenth[s];\n" + + " 100: << hundredth[s];\n" + + " 1000: << thousandth[s];\n" + + " 10,000: << ten-thousandth[s];\n" + + " 100,000: << hundred-thousandth[s];\n" + + " 1,000,000: << millionth[s];"; /** - * Number with closest fraction. This example formats a value using - * numerals, but shows the fractional part as a ratio (fraction) rather - * than a decimal. The fraction always has a denominator between 2 and 10. + * Number with closest fraction. This example formats a value using numerals, but shows the + * fractional part as a ratio (fraction) rather than a decimal. The fraction always has a + * denominator between 2 and 10. */ public static final String closestFraction = - "%main:\n" - // this rule formats the number if it's 1 or more. It formats - // the integral part using a DecimalFormat ("#,##0" puts - // thousands separators in the right places) and the fractional - // part using %%frac. If there is no fractional part, it - // just shows the integral part. - + " x.0: <#,##0<[ >%%frac>];\n" - // this rule formats the number if it's between 0 and 1. It - // shows only the fractional part (0.5 shows up as "1/2," not - // "0 1/2") - + " 0.x: >%%frac>;\n" - // the fraction rule set. This works the same way as the one in the - // preceding example: We multiply the fractional part of the number - // being formatted by each rule's base value and use the rule that - // produces the result closest to 0 (or the first rule that produces 0). - // Since we only provide rules for the numbers from 2 to 10, we know - // we'll get a fraction with a denominator between 2 and 10. - // "<0<" causes the numerator of the fraction to be formatted - // using numerals - + "%%frac:\n" - + " 2: 1/2;\n" - + " 3: <0%%frac>];\n" + // this rule formats the number if it's between 0 and 1. It + // shows only the fractional part (0.5 shows up as "1/2," not + // "0 1/2") + + " 0.x: >%%frac>;\n" + // the fraction rule set. This works the same way as the one in the + // preceding example: We multiply the fractional part of the number + // being formatted by each rule's base value and use the rule that + // produces the result closest to 0 (or the first rule that produces 0). + // Since we only provide rules for the numbers from 2 to 10, we know + // we'll get a fraction with a denominator between 2 and 10. + // "<0<" causes the numerator of the fraction to be formatted + // using numerals + + "%%frac:\n" + + " 2: 1/2;\n" + + " 3: <0%%frac1>];\n" - // this rule is used for values between 0 and 1 and omits the - // integral part - + " 0.x: >%%frac2>;\n" - // this rule set is used to format the fractional part of the number when - // there's an integral part before it (again, we try all denominators - // and use the "best" one) - + "%%frac1:\n" - // for even multiples of 1/4, format the fraction using the - // typographer's fractions - + " 4: <%%quarters<;\n" - // format the value as a number of eighths, sixteenths, or - // thirty-seconds, whichever produces the most accurate value. - // The apostrophe at the front of these rules is ignored, but - // it makes the space that follows it significant. This puts a - // space between the value's integral and fractional parts so - // you can read it - + " 8: ' <0%%frac1>];\n" + // this rule is used for values between 0 and 1 and omits the + // integral part + + " 0.x: >%%frac2>;\n" + // this rule set is used to format the fractional part of the number when + // there's an integral part before it (again, we try all denominators + // and use the "best" one) + + "%%frac1:\n" + // for even multiples of 1/4, format the fraction using the + // typographer's fractions + + " 4: <%%quarters<;\n" + // format the value as a number of eighths, sixteenths, or + // thirty-seconds, whichever produces the most accurate value. + // The apostrophe at the front of these rules is ignored, but + // it makes the space that follows it significant. This puts a + // space between the value's integral and fractional parts so + // you can read it + + " 8: ' <0%%small>;\n" - // otherwise, show between 3 and 6 significant digits of the value - // along with the most appropriate unit - + " 0: =##0.###= m;\n" - + " 1,000: <##0.###< km;\n" - + " 1,000,000: <##0.###< Mm;\n" - + " 1,000,000,000: <##0.###< Gm;\n" - + " 1,000,000,000,000: <#,##0.###< Tm;\n" - // %%small formats the number when it's less then 1. It multiplies the - // value by one billion, and then uses %%small2 to actually do the - // formatting. - + "%%small:\n" - + " 1,000,000,000,000: <%%small2<;\n" - // this rule set actually formats small values. %%small passes this - // rule set a number of picometers, and it takes care of scaling up as - // appropriate in exactly the same way %main does (we can't normally - // handle fractional values this way: here, we're concerned about - // magnitude; most of the time, we're concerned about precsion) - + "%%small2:\n" - + " 0: =##0= pm;\n" - + " 1,000: <##0.###< nm;\n" - + " 1,000,000: <##0.###< \u00b5m;\n" - + " 1,000,000,000: <##0.###< mm;\n"; + "%main:\n" + // for values between 0 and 1, delegate to %%small + + " 0.x: >%%small>;\n" + // otherwise, show between 3 and 6 significant digits of the value + // along with the most appropriate unit + + " 0: =##0.###= m;\n" + + " 1,000: <##0.###< km;\n" + + " 1,000,000: <##0.###< Mm;\n" + + " 1,000,000,000: <##0.###< Gm;\n" + + " 1,000,000,000,000: <#,##0.###< Tm;\n" + // %%small formats the number when it's less then 1. It multiplies the + // value by one billion, and then uses %%small2 to actually do the + // formatting. + + "%%small:\n" + + " 1,000,000,000,000: <%%small2<;\n" + // this rule set actually formats small values. %%small passes this + // rule set a number of picometers, and it takes care of scaling up as + // appropriate in exactly the same way %main does (we can't normally + // handle fractional values this way: here, we're concerned about + // magnitude; most of the time, we're concerned about precsion) + + "%%small2:\n" + + " 0: =##0= pm;\n" + + " 1,000: <##0.###< nm;\n" + + " 1,000,000: <##0.###< \u00b5m;\n" + + " 1,000,000,000: <##0.###< mm;\n"; /** - * A more complicated message-formatting example. Here, in addition to - * handling the singular and plural versions of the word, the value is - * denominated in bytes, kilobytes, or megabytes depending on its magnitude. - * Also notice that it correctly treats a kilobyte as 1,024 bytes (not 1,000), - * and a megabyte as 1,024 kilobytes (not 1,000). + * A more complicated message-formatting example. Here, in addition to handling the singular and + * plural versions of the word, the value is denominated in bytes, kilobytes, or megabytes + * depending on its magnitude. Also notice that it correctly treats a kilobyte as 1,024 bytes + * (not 1,000), and a megabyte as 1,024 kilobytes (not 1,000). */ public static final String message2 = - // this rule supplies the shell of the sentence - "x.0: There << free space on the disk.;\n" - // handle singular and plural forms of "byte" (and format 0 as - // "There is no free space...") - + "0: is no;\n" - + "is one byte of;\n" - + "are =0= bytes of;\n" - // for values above 1,024, format the number in K (since "K" is usually - // promounced "K" regardless of whether it's singular or plural, we - // don't worry about the plural form). The "/1024" here causes us to - // treat a K as 1,024 bytes rather than 1,000 bytes. - + "1024/1024: is <0>];\n" - // format values over 144 in gross - + "144/12: << gross[, >>];\n" - // format values over 1,000 in thousands - + "1000: << thousand[, >>];\n" - // overflow rule. Format values over 10,000 in numerals - + "10,000: =#,##0=;\n"; - - //======================================================================== + // words for numbers... + "zero; one; two; three; four; five; six;\n" + + "seven; eight; nine; ten; eleven;\n" + // format values over 12 in dozens + + "12/12: << dozen[ and >>];\n" + // format values over 144 in gross + + "144/12: << gross[, >>];\n" + // format values over 1,000 in thousands + + "1000: << thousand[, >>];\n" + // overflow rule. Format values over 10,000 in numerals + + "10,000: =#,##0=;\n"; + + // ======================================================================== // Major and minor units // // These examples show how a single value can be divided up into major // and minor units that don't relate to each other by a factor of 10. - //======================================================================== + // ======================================================================== /** - * This example formats a number of seconds in sexagesimal notation - * (i.e., hours, minutes, and seconds). %with-words formats it with - * words (3740 is "1 hour, 2 minutes, 20 seconds") and %in-numerals - * formats it entirely in numerals (3740 is "1:02:20"). + * This example formats a number of seconds in sexagesimal notation (i.e., hours, minutes, and + * seconds). %with-words formats it with words (3740 is "1 hour, 2 minutes, 20 seconds") and + * %in-numerals formats it entirely in numerals (3740 is "1:02:20"). */ public static final String durationInSeconds = - // main rule set for formatting with words - "%with-words:\n" - // take care of singular and plural forms of "second" - + " 0 seconds; 1 second; =0= seconds;\n" - // use %%min to format values greater than 60 seconds - + " 60/60: <%%min<[, >>];\n" - // use %%hr to format values greater than 3,600 seconds - // (the ">>>" below causes us to see the number of minutes - // when when there are zero minutes) - + " 3600/60: <%%hr<[, >>>];\n" - // this rule set takes care of the singular and plural forms - // of "minute" - + "%%min:\n" - + " 0 minutes; 1 minute; =0= minutes;\n" - // this rule set takes care of the singular and plural forms - // of "hour" - + "%%hr:\n" - + " 0 hours; 1 hour; =0= hours;\n" - - // main rule set for formatting in numerals - + "%in-numerals:\n" - // values below 60 seconds are shown with "sec." - + " =0= sec.;\n" - // higher values are shown with colons: %%min-sec is used for - // values below 3,600 seconds... - + " 60: =%%min-sec=;\n" - // ...and %%hr-min-sec is used for values of 3,600 seconds - // and above - + " 3600: =%%hr-min-sec=;\n" - // this rule causes values of less than 10 minutes to show without - // a leading zero - + "%%min-sec:\n" - + " 0: :=00=;\n" - + " 60/60: <0<>>;\n" - // this rule set is used for values of 3,600 or more. Minutes are always - // shown, and always shown with two digits - + "%%hr-min-sec:\n" - + " 0: :=00=;\n" - + " 60/60: <00<>>;\n" - + " 3600/60: <#,##0<:>>>;\n" - // the lenient-parse rules allow several different characters to be used - // as delimiters between hours, minutes, and seconds - + "%%lenient-parse:\n" - + " & : = . = ' ' = -;\n"; + // main rule set for formatting with words + "%with-words:\n" + // take care of singular and plural forms of "second" + + " 0 seconds; 1 second; =0= seconds;\n" + // use %%min to format values greater than 60 seconds + + " 60/60: <%%min<[, >>];\n" + // use %%hr to format values greater than 3,600 seconds + // (the ">>>" below causes us to see the number of minutes + // when when there are zero minutes) + + " 3600/60: <%%hr<[, >>>];\n" + // this rule set takes care of the singular and plural forms + // of "minute" + + "%%min:\n" + + " 0 minutes; 1 minute; =0= minutes;\n" + // this rule set takes care of the singular and plural forms + // of "hour" + + "%%hr:\n" + + " 0 hours; 1 hour; =0= hours;\n" + + // main rule set for formatting in numerals + + "%in-numerals:\n" + // values below 60 seconds are shown with "sec." + + " =0= sec.;\n" + // higher values are shown with colons: %%min-sec is used for + // values below 3,600 seconds... + + " 60: =%%min-sec=;\n" + // ...and %%hr-min-sec is used for values of 3,600 seconds + // and above + + " 3600: =%%hr-min-sec=;\n" + // this rule causes values of less than 10 minutes to show without + // a leading zero + + "%%min-sec:\n" + + " 0: :=00=;\n" + + " 60/60: <0<>>;\n" + // this rule set is used for values of 3,600 or more. Minutes are always + // shown, and always shown with two digits + + "%%hr-min-sec:\n" + + " 0: :=00=;\n" + + " 60/60: <00<>>;\n" + + " 3600/60: <#,##0<:>>>;\n" + // the lenient-parse rules allow several different characters to be used + // as delimiters between hours, minutes, and seconds + + "%%lenient-parse:\n" + + " & : = . = ' ' = -;\n"; /** - * This example formats a number of hours in sexagesimal notation (i.e., - * hours, minutes, and seconds). %with-words formats the value using - * words for the units, and %in-numerals formats the value using only - * numerals. + * This example formats a number of hours in sexagesimal notation (i.e., hours, minutes, and + * seconds). %with-words formats the value using words for the units, and %in-numerals formats + * the value using only numerals. */ public static final String durationInHours = - // main entry point for formatting with words - "%with-words:\n" - // this rule omits minutes and seconds when the value is - // an even number of hours - + " x.0: <<[, >%%min-sec>];\n" - // these rules take care of the singular and plural forms - // of hours - + " 0 hours; 1 hour; =#,##0= hours;\n" - // this rule set takes the fractional part of the number and multiplies - // it by 3,600 (turning it into a number of seconds). Then it delegates - // to %%min-sec-implementation to format the resulting value - + "%%min-sec:\n" - + " 3600: =%%min-sec-implementation=;\n" - // this rule set formats the seconds as either seconds or minutes and - // seconds, and takes care of the singular and plural forms of - // "minute" and "second" - + "%%min-sec-implementation:\n" - + " 0 seconds; 1 second; =0= seconds;\n" - + " 60/60: 1 minute[, >>];\n" - + " 120/60: <0< minutes[, >>];\n" - - // main entry point for formatting in numerals - + "%in-numerals:\n" - // show minutes even for even numbers of hours - + " x.0: <#,##0<:00;\n" - // delegate to %%min-sec2 to format minutes and seconds - + " x.x: <#,##0<:>%%min-sec2>;\n" - // this rule set formats minutes when there is an even number of - // minutes, and delegates to %%min-sec2-implementation when there - // are seconds - + "%%min-sec2:\n" - + " 60: <00<;\n" - + " 3600: <%%min-sec2-implementation<;\n" - // these two rule sets are used to format the minutes and seconds - + "%%min-sec2-implementation:\n" - // if there are fewer than 60 seconds, show the minutes anyway - + " 0: 00:=00=;\n" - // if there are minutes, format them too, and always use 2 digits - // for both minutes and seconds - + " 60: =%%min-sec3=;\n" - + "%%min-sec3:\n" - + " 0: :=00=;\n" - + " 60/60: <00<>>;\n" - // the lenient-parse rules allow the user to use any of several - // characters as delimiters between hours, minutes, and seconds - + "%%lenient-parse:\n" - + " & : = . = ' ' = -;\n"; + // main entry point for formatting with words + "%with-words:\n" + // this rule omits minutes and seconds when the value is + // an even number of hours + + " x.0: <<[, >%%min-sec>];\n" + // these rules take care of the singular and plural forms + // of hours + + " 0 hours; 1 hour; =#,##0= hours;\n" + // this rule set takes the fractional part of the number and multiplies + // it by 3,600 (turning it into a number of seconds). Then it delegates + // to %%min-sec-implementation to format the resulting value + + "%%min-sec:\n" + + " 3600: =%%min-sec-implementation=;\n" + // this rule set formats the seconds as either seconds or minutes and + // seconds, and takes care of the singular and plural forms of + // "minute" and "second" + + "%%min-sec-implementation:\n" + + " 0 seconds; 1 second; =0= seconds;\n" + + " 60/60: 1 minute[, >>];\n" + + " 120/60: <0< minutes[, >>];\n" + + // main entry point for formatting in numerals + + "%in-numerals:\n" + // show minutes even for even numbers of hours + + " x.0: <#,##0<:00;\n" + // delegate to %%min-sec2 to format minutes and seconds + + " x.x: <#,##0<:>%%min-sec2>;\n" + // this rule set formats minutes when there is an even number of + // minutes, and delegates to %%min-sec2-implementation when there + // are seconds + + "%%min-sec2:\n" + + " 60: <00<;\n" + + " 3600: <%%min-sec2-implementation<;\n" + // these two rule sets are used to format the minutes and seconds + + "%%min-sec2-implementation:\n" + // if there are fewer than 60 seconds, show the minutes anyway + + " 0: 00:=00=;\n" + // if there are minutes, format them too, and always use 2 digits + // for both minutes and seconds + + " 60: =%%min-sec3=;\n" + + "%%min-sec3:\n" + + " 0: :=00=;\n" + + " 60/60: <00<>>;\n" + // the lenient-parse rules allow the user to use any of several + // characters as delimiters between hours, minutes, and seconds + + "%%lenient-parse:\n" + + " & : = . = ' ' = -;\n"; /** - * This rule set formats a number of pounds as pounds, shillings, and - * pence in the old English system of currency. + * This rule set formats a number of pounds as pounds, shillings, and pence in the old English + * system of currency. */ public static final String poundsShillingsAndPence = - // for values of 1 or more, format the integral part with a pound - // sign in front, and show shillings and pence if necessary - "%main:\n" - + " x.0: \u00a3<#,##0<[ >%%shillings-and-pence>];\n" - // for values between 0 and 1, omit the number of pounds - + " 0.x: >%%pence-alone>;\n" - // this rule set is used to show shillings and pence. It multiplies - // the fractional part of the number by 240 (the number of pence in a - // pound) and uses %%shillings-and-pence-implementation to format - // the result - + "%%shillings-and-pence:\n" - + " 240: <%%shillings-and-pence-implementation<;\n" - // this rule set is used to show shillings and pence when there are - // no pounds. It also multiplies the value by 240, and then it uses - // %%pence-alone-implementation to format the result. - + "%%pence-alone:\n" - + " 240: <%%pence-alone-implementation<;\n" - // this rule set formats a number of pence when we know we also - // have pounds. We always show shillings (with a 0 if necessary), - // but only show pence if the value isn't an even number of shillings - + "%%shillings-and-pence-implementation:\n" - + " 0/; 0/=0=;\n" - + " 12/12: <00>];\n" - // this rule set formats a number of pence when we know there are - // no pounds. Values less than a shilling are shown with "d." (the - // abbreviation for pence), and values greater than a shilling are - // shown with a shilling bar (and without pence when the value is - // an even number of shillings) - + "%%pence-alone-implementation:\n" - + " =0= d.;\n" - + " 12/12: <00>];\n"; - - //======================================================================== + // for values of 1 or more, format the integral part with a pound + // sign in front, and show shillings and pence if necessary + "%main:\n" + + " x.0: \u00a3<#,##0<[ >%%shillings-and-pence>];\n" + // for values between 0 and 1, omit the number of pounds + + " 0.x: >%%pence-alone>;\n" + // this rule set is used to show shillings and pence. It multiplies + // the fractional part of the number by 240 (the number of pence in a + // pound) and uses %%shillings-and-pence-implementation to format + // the result + + "%%shillings-and-pence:\n" + + " 240: <%%shillings-and-pence-implementation<;\n" + // this rule set is used to show shillings and pence when there are + // no pounds. It also multiplies the value by 240, and then it uses + // %%pence-alone-implementation to format the result. + + "%%pence-alone:\n" + + " 240: <%%pence-alone-implementation<;\n" + // this rule set formats a number of pence when we know we also + // have pounds. We always show shillings (with a 0 if necessary), + // but only show pence if the value isn't an even number of shillings + + "%%shillings-and-pence-implementation:\n" + + " 0/; 0/=0=;\n" + + " 12/12: <00>];\n" + // this rule set formats a number of pence when we know there are + // no pounds. Values less than a shilling are shown with "d." (the + // abbreviation for pence), and values greater than a shilling are + // shown with a shilling bar (and without pence when the value is + // an even number of shillings) + + "%%pence-alone-implementation:\n" + + " =0= d.;\n" + + " 12/12: <00>];\n"; + + // ======================================================================== // Alternate numeration systems // // These examples show how RuleBasedNumberFormat can be used to format // numbers using non-positional numeration systems. - //======================================================================== + // ======================================================================== /** - * Arabic digits. This example formats numbers in Arabic numerals. - * Normally, you'd do this with DecimalFormat, but this shows that - * RuleBasedNumberFormat can handle it too. + * Arabic digits. This example formats numbers in Arabic numerals. Normally, you'd do this with + * DecimalFormat, but this shows that RuleBasedNumberFormat can handle it too. */ public static final String arabicNumerals = - "0; 1; 2; 3; 4; 5; 6; 7; 8; 9;\n" - + "10: <<>>;\n" - + "100: <<>>>;\n" - + "1000: <<,>>>;\n" - + "1,000,000: <<,>>>;\n" - + "1,000,000,000: <<,>>>;\n" - + "1,000,000,000,000: <<,>>>;\n" - + "1,000,000,000,000,000: =#,##0=;\n" - + "-x: ->>;\n" - + "x.x: <<.>>;"; + "0; 1; 2; 3; 4; 5; 6; 7; 8; 9;\n" + + "10: <<>>;\n" + + "100: <<>>>;\n" + + "1000: <<,>>>;\n" + + "1,000,000: <<,>>>;\n" + + "1,000,000,000: <<,>>>;\n" + + "1,000,000,000,000: <<,>>>;\n" + + "1,000,000,000,000,000: =#,##0=;\n" + + "-x: ->>;\n" + + "x.x: <<.>>;"; /** - * Words for digits. Follows the same pattern as the Arabic-numerals - * example above, but uses words for the various digits (e.g., 123 comes - * out as "one two three"). + * Words for digits. Follows the same pattern as the Arabic-numerals example above, but uses + * words for the various digits (e.g., 123 comes out as "one two three"). */ public static final String wordsForDigits = - "-x: minus >>;\n" - + "x.x: << point >>;\n" - + "zero; one; two; three; four; five; six;\n" - + " seven; eight; nine;\n" - + "10: << >>;\n" - + "100: << >>>;\n" - + "1000: <<, >>>;\n" - + "1,000,000: <<, >>>;\n" - + "1,000,000,000: <<, >>>;\n" - + "1,000,000,000,000: <<, >>>;\n" - + "1,000,000,000,000,000: =#,##0=;\n"; + "-x: minus >>;\n" + + "x.x: << point >>;\n" + + "zero; one; two; three; four; five; six;\n" + + " seven; eight; nine;\n" + + "10: << >>;\n" + + "100: << >>>;\n" + + "1000: <<, >>>;\n" + + "1,000,000: <<, >>>;\n" + + "1,000,000,000: <<, >>>;\n" + + "1,000,000,000,000: <<, >>>;\n" + + "1,000,000,000,000,000: =#,##0=;\n"; /** - * This example formats numbers using Chinese characters in the Arabic - * place-value method. This was used historically in China for a while. + * This example formats numbers using Chinese characters in the Arabic place-value method. This + * was used historically in China for a while. */ public static final String chinesePlaceValue = - "\u3007; \u4e00; \u4e8c; \u4e09; \u56db; \u4e94; \u516d; \u4e03; \u516b; \u4e5d;\n" - + "10: <<>>;\n" - + "100: <<>>>;\n" - + "1000: <<>>>;\n" - + "1,000,000: <<>>>;\n" - + "1,000,000,000: <<>>>;\n" - + "1,000,000,000,000: <<>>>;\n" - + "1,000,000,000,000,000: =#,##0=;\n"; + "\u3007; \u4e00; \u4e8c; \u4e09; \u56db; \u4e94; \u516d; \u4e03; \u516b; \u4e5d;\n" + + "10: <<>>;\n" + + "100: <<>>>;\n" + + "1000: <<>>>;\n" + + "1,000,000: <<>>>;\n" + + "1,000,000,000: <<>>>;\n" + + "1,000,000,000,000: <<>>>;\n" + + "1,000,000,000,000,000: =#,##0=;\n"; /** - * Roman numerals. This example has two variants: %modern shows how large - * numbers are usually handled today; %historical ses the older symbols for - * thousands. + * Roman numerals. This example has two variants: %modern shows how large numbers are usually + * handled today; %historical ses the older symbols for thousands. */ public static final String romanNumerals = - "%historical:\n" - + " =%modern=;\n" - // in early Roman numerals, 1,000 was shown with a circle - // bisected by a vertical line. Additional thousands were - // shown by adding more concentric circles, and fives were - // shown by cutting the symbol for next-higher power of 10 - // in half (the letter D for 500 evolved from this). - // We could go beyond 40,000, but Unicode doesn't encode - // the symbols for higher numbers/ - + " 1000: \u2180[>>]; 2000: \u2180\u2180[>>]; 3000: \u2180\u2180\u2180[>>]; 4000: \u2180\u2181[>>];\n" - + " 5000: \u2181[>>]; 6000: \u2181\u2180[>>]; 7000: \u2181\u2180\u2180[>>];\n" - + " 8000: \u2181\u2180\u2180\u2180[>>]; 9000: \u2180\u2182[>>];\n" - + " 10,000: \u2182[>>]; 20,000: \u2182\u2182[>>]; 30,000: \u2182\u2182\u2182[>>];\n" - + " 40,000: =#,##0=;\n" - + "%modern:\n" - + " ; I; II; III; IV; V; VI; VII; VIII; IX;\n" - + " 10: X[>>]; 20: XX[>>]; 30: XXX[>>]; 40: XL[>>]; 50: L[>>];\n" - + " 60: LX[>>]; 70: LXX[>>]; 80: LXXX[>>]; 90: XC[>>];\n" - + " 100: C[>>]; 200: CC[>>]; 300: CCC[>>]; 400: CD[>>]; 500: D[>>];\n" - + " 600: DC[>>]; 700: DCC[>>]; 800: DCCC[>>]; 900: CM[>>];\n" - // in modern Roman numerals, high numbers are generally shown - // by placing a bar over the letters for the lower numbers: - // the bar multiplied a letter's value by 1,000 - + " 1000: M[>>]; 2000: MM[>>]; 3000: MMM[>>]; 4000: MV\u0306[>>];\n" - + " 5000: V\u0306[>>]; 6000: V\u0306M[>>]; 7000: V\u0306MM[>>];\n" - + " 8000: V\u0306MMM[>>]; 9000: MX\u0306[>>];\n" - + " 10,000: X\u0306[>>]; 20,000: X\u0306X\u0306[>>]; 30,000: X\u0306X\u0306X\u0306[>>];\n" - + " 40,000: X\u0306L\u0306[>>]; 50,000: L\u0306[>>]; 60,000: L\u0306X\u0306[>>];\n" - + " 70,000: L\u0306X\u0306X\u0306[>>]; 80,000: L\u0306X\u0306X\u0306X\u0306[>>];\n" - + " 90,000: X\u0306C\u0306[>>];\n" - + " 100,000: C\u0306[>>]; 200,000: C\u0306C\u0306[>>]; 300,000: C\u0306C\u0306[>>];\n" - + " 400,000: C\u0306D\u0306[>>]; 500,000: D\u0306[>>]; 600,000: D\u0306C\u0306[>>];\n" - + " 700,000: D\u0306C\u0306C\u0306[>>]; 800,000: D\u0306C\u0306C\u0306C\u0306[>>];\n" - + " 900,000: =#,##0=;\n"; + "%historical:\n" + + " =%modern=;\n" + // in early Roman numerals, 1,000 was shown with a circle + // bisected by a vertical line. Additional thousands were + // shown by adding more concentric circles, and fives were + // shown by cutting the symbol for next-higher power of 10 + // in half (the letter D for 500 evolved from this). + // We could go beyond 40,000, but Unicode doesn't encode + // the symbols for higher numbers/ + + " 1000: \u2180[>>]; 2000: \u2180\u2180[>>]; 3000: \u2180\u2180\u2180[>>]; 4000: \u2180\u2181[>>];\n" + + " 5000: \u2181[>>]; 6000: \u2181\u2180[>>]; 7000: \u2181\u2180\u2180[>>];\n" + + " 8000: \u2181\u2180\u2180\u2180[>>]; 9000: \u2180\u2182[>>];\n" + + " 10,000: \u2182[>>]; 20,000: \u2182\u2182[>>]; 30,000: \u2182\u2182\u2182[>>];\n" + + " 40,000: =#,##0=;\n" + + "%modern:\n" + + " ; I; II; III; IV; V; VI; VII; VIII; IX;\n" + + " 10: X[>>]; 20: XX[>>]; 30: XXX[>>]; 40: XL[>>]; 50: L[>>];\n" + + " 60: LX[>>]; 70: LXX[>>]; 80: LXXX[>>]; 90: XC[>>];\n" + + " 100: C[>>]; 200: CC[>>]; 300: CCC[>>]; 400: CD[>>]; 500: D[>>];\n" + + " 600: DC[>>]; 700: DCC[>>]; 800: DCCC[>>]; 900: CM[>>];\n" + // in modern Roman numerals, high numbers are generally shown + // by placing a bar over the letters for the lower numbers: + // the bar multiplied a letter's value by 1,000 + + " 1000: M[>>]; 2000: MM[>>]; 3000: MMM[>>]; 4000: MV\u0306[>>];\n" + + " 5000: V\u0306[>>]; 6000: V\u0306M[>>]; 7000: V\u0306MM[>>];\n" + + " 8000: V\u0306MMM[>>]; 9000: MX\u0306[>>];\n" + + " 10,000: X\u0306[>>]; 20,000: X\u0306X\u0306[>>]; 30,000: X\u0306X\u0306X\u0306[>>];\n" + + " 40,000: X\u0306L\u0306[>>]; 50,000: L\u0306[>>]; 60,000: L\u0306X\u0306[>>];\n" + + " 70,000: L\u0306X\u0306X\u0306[>>]; 80,000: L\u0306X\u0306X\u0306X\u0306[>>];\n" + + " 90,000: X\u0306C\u0306[>>];\n" + + " 100,000: C\u0306[>>]; 200,000: C\u0306C\u0306[>>]; 300,000: C\u0306C\u0306[>>];\n" + + " 400,000: C\u0306D\u0306[>>]; 500,000: D\u0306[>>]; 600,000: D\u0306C\u0306[>>];\n" + + " 700,000: D\u0306C\u0306C\u0306[>>]; 800,000: D\u0306C\u0306C\u0306C\u0306[>>];\n" + + " 900,000: =#,##0=;\n"; /** - * Hebrew alphabetic numerals. Before adoption of Arabic numerals, Hebrew speakers - * used the letter of their alphabet as numerals. The first nine letters of - * the alphabet represented the values from 1 to 9, the second nine letters the - * multiples of 10, and the remaining letters the multiples of 100. Since they - * ran out of letters at 400, the remaining multiples of 100 were represented - * using combinations of the existing letters for the hundreds. Numbers were - * distinguished from words in a number of different ways: the way shown here - * uses a single mark after a number consisting of one letter, and a double - * mark between the last two letters of a number consisting of two or more - * letters. Two dots over a letter multiplied its value by 1,000. Also, since - * the letter for 10 is the first letter of God's name and the letters for 5 and 6 - * are letters in God's name, which wasn't supposed to be written or spoken, 15 and - * 16 were usually written as 9 + 6 and 9 + 7 instead of 10 + 5 and 10 + 6. + * Hebrew alphabetic numerals. Before adoption of Arabic numerals, Hebrew speakers used the + * letter of their alphabet as numerals. The first nine letters of the alphabet represented the + * values from 1 to 9, the second nine letters the multiples of 10, and the remaining letters + * the multiples of 100. Since they ran out of letters at 400, the remaining multiples of 100 + * were represented using combinations of the existing letters for the hundreds. Numbers were + * distinguished from words in a number of different ways: the way shown here uses a single mark + * after a number consisting of one letter, and a double mark between the last two letters of a + * number consisting of two or more letters. Two dots over a letter multiplied its value by + * 1,000. Also, since the letter for 10 is the first letter of God's name and the letters for 5 + * and 6 are letters in God's name, which wasn't supposed to be written or spoken, 15 and 16 + * were usually written as 9 + 6 and 9 + 7 instead of 10 + 5 and 10 + 6. */ public static final String hebrewAlphabetic = - // letters for the ones - "%%ones:\n" - + " (no zero); \u05d0; \u05d1; \u05d2; \u05d3; \u05d4; \u05d5; \u05d6; \u05d7; \u05d8;\n" - // letters for the tens - + "%%tens:\n" - + " ; \u05d9; \u05db; \u05dc; \u05de; \u05e0; \u05e1; \u05e2; \u05e4; \u05e6;\n" - // letters for the first four hundreds - + "%%hundreds:\n" - + " ; \u05e7; \u05e8; \u05e9; \u05ea;\n" - // this rule set is used to write the combination of the tens and ones digits - // when we know that no other digits precede them: they put the numeral marks - // in the right place and properly handle 15 and 16 (I'm using the mathematical - // prime characters for the numeral marks because my Unicode font doesn't - // include the real Hebrew characters, which look just like the prime marks) - + "%%tens-and-ones:\n" - // for values less than 10, just use %%ones and put the numeral mark - // afterward - + " =%%ones=\u2032;\n" - // put the numeral mark at the end for 10, but in the middle for - // 11 through 14 - + " 10: <%%tens<\u2032; <%%tens<\u2033>%%ones>;\n" - // special-case 15 and 16 - + " 15: \u05d8\u2033\u05d5; 16: \u05d8\u2033\u05d6;\n" - // go back to the normal method at 17 - + " 17: <%%tens<\u2033>%%ones>;\n" - // repeat the rules for 10 and 11 to cover the values from 20 to 99 - + " 20: <%%tens<\u2032; <%%tens<\u2033>%%ones>;\n" - // this rule set is used to format numbers below 1,000. It relies on - // %%tens-and-ones to format the tens and ones places, and adds logic - // to handle the high hundreds and the numeral marks when there is no - // tens digit. Notice how the rules are paired: all of these pairs of - // rules take advantage of the rollback rule: if the value (between 100 - // and 499) is an even multiple of 100, the rule for 100 is used; otherwise, - // the rule for 101 (the following rule) is used. The first rule in each - // pair (the one for the even multiple) places the numeral mark in a different - // spot than the second rule in each pair (which knows there are more digits - // and relies on the rule supplying them to also supply the numeral mark). - // The call to %%null in line 10 is there simply to invoke the rollback - // rule. - + "%%low-order:\n" - // this rule is only called when there are other characters before. - // It places the numeral mark before the last digit - + " \u2033=%%ones=;\n" - // the rule for 10 places the numeral mark before the 10 character - // (because we know it's the last character); the rule for 11 relies - // on %%tens-and-ones to place the numeral mark - + " 10: \u2033<%%tens<; =%%tens-and-ones=>%%null>;\n" - // the rule for 100 places the numeral mark before the 100 character - // (we know it's the last character); the rule for 101 recurses to - // fill in the remaining digits and the numeral mark - + " 100: <%%hundreds<\u2032; <%%hundreds<>>;\n" - // special-case the hundreds from 500 to 900 because they consist of - // more than one character - + " 500: \u05ea\u2033\u05e7; \u05ea\u05e7>>;\n" - + " 600: \u05ea\u2033\u05e8; \u05ea\u05e8>>;\n" - + " 700: \u05ea\u2033\u05e9; \u05ea\u05e9>>;\n" - + " 800: \u05ea\u2033\u05ea; \u05ea\u05ea>>;\n" - + " 900: \u05ea\u05ea\u2033\u05e7; \u05ea\u05ea\u05e7>>;\n" - // this rule set is used to format values of 1,000 or more. Here, we don't - // worry about the numeral mark, and we add two dots (the Unicode combining - // diaeresis character) to ever letter - + "%%high-order:\n" - // put the ones digit, followed by the diaeresis - + " =%%ones=\u0308;\n" - // the tens can be handled with recursion - + " 10: <%%tens<\u0308[>>];\n" - // still have to special-case 15 and 16 - + " 15: \u05d8\u0308\u05d5\u0308; 16: \u05d8\u003078\u05d6\u0308;\n" - // back to the regular rules at 17 - + " 17: <%%tens<\u0308[>>];\n" - // the hundreds with the dots added (and without worrying about - // placing the numeral mark) - + " 100: <%%hundreds<\u0308[>>];\n" - + " 500: \u05ea\u0308\u05e7\u0308[>>];\n" - + " 600: \u05ea\u0308\u05e8\u0308[>>];\n" - + " 700: \u05ea\u0308\u05e9\u0308[>>];\n" - + " 800: \u05ea\u0308\u05ea\u0308[>>];\n" - + " 900: \u05ea\u0308\u05ea\u0308\u05e7\u0308[>>];\n" - // this rule set doesn't do anything; it's used by some other rules to - // invoke the rollback rule - + " %%null:\n" - + " ;\n" - // the main rule set. - + "%main:\n" - // for values below 10, just output the letter and the numeral mark - + " =%%ones=\u2032;\n" - // for values from 10 to 99, use %%tens-and-ones to do the formatting - + " 10: =%%tens-and-ones=;\n" - // for values from 100 to 999, use %%low-order to do the formatting - + " 100: =%%low-order=;\n" - // for values of 1,000 and over, use %%high-order to do the formatting - + " 1000: <%%high-order<[>%%low-order>];\n"; + // letters for the ones + "%%ones:\n" + + " (no zero); \u05d0; \u05d1; \u05d2; \u05d3; \u05d4; \u05d5; \u05d6; \u05d7; \u05d8;\n" + // letters for the tens + + "%%tens:\n" + + " ; \u05d9; \u05db; \u05dc; \u05de; \u05e0; \u05e1; \u05e2; \u05e4; \u05e6;\n" + // letters for the first four hundreds + + "%%hundreds:\n" + + " ; \u05e7; \u05e8; \u05e9; \u05ea;\n" + // this rule set is used to write the combination of the tens and ones digits + // when we know that no other digits precede them: they put the numeral marks + // in the right place and properly handle 15 and 16 (I'm using the mathematical + // prime characters for the numeral marks because my Unicode font doesn't + // include the real Hebrew characters, which look just like the prime marks) + + "%%tens-and-ones:\n" + // for values less than 10, just use %%ones and put the numeral mark + // afterward + + " =%%ones=\u2032;\n" + // put the numeral mark at the end for 10, but in the middle for + // 11 through 14 + + " 10: <%%tens<\u2032; <%%tens<\u2033>%%ones>;\n" + // special-case 15 and 16 + + " 15: \u05d8\u2033\u05d5; 16: \u05d8\u2033\u05d6;\n" + // go back to the normal method at 17 + + " 17: <%%tens<\u2033>%%ones>;\n" + // repeat the rules for 10 and 11 to cover the values from 20 to 99 + + " 20: <%%tens<\u2032; <%%tens<\u2033>%%ones>;\n" + // this rule set is used to format numbers below 1,000. It relies on + // %%tens-and-ones to format the tens and ones places, and adds logic + // to handle the high hundreds and the numeral marks when there is no + // tens digit. Notice how the rules are paired: all of these pairs of + // rules take advantage of the rollback rule: if the value (between 100 + // and 499) is an even multiple of 100, the rule for 100 is used; otherwise, + // the rule for 101 (the following rule) is used. The first rule in each + // pair (the one for the even multiple) places the numeral mark in a different + // spot than the second rule in each pair (which knows there are more digits + // and relies on the rule supplying them to also supply the numeral mark). + // The call to %%null in line 10 is there simply to invoke the rollback + // rule. + + "%%low-order:\n" + // this rule is only called when there are other characters before. + // It places the numeral mark before the last digit + + " \u2033=%%ones=;\n" + // the rule for 10 places the numeral mark before the 10 character + // (because we know it's the last character); the rule for 11 relies + // on %%tens-and-ones to place the numeral mark + + " 10: \u2033<%%tens<; =%%tens-and-ones=>%%null>;\n" + // the rule for 100 places the numeral mark before the 100 character + // (we know it's the last character); the rule for 101 recurses to + // fill in the remaining digits and the numeral mark + + " 100: <%%hundreds<\u2032; <%%hundreds<>>;\n" + // special-case the hundreds from 500 to 900 because they consist of + // more than one character + + " 500: \u05ea\u2033\u05e7; \u05ea\u05e7>>;\n" + + " 600: \u05ea\u2033\u05e8; \u05ea\u05e8>>;\n" + + " 700: \u05ea\u2033\u05e9; \u05ea\u05e9>>;\n" + + " 800: \u05ea\u2033\u05ea; \u05ea\u05ea>>;\n" + + " 900: \u05ea\u05ea\u2033\u05e7; \u05ea\u05ea\u05e7>>;\n" + // this rule set is used to format values of 1,000 or more. Here, we don't + // worry about the numeral mark, and we add two dots (the Unicode combining + // diaeresis character) to ever letter + + "%%high-order:\n" + // put the ones digit, followed by the diaeresis + + " =%%ones=\u0308;\n" + // the tens can be handled with recursion + + " 10: <%%tens<\u0308[>>];\n" + // still have to special-case 15 and 16 + + " 15: \u05d8\u0308\u05d5\u0308; 16: \u05d8\u003078\u05d6\u0308;\n" + // back to the regular rules at 17 + + " 17: <%%tens<\u0308[>>];\n" + // the hundreds with the dots added (and without worrying about + // placing the numeral mark) + + " 100: <%%hundreds<\u0308[>>];\n" + + " 500: \u05ea\u0308\u05e7\u0308[>>];\n" + + " 600: \u05ea\u0308\u05e8\u0308[>>];\n" + + " 700: \u05ea\u0308\u05e9\u0308[>>];\n" + + " 800: \u05ea\u0308\u05ea\u0308[>>];\n" + + " 900: \u05ea\u0308\u05ea\u0308\u05e7\u0308[>>];\n" + // this rule set doesn't do anything; it's used by some other rules to + // invoke the rollback rule + + " %%null:\n" + + " ;\n" + // the main rule set. + + "%main:\n" + // for values below 10, just output the letter and the numeral mark + + " =%%ones=\u2032;\n" + // for values from 10 to 99, use %%tens-and-ones to do the formatting + + " 10: =%%tens-and-ones=;\n" + // for values from 100 to 999, use %%low-order to do the formatting + + " 100: =%%low-order=;\n" + // for values of 1,000 and over, use %%high-order to do the formatting + + " 1000: <%%high-order<[>%%low-order>];\n"; /** - * Greek alphabetic numerals. The Greeks, before adopting the Arabic numerals, - * also used the letters of their alphabet as numerals. There are three now- - * obsolete Greek letters that are used as numerals; many fonts don't have them. - * Large numbers were handled many different ways; the way shown here divides - * large numbers into groups of four letters (factors of 10,000), and separates - * the groups with the capital letter mu (for myriad). Capital letters are used - * for values below 10,000; small letters for higher numbers (to make the capital - * mu stand out). + * Greek alphabetic numerals. The Greeks, before adopting the Arabic numerals, also used the + * letters of their alphabet as numerals. There are three now- obsolete Greek letters that are + * used as numerals; many fonts don't have them. Large numbers were handled many different ways; + * the way shown here divides large numbers into groups of four letters (factors of 10,000), and + * separates the groups with the capital letter mu (for myriad). Capital letters are used for + * values below 10,000; small letters for higher numbers (to make the capital mu stand out). */ public static final String greekAlphabetic = - // this rule set is used for formatting numbers below 10,000. It uses - // capital letters. - "%%low-order:\n" - + " (no zero); \u0391; \u0392; \u0393; \u0394; \u0395; \u03dc; \u0396; \u0397; \u0398;\n" - + " 10: \u0399[>>]; 20: \u039a[>>]; 30: \u039b[>>]; 40: \u039c[>>]; 50: \u039d[>>];\n" - + " 60: \u039e[>>]; 70: \u039f[>>]; 80: \u03a0[>>]; 90: \u03de[>>];\n" - + " 100: \u03a1[>>]; 200: \u03a3[>>]; 300: \u03a4[>>]; 400: \u03a5[>>];\n" - + " 500: \u03a6[>>]; 600: \u03a7[>>]; 700: \u03a8[>>]; 800: \u03a9[>>];\n" - + " 900: \u03e0[>>];\n" - // the thousands are represented by the same numbers as the ones, but - // with a comma-like mark added to their left shoulder - + " 1000: \u0391\u0313[>>]; 2000: \u0392\u0313[>>]; 3000: \u0393\u0313[>>];\n" - + " 4000: \u0394\u0313[>>]; 5000: \u0395\u0313[>>]; 6000: \u03dc\u0313[>>];\n" - + " 7000: \u0396\u0313[>>]; 8000: \u0397\u0313[>>]; 9000: \u0398\u0313[>>];\n" - // this rule set is the same as above, but uses lowercase letters. It is used - // for formatting the groups in numbers above 10,000. - + "%%high-order:\n" - + " (no zero); \u03b1; \u03b2; \u03b3; \u03b4; \u03b5; \u03dc; \u03b6; \u03b7; \u03b8;\n" - + " 10: \u03b9[>>]; 20: \u03ba[>>]; 30: \u03bb[>>]; 40: \u03bc[>>]; 50: \u03bd[>>];\n" - + " 60: \u03be[>>]; 70: \u03bf[>>]; 80: \u03c0[>>]; 90: \u03de[>>];\n" - + " 100: \u03c1[>>]; 200: \u03c3[>>]; 300: \u03c4[>>]; 400: \u03c5[>>];\n" - + " 500: \u03c6[>>]; 600: \u03c7[>>]; 700: \u03c8[>>]; 800: \u03c9[>>];\n" - + " 900: \u03c0[>>];\n" - + " 1000: \u03b1\u0313[>>]; 2000: \u03b2\u0313[>>]; 3000: \u03b3\u0313[>>];\n" - + " 4000: \u03b4\u0313[>>]; 5000: \u03b5\u0313[>>]; 6000: \u03dc\u0313[>>];\n" - + " 7000: \u03b6\u0313[>>]; 8000: \u03b7\u0313[>>]; 9000: \u03b8\u0313[>>];\n" - // the main rule set - + "%main:\n" - // for values below 10,000, just use %%low-order - + " =%%low-order=;\n" - // for values above 10,000, split into two groups of four digits - // and format each with %%high-order (putting an M in between) - + " 10,000: <%%high-order<\u039c>%%high-order>;\n" - // for values above 100,000,000, add another group onto the front - // and another M - + " 100,000,000: <%%high-order<\u039c>>\n"; - - /** - * A list of all the sample rule sets, used by the demo program. - */ - public static final String[] sampleRuleSets = - { usEnglish, - ukEnglish, - spanish, - french, - swissFrench, - german, - italian, - swedish, - dutch, - japanese, - greek, - russian, - hebrew, - ordinal, - message1, - dollarsAndCents, - decimalAsFraction, - closestFraction, - stock, - abbEnglish, - units, - message2, - dozens, - durationInSeconds, - durationInHours, - poundsShillingsAndPence, - arabicNumerals, - wordsForDigits, - chinesePlaceValue, - romanNumerals, - hebrewAlphabetic, - greekAlphabetic }; + // this rule set is used for formatting numbers below 10,000. It uses + // capital letters. + "%%low-order:\n" + + " (no zero); \u0391; \u0392; \u0393; \u0394; \u0395; \u03dc; \u0396; \u0397; \u0398;\n" + + " 10: \u0399[>>]; 20: \u039a[>>]; 30: \u039b[>>]; 40: \u039c[>>]; 50: \u039d[>>];\n" + + " 60: \u039e[>>]; 70: \u039f[>>]; 80: \u03a0[>>]; 90: \u03de[>>];\n" + + " 100: \u03a1[>>]; 200: \u03a3[>>]; 300: \u03a4[>>]; 400: \u03a5[>>];\n" + + " 500: \u03a6[>>]; 600: \u03a7[>>]; 700: \u03a8[>>]; 800: \u03a9[>>];\n" + + " 900: \u03e0[>>];\n" + // the thousands are represented by the same numbers as the ones, but + // with a comma-like mark added to their left shoulder + + " 1000: \u0391\u0313[>>]; 2000: \u0392\u0313[>>]; 3000: \u0393\u0313[>>];\n" + + " 4000: \u0394\u0313[>>]; 5000: \u0395\u0313[>>]; 6000: \u03dc\u0313[>>];\n" + + " 7000: \u0396\u0313[>>]; 8000: \u0397\u0313[>>]; 9000: \u0398\u0313[>>];\n" + // this rule set is the same as above, but uses lowercase letters. It is used + // for formatting the groups in numbers above 10,000. + + "%%high-order:\n" + + " (no zero); \u03b1; \u03b2; \u03b3; \u03b4; \u03b5; \u03dc; \u03b6; \u03b7; \u03b8;\n" + + " 10: \u03b9[>>]; 20: \u03ba[>>]; 30: \u03bb[>>]; 40: \u03bc[>>]; 50: \u03bd[>>];\n" + + " 60: \u03be[>>]; 70: \u03bf[>>]; 80: \u03c0[>>]; 90: \u03de[>>];\n" + + " 100: \u03c1[>>]; 200: \u03c3[>>]; 300: \u03c4[>>]; 400: \u03c5[>>];\n" + + " 500: \u03c6[>>]; 600: \u03c7[>>]; 700: \u03c8[>>]; 800: \u03c9[>>];\n" + + " 900: \u03c0[>>];\n" + + " 1000: \u03b1\u0313[>>]; 2000: \u03b2\u0313[>>]; 3000: \u03b3\u0313[>>];\n" + + " 4000: \u03b4\u0313[>>]; 5000: \u03b5\u0313[>>]; 6000: \u03dc\u0313[>>];\n" + + " 7000: \u03b6\u0313[>>]; 8000: \u03b7\u0313[>>]; 9000: \u03b8\u0313[>>];\n" + // the main rule set + + "%main:\n" + // for values below 10,000, just use %%low-order + + " =%%low-order=;\n" + // for values above 10,000, split into two groups of four digits + // and format each with %%high-order (putting an M in between) + + " 10,000: <%%high-order<\u039c>%%high-order>;\n" + // for values above 100,000,000, add another group onto the front + // and another M + + " 100,000,000: <%%high-order<\u039c>>\n"; + + /** A list of all the sample rule sets, used by the demo program. */ + public static final String[] sampleRuleSets = { + usEnglish, + ukEnglish, + spanish, + french, + swissFrench, + german, + italian, + swedish, + dutch, + japanese, + greek, + russian, + hebrew, + ordinal, + message1, + dollarsAndCents, + decimalAsFraction, + closestFraction, + stock, + abbEnglish, + units, + message2, + dozens, + durationInSeconds, + durationInHours, + poundsShillingsAndPence, + arabicNumerals, + wordsForDigits, + chinesePlaceValue, + romanNumerals, + hebrewAlphabetic, + greekAlphabetic + }; /** - * The displayable names for all the sample rule sets, in the same order as - * the preceding array. + * The displayable names for all the sample rule sets, in the same order as the preceding array. */ - public static final String[] sampleRuleSetNames = - { "English (US)", - "English (UK)", - "Spanish", - "French (France)", - "French (Switzerland)", - "German", - "Italian", - "Swedish", - "Dutch", - "Japanese", - "Greek", - "Russian", - "Hebrew", - "English ordinal abbreviations", - "Simple message formatting", - "Dollars and cents", - "Decimals as fractions", - "Closest fraction", - "Stock prices", - "Abbreviated US English", - "Changing dimensions", - "Complex message formatting", - "Dozens", - "Duration (value in seconds)", - "Duration (value in hours)", - "Pounds, shillings, and pence", - "Arabic numerals", - "Words for digits", - "Chinese place-value notation", - "Roman numerals", - "Hebrew alphabetic numerals", - "Greek alphabetic numerals" }; + public static final String[] sampleRuleSetNames = { + "English (US)", + "English (UK)", + "Spanish", + "French (France)", + "French (Switzerland)", + "German", + "Italian", + "Swedish", + "Dutch", + "Japanese", + "Greek", + "Russian", + "Hebrew", + "English ordinal abbreviations", + "Simple message formatting", + "Dollars and cents", + "Decimals as fractions", + "Closest fraction", + "Stock prices", + "Abbreviated US English", + "Changing dimensions", + "Complex message formatting", + "Dozens", + "Duration (value in seconds)", + "Duration (value in hours)", + "Pounds, shillings, and pence", + "Arabic numerals", + "Words for digits", + "Chinese place-value notation", + "Roman numerals", + "Hebrew alphabetic numerals", + "Greek alphabetic numerals" + }; /** - * The base locale for each of the sample rule sets. The locale is used to - * determine DecimalFormat behavior, lenient-parse behavior, and text-display - * selection (we have a hack in here to allow display of non-Latin scripts). - * Null means the locale setting is irrelevant and the default can be used. + * The base locale for each of the sample rule sets. The locale is used to determine + * DecimalFormat behavior, lenient-parse behavior, and text-display selection (we have a hack in + * here to allow display of non-Latin scripts). Null means the locale setting is irrelevant and + * the default can be used. */ - public static final Locale[] sampleRuleSetLocales = - { Locale.US, - Locale.UK, - new Locale("es", "", ""), - Locale.FRANCE, - new Locale("fr", "CH", ""), - Locale.GERMAN, - Locale.ITALIAN, - new Locale("sv", "", ""), - new Locale("nl", "", ""), - Locale.JAPANESE, - new Locale("el", "", ""), - new Locale("ru", "", ""), - new Locale("iw", "", ""), - Locale.ENGLISH, - Locale.ENGLISH, - Locale.US, - Locale.ENGLISH, - null, - null, - Locale.ENGLISH, - null, - Locale.ENGLISH, - Locale.ENGLISH, - null, - null, - Locale.UK, - null, - Locale.ENGLISH, - new Locale("zh", "", ""), - null, - new Locale("iw", "", ""), - new Locale("el", "", ""), - null }; - - public static final String[] sampleRuleSetCommentary = { - "This demonstration version of the " - + "U.S. English spellout rules has four variants: 1) %simplified is a " - + "set of rules showing the simple method of spelling out numbers in " - + "English: 289 is formatted as \"two hundred eighty-nine\". 2) %alt-teens " - + "is the same as %simplified, except that values between 1,000 and 9,999 " - + "whose hundreds place isn't zero are formatted in hundreds. For example, " - + "1,983 is formatted as \"nineteen hundred eighty-three,\" and 2,183 is " - + "formatted as \"twenty-one hundred eighty-three,\" but 2,083 is still " - + "formatted as \"two thousand eighty-three.\" 3) %ordinal formats the " - + "values as ordinal numbers in English (e.g., 289 is \"two hundred eighty-" - + "ninth\"). 4) %default uses a more complicated algorithm to format " - + "numbers in a more natural way: 289 is formatted as \"two hundred AND " - + "eighty-nine\" and commas are inserted between the thousands groups for " - + "values above 100,000.", - - "U.K. English has one significant " - + "difference from U.S. English: the names for values of 1,000,000,000 " - + "and higher. In American English, each successive \"-illion\" is 1,000 " - + "times greater than the preceding one: 1,000,000,000 is \"one billion\" " - + "and 1,000,000,000,000 is \"one trillion.\" In British English, each " - + "successive \"-illion\" is one million times greater than the one before: " - + "\"one billion\" is 1,000,000,000,000 (or what Americans would call a " - + "\"trillion\"), and \"one trillion\" is 1,000,000,000,000,000,000. " - + "1,000,000,000 in British English is \"one thousand million.\" (This " - + "value is sometimes called a \"milliard,\" but this word seems to have " - + "fallen into disuse.)", - - "The Spanish rules are quite similar to " - + "the English rules, but there are some important differences: " - + "First, we have to provide separate rules for most of the twenties " - + "because the ones digit frequently picks up an accent mark that it " - + "doesn't have when standing alone. Second, each multiple of 100 has " - + "to be specified separately because the multiplier on 100 very often " - + "changes form in the contraction: 500 is \"quinientos,\" not " - + "\"cincocientos.\" In addition, the word for 100 is \"cien\" when " - + "standing alone, but changes to \"ciento\" when followed by more digits. " - + "There also some other differences.", - - "French adds some interesting quirks of its " - + "own: 1) The word \"et\" is interposed between the tens and ones digits, " - + "but only if the ones digit if 1: 20 is \"vingt,\" and 2 is \"vingt-deux,\" " - + "but 21 is \"vingt-et-un.\" 2) There are no words for 70, 80, or 90. " - + "\"quatre-vingts\" (\"four twenties\") is used for 80, and values proceed " - + "by score from 60 to 99 (e.g., 73 is \"soixante-treize\" [\"sixty-thirteen\"]). " - + "Numbers from 1,100 to 1,199 are rendered as hundreds rather than " - + "thousands: 1,100 is \"onze cents\" (\"eleven hundred\"), rather than " - + "\"mille cent\" (\"one thousand one hundred\")", - - "Swiss French differs from French French " - + "in that it does have words for 70, 80, and 90. This rule set shows them, " - + "and is simpler as a result.", - - "German also adds some interesting " - + "characteristics. For values below 1,000,000, numbers are customarily " - + "written out as a single word. And the ones digit PRECEDES the tens " - + "digit (e.g., 23 is \"dreiundzwanzig,\" not \"zwanzigunddrei\").", - - "Like German, most Italian numbers are " - + "written as single words. What makes these rules complicated is the rule " - + "that says that when a word ending in a vowel and a word beginning with " - + "a vowel are combined into a compound, the vowel is dropped from the " - + "end of the first word: 180 is \"centottanta,\" not \"centoottanta.\" " - + "The complexity of this rule set is to produce this behavior.", - - "Spellout rules for Swedish.", - - "Spellout rules for Dutch. Notice that in Dutch, as in German," - + "the ones digit precedes the tens digit.", - - "In Japanese, there really isn't any " - + "distinction between a number written out in digits and a number " - + "written out in words: the ideographic characters are both digits " - + "and words. This rule set provides two variants: %traditional " - + "uses the traditional CJK numerals (which are also used in China " - + "and Korea). %financial uses alternate ideographs for many numbers " - + "that are harder to alter than the traditional numerals (one could " - + "fairly easily change a one to " - + "a three just by adding two strokes, for example). This is also done in " - + "the other countries using Chinese ideographs, but different ideographs " - + "are used in those places.", - - "Again in Greek we have to supply the words " - + "for the multiples of 100 because they can't be derived algorithmically. " - + "Also, the tens dgit changes form when followed by a ones digit: an " - + "accent mark disappears from the tens digit and moves to the ones digit. " - + "Therefore, instead of using the [] notation, we actually have to use " - + "two separate rules for each multiple of 10 to show the two forms of " - + "the word.", - - "Spellout rules for Russian.", - - "Spellout rules for Hebrew. Hebrew actually has inflected forms for " - + "most of the lower-order numbers. The masculine forms are shown " - + "here.", - - "This rule set adds an English ordinal abbreviation to the end of a " - + "number. For example, 2 is formatted as \"2nd\". Parsing doesn't work with " - + "this rule set. To parse, use DecimalFormat on the numeral.", - - "This is a simple message-formatting example. Normally one would " - + "use ChoiceFormat and MessageFormat to do something this simple, " - + "but this shows it could be done with RuleBasedNumberFormat too. " - + "A message-formatting example that might work better with " - + "RuleBasedNumberFormat appears later.", - - "The next few examples demonstrate fraction handling. " - + "This example formats a number in one of the two styles often used " - + "on checks. %dollars-and-hundredths formats cents as hundredths of " - + "a dollar (23.40 comes out as \"twenty-three and 40/100 dollars\"). " - + "%dollars-and-cents formats in dollars and cents (23.40 comes out as " - + "\"twenty-three dollars and forty cents\")", - - "This rule set shows the fractional part of the number as a fraction " - + "with a power of 10 as the denominator. Some languages don't spell " - + "out the fractional part of a number as \"point one two three,\" but " - + "always render it as a fraction. If we still want to treat the fractional " - + "part of the number as a decimal, then the fraction's denominator " - + "is always a power of 10. This example does that: 23.125 is formatted " - + "as \"twenty-three and one hundred twenty-five thousandths\" (as opposed " - + "to \"twenty-three point one two five\" or \"twenty-three and one eighth\").", - - "Number with closest fraction. This example formats a value using " - + "numerals, but shows the fractional part as a ratio (fraction) rather " - + "than a decimal. The fraction always has a denominator between 2 and 10.", - - "American stock-price formatting. Non-integral stock prices are still " - + "generally shown in eighths or sixteenths of dollars instead of dollars " - + "and cents. This example formats stock prices in this way if possible, " - + "and in dollars and cents if not.", - - "The next few examples demonstrate using a RuleBasedNumberFormat to " - + "change the units a value is denominated in depending on its magnitude. " - + "The example shows large numbers the way they often appear is nwespapers: " - + "1,200,000 is formatted as \"1.2 million\".", - - "This example takes a number of meters and formats it in whatever unit " - + "will produce a number with from one to three digits before the decimal " - + "point. For example, 230,000 is formatted as \"230 km\".", - - "A more complicated message-formatting example. Here, in addition to " - + "handling the singular and plural versions of the word, the value is " - + "denominated in bytes, kilobytes, or megabytes depending on its magnitude. " - + "Also notice that it correctly treats a kilobyte as 1,024 bytes (not 1,000), " - + "and a megabyte as 1,024 kilobytes (not 1,000).", - - "This example formats a number in dozens and gross. This is intended to " - + "demonstrate how this rule set can be used to format numbers in systems " - + "other than base 10. The \"/12\" after the rules' base values controls this. " - + "Also notice that the base doesn't have to be consistent throughout the " - + "whole rule set: we go back to base 10 for values over 1,000.", - - "The next few examples show how a single value can be divided up into major " - + "and minor units that don't relate to each other by a factor of 10. " - + "This example formats a number of seconds in sexagesimal notation " - + "(i.e., hours, minutes, and seconds). %with-words formats it with " - + "words (3740 is \"1 hour, 2 minutes, 20 seconds\") and %in-numerals " - + "formats it entirely in numerals (3740 is \"1:02:20\").", - - "This example formats a number of hours in sexagesimal notation (i.e., " - + "hours, minutes, and seconds). %with-words formats the value using " - + "words for the units, and %in-numerals formats the value using only " - + "numerals.", - - "This rule set formats a number of pounds as pounds, shillings, and " - + "pence in the old English system of currency.", - - "These examples show how RuleBasedNumberFormat can be used to format " - + "numbers using non-positional numeration systems. " - + "This example formats numbers in Arabic numerals. " - + "Normally, you'd do this with DecimalFormat, but this shows that " - + "RuleBasedNumberFormat can handle it too.", - - "This example follows the same pattern as the Arabic-numerals " - + "example, but uses words for the various digits (e.g., 123 comes " - + "out as \"one two three\").", - - "This example formats numbers using Chinese characters in the Arabic " - + "place-value method. This was used historically in China for a while.", - - "Roman numerals. This example has two variants: %modern shows how large " - + "numbers are usually handled today; %historical ses the older symbols for " - + "thousands. Not all of the characters are displayable with most fonts.", - - "Hebrew alphabetic numerals. Before adoption of Arabic numerals, Hebrew speakers " - + "used the letter of their alphabet as numerals. The first nine letters of " - + "the alphabet represented the values from 1 to 9, the second nine letters the " - + "multiples of 10, and the remaining letters the multiples of 100. Since they " - + "ran out of letters at 400, the remaining multiples of 100 were represented " - + "using combinations of the existing letters for the hundreds. Numbers were " - + "distinguished from words in a number of different ways: the way shown here " - + "uses a single mark after a number consisting of one letter, and a double " - + "mark between the last two letters of a number consisting of two or more " - + "letters. Two dots over a letter multiplied its value by 1,000. Also, since " - + "the letter for 10 is the first letter of God's name and the letters for 5 and 6 " - + "are letters in God's name, which wasn't supposed to be written or spoken, 15 and " - + "16 were usually written as 9 + 6 and 9 + 7 instead of 10 + 5 and 10 + 6.", - - "Greek alphabetic numerals. The Greeks, before adopting the Arabic numerals, " - + "also used the letters of their alphabet as numerals. There are three now-" - + "obsolete Greek letters that are used as numerals; many fonts don't have them. " - + "Large numbers were handled many different ways; the way shown here divides " - + "large numbers into groups of four letters (factors of 10,000), and separates " - + "the groups with the capital letter mu (for myriad). Capital letters are used " - + "for values below 10,000; small letters for higher numbers (to make the capital " - + "mu stand out).", - - "This is a custom (user-defined) rule set." - }; + public static final Locale[] sampleRuleSetLocales = { + Locale.US, + Locale.UK, + new Locale("es", "", ""), + Locale.FRANCE, + new Locale("fr", "CH", ""), + Locale.GERMAN, + Locale.ITALIAN, + new Locale("sv", "", ""), + new Locale("nl", "", ""), + Locale.JAPANESE, + new Locale("el", "", ""), + new Locale("ru", "", ""), + new Locale("iw", "", ""), + Locale.ENGLISH, + Locale.ENGLISH, + Locale.US, + Locale.ENGLISH, + null, + null, + Locale.ENGLISH, + null, + Locale.ENGLISH, + Locale.ENGLISH, + null, + null, + Locale.UK, + null, + Locale.ENGLISH, + new Locale("zh", "", ""), + null, + new Locale("iw", "", ""), + new Locale("el", "", ""), + null + }; + + public static final String[] sampleRuleSetCommentary = { + "This demonstration version of the " + + "U.S. English spellout rules has four variants: 1) %simplified is a " + + "set of rules showing the simple method of spelling out numbers in " + + "English: 289 is formatted as \"two hundred eighty-nine\". 2) %alt-teens " + + "is the same as %simplified, except that values between 1,000 and 9,999 " + + "whose hundreds place isn't zero are formatted in hundreds. For example, " + + "1,983 is formatted as \"nineteen hundred eighty-three,\" and 2,183 is " + + "formatted as \"twenty-one hundred eighty-three,\" but 2,083 is still " + + "formatted as \"two thousand eighty-three.\" 3) %ordinal formats the " + + "values as ordinal numbers in English (e.g., 289 is \"two hundred eighty-" + + "ninth\"). 4) %default uses a more complicated algorithm to format " + + "numbers in a more natural way: 289 is formatted as \"two hundred AND " + + "eighty-nine\" and commas are inserted between the thousands groups for " + + "values above 100,000.", + "U.K. English has one significant " + + "difference from U.S. English: the names for values of 1,000,000,000 " + + "and higher. In American English, each successive \"-illion\" is 1,000 " + + "times greater than the preceding one: 1,000,000,000 is \"one billion\" " + + "and 1,000,000,000,000 is \"one trillion.\" In British English, each " + + "successive \"-illion\" is one million times greater than the one before: " + + "\"one billion\" is 1,000,000,000,000 (or what Americans would call a " + + "\"trillion\"), and \"one trillion\" is 1,000,000,000,000,000,000. " + + "1,000,000,000 in British English is \"one thousand million.\" (This " + + "value is sometimes called a \"milliard,\" but this word seems to have " + + "fallen into disuse.)", + "The Spanish rules are quite similar to " + + "the English rules, but there are some important differences: " + + "First, we have to provide separate rules for most of the twenties " + + "because the ones digit frequently picks up an accent mark that it " + + "doesn't have when standing alone. Second, each multiple of 100 has " + + "to be specified separately because the multiplier on 100 very often " + + "changes form in the contraction: 500 is \"quinientos,\" not " + + "\"cincocientos.\" In addition, the word for 100 is \"cien\" when " + + "standing alone, but changes to \"ciento\" when followed by more digits. " + + "There also some other differences.", + "French adds some interesting quirks of its " + + "own: 1) The word \"et\" is interposed between the tens and ones digits, " + + "but only if the ones digit if 1: 20 is \"vingt,\" and 2 is \"vingt-deux,\" " + + "but 21 is \"vingt-et-un.\" 2) There are no words for 70, 80, or 90. " + + "\"quatre-vingts\" (\"four twenties\") is used for 80, and values proceed " + + "by score from 60 to 99 (e.g., 73 is \"soixante-treize\" [\"sixty-thirteen\"]). " + + "Numbers from 1,100 to 1,199 are rendered as hundreds rather than " + + "thousands: 1,100 is \"onze cents\" (\"eleven hundred\"), rather than " + + "\"mille cent\" (\"one thousand one hundred\")", + "Swiss French differs from French French " + + "in that it does have words for 70, 80, and 90. This rule set shows them, " + + "and is simpler as a result.", + "German also adds some interesting " + + "characteristics. For values below 1,000,000, numbers are customarily " + + "written out as a single word. And the ones digit PRECEDES the tens " + + "digit (e.g., 23 is \"dreiundzwanzig,\" not \"zwanzigunddrei\").", + "Like German, most Italian numbers are " + + "written as single words. What makes these rules complicated is the rule " + + "that says that when a word ending in a vowel and a word beginning with " + + "a vowel are combined into a compound, the vowel is dropped from the " + + "end of the first word: 180 is \"centottanta,\" not \"centoottanta.\" " + + "The complexity of this rule set is to produce this behavior.", + "Spellout rules for Swedish.", + "Spellout rules for Dutch. Notice that in Dutch, as in German," + + "the ones digit precedes the tens digit.", + "In Japanese, there really isn't any " + + "distinction between a number written out in digits and a number " + + "written out in words: the ideographic characters are both digits " + + "and words. This rule set provides two variants: %traditional " + + "uses the traditional CJK numerals (which are also used in China " + + "and Korea). %financial uses alternate ideographs for many numbers " + + "that are harder to alter than the traditional numerals (one could " + + "fairly easily change a one to " + + "a three just by adding two strokes, for example). This is also done in " + + "the other countries using Chinese ideographs, but different ideographs " + + "are used in those places.", + "Again in Greek we have to supply the words " + + "for the multiples of 100 because they can't be derived algorithmically. " + + "Also, the tens dgit changes form when followed by a ones digit: an " + + "accent mark disappears from the tens digit and moves to the ones digit. " + + "Therefore, instead of using the [] notation, we actually have to use " + + "two separate rules for each multiple of 10 to show the two forms of " + + "the word.", + "Spellout rules for Russian.", + "Spellout rules for Hebrew. Hebrew actually has inflected forms for " + + "most of the lower-order numbers. The masculine forms are shown " + + "here.", + "This rule set adds an English ordinal abbreviation to the end of a " + + "number. For example, 2 is formatted as \"2nd\". Parsing doesn't work with " + + "this rule set. To parse, use DecimalFormat on the numeral.", + "This is a simple message-formatting example. Normally one would " + + "use ChoiceFormat and MessageFormat to do something this simple, " + + "but this shows it could be done with RuleBasedNumberFormat too. " + + "A message-formatting example that might work better with " + + "RuleBasedNumberFormat appears later.", + "The next few examples demonstrate fraction handling. " + + "This example formats a number in one of the two styles often used " + + "on checks. %dollars-and-hundredths formats cents as hundredths of " + + "a dollar (23.40 comes out as \"twenty-three and 40/100 dollars\"). " + + "%dollars-and-cents formats in dollars and cents (23.40 comes out as " + + "\"twenty-three dollars and forty cents\")", + "This rule set shows the fractional part of the number as a fraction " + + "with a power of 10 as the denominator. Some languages don't spell " + + "out the fractional part of a number as \"point one two three,\" but " + + "always render it as a fraction. If we still want to treat the fractional " + + "part of the number as a decimal, then the fraction's denominator " + + "is always a power of 10. This example does that: 23.125 is formatted " + + "as \"twenty-three and one hundred twenty-five thousandths\" (as opposed " + + "to \"twenty-three point one two five\" or \"twenty-three and one eighth\").", + "Number with closest fraction. This example formats a value using " + + "numerals, but shows the fractional part as a ratio (fraction) rather " + + "than a decimal. The fraction always has a denominator between 2 and 10.", + "American stock-price formatting. Non-integral stock prices are still " + + "generally shown in eighths or sixteenths of dollars instead of dollars " + + "and cents. This example formats stock prices in this way if possible, " + + "and in dollars and cents if not.", + "The next few examples demonstrate using a RuleBasedNumberFormat to " + + "change the units a value is denominated in depending on its magnitude. " + + "The example shows large numbers the way they often appear is nwespapers: " + + "1,200,000 is formatted as \"1.2 million\".", + "This example takes a number of meters and formats it in whatever unit " + + "will produce a number with from one to three digits before the decimal " + + "point. For example, 230,000 is formatted as \"230 km\".", + "A more complicated message-formatting example. Here, in addition to " + + "handling the singular and plural versions of the word, the value is " + + "denominated in bytes, kilobytes, or megabytes depending on its magnitude. " + + "Also notice that it correctly treats a kilobyte as 1,024 bytes (not 1,000), " + + "and a megabyte as 1,024 kilobytes (not 1,000).", + "This example formats a number in dozens and gross. This is intended to " + + "demonstrate how this rule set can be used to format numbers in systems " + + "other than base 10. The \"/12\" after the rules' base values controls this. " + + "Also notice that the base doesn't have to be consistent throughout the " + + "whole rule set: we go back to base 10 for values over 1,000.", + "The next few examples show how a single value can be divided up into major " + + "and minor units that don't relate to each other by a factor of 10. " + + "This example formats a number of seconds in sexagesimal notation " + + "(i.e., hours, minutes, and seconds). %with-words formats it with " + + "words (3740 is \"1 hour, 2 minutes, 20 seconds\") and %in-numerals " + + "formats it entirely in numerals (3740 is \"1:02:20\").", + "This example formats a number of hours in sexagesimal notation (i.e., " + + "hours, minutes, and seconds). %with-words formats the value using " + + "words for the units, and %in-numerals formats the value using only " + + "numerals.", + "This rule set formats a number of pounds as pounds, shillings, and " + + "pence in the old English system of currency.", + "These examples show how RuleBasedNumberFormat can be used to format " + + "numbers using non-positional numeration systems. " + + "This example formats numbers in Arabic numerals. " + + "Normally, you'd do this with DecimalFormat, but this shows that " + + "RuleBasedNumberFormat can handle it too.", + "This example follows the same pattern as the Arabic-numerals " + + "example, but uses words for the various digits (e.g., 123 comes " + + "out as \"one two three\").", + "This example formats numbers using Chinese characters in the Arabic " + + "place-value method. This was used historically in China for a while.", + "Roman numerals. This example has two variants: %modern shows how large " + + "numbers are usually handled today; %historical ses the older symbols for " + + "thousands. Not all of the characters are displayable with most fonts.", + "Hebrew alphabetic numerals. Before adoption of Arabic numerals, Hebrew speakers " + + "used the letter of their alphabet as numerals. The first nine letters of " + + "the alphabet represented the values from 1 to 9, the second nine letters the " + + "multiples of 10, and the remaining letters the multiples of 100. Since they " + + "ran out of letters at 400, the remaining multiples of 100 were represented " + + "using combinations of the existing letters for the hundreds. Numbers were " + + "distinguished from words in a number of different ways: the way shown here " + + "uses a single mark after a number consisting of one letter, and a double " + + "mark between the last two letters of a number consisting of two or more " + + "letters. Two dots over a letter multiplied its value by 1,000. Also, since " + + "the letter for 10 is the first letter of God's name and the letters for 5 and 6 " + + "are letters in God's name, which wasn't supposed to be written or spoken, 15 and " + + "16 were usually written as 9 + 6 and 9 + 7 instead of 10 + 5 and 10 + 6.", + "Greek alphabetic numerals. The Greeks, before adopting the Arabic numerals, " + + "also used the letters of their alphabet as numerals. There are three now-" + + "obsolete Greek letters that are used as numerals; many fonts don't have them. " + + "Large numbers were handled many different ways; the way shown here divides " + + "large numbers into groups of four letters (factors of 10,000), and separates " + + "the groups with the capital letter mu (for myriad). Capital letters are used " + + "for values below 10,000; small letters for higher numbers (to make the capital " + + "mu stand out).", + "This is a custom (user-defined) rule set." + }; } diff --git a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/translit/AnyTransliterator.java b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/translit/AnyTransliterator.java index c6c525467b51..48d2a5f135d6 100644 --- a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/translit/AnyTransliterator.java +++ b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/translit/AnyTransliterator.java @@ -1,61 +1,61 @@ // © 2016 and later: Unicode, Inc. and others. // License & terms of use: http://www.unicode.org/copyright.html /** - ******************************************************************************* - * Copyright (C) 2001-2010, International Business Machines Corporation and * - * others. All Rights Reserved. * - ******************************************************************************* + * ****************************************************************************** Copyright (C) + * 2001-2010, International Business Machines Corporation and * others. All Rights Reserved. * + * ****************************************************************************** */ package com.ibm.icu.dev.demo.translit; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; -import java.util.TreeSet; import com.ibm.icu.lang.UScript; import com.ibm.icu.text.Replaceable; import com.ibm.icu.text.Transliterator; import com.ibm.icu.text.UTF16; import com.ibm.icu.text.UnicodeFilter; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import java.util.TreeSet; public class AnyTransliterator extends Transliterator { - + static final boolean DEBUG = false; private String targetName; private RunIterator it; private Position run; - - - public AnyTransliterator(String targetName, UnicodeFilter filter, RunIterator it){ + + public AnyTransliterator(String targetName, UnicodeFilter filter, RunIterator it) { super("Any-" + targetName, filter); this.targetName = targetName; this.it = it; run = new Position(); } - - public AnyTransliterator(String targetName, UnicodeFilter filter){ + + public AnyTransliterator(String targetName, UnicodeFilter filter) { this(targetName, filter, new ScriptRunIterator()); } - - static private Transliterator hex = Transliterator.getInstance("[^\\u0020-\\u007E] hex"); - - protected void handleTransliterate(Replaceable text, - Position offsets, boolean isIncremental) { + + private static Transliterator hex = Transliterator.getInstance("[^\\u0020-\\u007E] hex"); + + protected void handleTransliterate(Replaceable text, Position offsets, boolean isIncremental) { if (DEBUG) { - System.out.println("- handleTransliterate " + hex.transliterate(text.toString()) - + ", " + toString(offsets)); + System.out.println( + "- handleTransliterate " + + hex.transliterate(text.toString()) + + ", " + + toString(offsets)); } it.reset(text, offsets); - + while (it.next(run)) { if (targetName.equalsIgnoreCase(it.getName())) { if (DEBUG) System.out.println("Skipping identical: " + targetName); run.start = run.limit; // show we processed continue; // skip if same } - + Transliterator t; String id = it.getName() + '-' + targetName; try { @@ -71,13 +71,13 @@ protected void handleTransliterate(Replaceable text, } } // TODO catch error later!! - + if (DEBUG) { System.out.println(t.getID()); - System.out.println("input: " + hex.transliterate(text.toString()) - + ", " + toString(run)); + System.out.println( + "input: " + hex.transliterate(text.toString()) + ", " + toString(run)); } - + if (isIncremental && it.atEnd()) { t.transliterate(text, run); } else { @@ -85,10 +85,10 @@ protected void handleTransliterate(Replaceable text, } // adjust the offsets in line with the changes it.adjust(run.limit); - + if (DEBUG) { - System.out.println("output: " + hex.transliterate(text.toString()) - + ", " + toString(run)); + System.out.println( + "output: " + hex.transliterate(text.toString()) + ", " + toString(run)); } } @@ -101,38 +101,46 @@ protected void handleTransliterate(Replaceable text, System.out.println(); } } - + // should be method on Position public static String toString(Position offsets) { - return "[cs: " + offsets.contextStart - + ", s: " + offsets.start - + ", l: " + offsets.limit - + ", cl: " + offsets.contextLimit + return "[cs: " + + offsets.contextStart + + ", s: " + + offsets.start + + ", l: " + + offsets.limit + + ", cl: " + + offsets.contextLimit + "]"; } - + public interface RunIterator { public void reset(Replaceable text, Position expanse); + public void getExpanse(Position run); + public void reset(); + public boolean next(Position run); + public void getCurrent(Position run); + public String getName(); + public void adjust(int newCurrentLimit); + public boolean atEnd(); } - + /** * Returns a series of ranges corresponding to scripts. They will be of the form: - * ccccSScSSccccTTcTcccc - where c is common, S is the first script and T is the second - *| | - first run - * | | - second run - * That is, the runs will overlap. The reason for this is so that a transliterator can - * consider common characters both before and after the scripts. - * The only time that contextStart != start is for the first run - * (the context is the start context of the entire expanse) - * The only time that contextLimit != limit is for the last run - * (the context is the end context of the entire expanse) + * ccccSScSSccccTTcTcccc - where c is common, S is the first script and T is the second | | - + * first run | | - second run That is, the runs will overlap. The reason for this is so that a + * transliterator can consider common characters both before and after the scripts. The only + * time that contextStart != start is for the first run (the context is the start context of the + * entire expanse) The only time that contextLimit != limit is for the last run (the context is + * the end context of the entire expanse) */ public static class ScriptRunIterator implements RunIterator { private Replaceable text; @@ -140,35 +148,40 @@ public static class ScriptRunIterator implements RunIterator { private Position current = new Position(); private int script; private boolean done = true; - public void reset(Replaceable repText, Position expansePos) { set(this.expanse, expansePos); this.text = repText; reset(); } - + public void reset() { done = false; - //this.expanse = expanse; + // this.expanse = expanse; script = UScript.INVALID_CODE; // set up first range to be empty, at beginning current.contextStart = expanse.contextStart; - current.start = current.limit = current.contextLimit = expanse.start; + current.start = current.limit = current.contextLimit = expanse.start; } - + public boolean next(Position run) { if (done) return false; if (DEBUG) { - System.out.println("+cs: " + current.contextStart - + ", s: " + current.start - + ", l: " + current.limit - + ", cl: " + current.contextLimit); + System.out.println( + "+cs: " + + current.contextStart + + ", s: " + + current.start + + ", l: " + + current.limit + + ", cl: " + + current.contextLimit); } // reset start context run to the last end current.start = current.limit; - - // Phase 1. Backup the START value through COMMON until we get to expanse.start or a real script. + + // Phase 1. Backup the START value through COMMON until we get to expanse.start or a + // real script. int i, cp; int limit = expanse.start; for (i = current.start; i > limit; i -= UTF16.getCharCount(cp)) { @@ -178,11 +191,12 @@ public boolean next(Position run) { } current.start = i; current.contextStart = (i == limit) ? expanse.contextStart : i; // extend at start - - // PHASE 2. Move up the LIMIT value through COMMON or single script until we get to expanse.limit + + // PHASE 2. Move up the LIMIT value through COMMON or single script until we get to + // expanse.limit int lastScript = UScript.COMMON; - //int veryLastScript = UScript.COMMON; - limit = expanse.limit; + // int veryLastScript = UScript.COMMON; + limit = expanse.limit; for (i = current.limit; i < limit; i += UTF16.getCharCount(cp)) { cp = text.char32At(i); int scrpt = UScript.getScript(cp); @@ -199,18 +213,23 @@ public boolean next(Position run) { current.contextLimit = (i == limit) ? expanse.contextLimit : i; // extend at end done = (i == limit); script = lastScript; - + if (DEBUG) { - System.out.println("-cs: " + current.contextStart - + ", s: " + current.start - + ", l: " + current.limit - + ", cl: " + current.contextLimit); + System.out.println( + "-cs: " + + current.contextStart + + ", s: " + + current.start + + ", l: " + + current.limit + + ", cl: " + + current.contextLimit); } - + set(run, current); return true; } - + // SHOULD BE METHOD ON POSITION public static void set(Position run, Position current) { run.contextStart = current.contextStart; @@ -218,23 +237,23 @@ public static void set(Position run, Position current) { run.limit = current.limit; run.contextLimit = current.contextLimit; } - + public boolean atEnd() { return current.limit == expanse.limit; } - + public void getCurrent(Position run) { set(run, current); } - + public void getExpanse(Position run) { set(run, expanse); } - + public String getName() { return UScript.getName(script); } - + public void adjust(int newCurrentLimit) { if (expanse == null) { throw new IllegalArgumentException("Must reset() before calling"); @@ -245,35 +264,43 @@ public void adjust(int newCurrentLimit) { expanse.limit += delta; expanse.contextLimit += delta; } - + // register Any-Script for every script. - + private static Set scriptList = new HashSet(); - + public static void registerAnyToScript() { synchronized (scriptList) { Enumeration sources = Transliterator.getAvailableSources(); - while(sources.hasMoreElements()) { + while (sources.hasMoreElements()) { String source = (String) sources.nextElement(); if (source.equals("Any")) continue; // to keep from looping - + Enumeration targets = Transliterator.getAvailableTargets(source); - while(targets.hasMoreElements()) { + while (targets.hasMoreElements()) { String target = (String) targets.nextElement(); - if (UScript.getCode(target) == null) continue; // SKIP unless we have a script (or locale) + if (UScript.getCode(target) == null) + continue; // SKIP unless we have a script (or locale) if (scriptList.contains(target)) continue; // already encountered scriptList.add(target); // otherwise add for later testing - - Set variantSet = add(new TreeSet(), Transliterator.getAvailableVariants(source, target)); + + Set variantSet = + add( + new TreeSet(), + Transliterator.getAvailableVariants(source, target)); if (variantSet.size() < 2) { AnyTransliterator at = new AnyTransliterator(target, null); DummyFactory.add(at.getID(), at); } else { Iterator variants = variantSet.iterator(); - while(variants.hasNext()) { + while (variants.hasNext()) { String variant = (String) variants.next(); - AnyTransliterator at = new AnyTransliterator( - (variant.length() > 0) ? target + "/" + variant : target, null); + AnyTransliterator at = + new AnyTransliterator( + (variant.length() > 0) + ? target + "/" + variant + : target, + null); DummyFactory.add(at.getID(), at); } } @@ -281,7 +308,7 @@ public static void registerAnyToScript() { } } } - + static class DummyFactory implements Transliterator.Factory { static DummyFactory singleton = new DummyFactory(); static HashMap m = new HashMap(); @@ -292,19 +319,18 @@ static void add(String ID, Transliterator t) { System.out.println("Registering: " + ID + ", " + t.toRules(true)); Transliterator.registerFactory(ID, singleton); } + public Transliterator getInstance(String ID) { return (Transliterator) m.get(ID); } } - + // Nice little Utility for converting Enumeration to collection static Set add(Set s, Enumeration enumeration) { - while(enumeration.hasMoreElements()) { + while (enumeration.hasMoreElements()) { s.add(enumeration.nextElement()); } return s; } - - } } diff --git a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/translit/CaseIterator.java b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/translit/CaseIterator.java index b9a6cd1254df..4a037567a3f0 100644 --- a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/translit/CaseIterator.java +++ b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/translit/CaseIterator.java @@ -1,13 +1,16 @@ // © 2016 and later: Unicode, Inc. and others. // License & terms of use: http://www.unicode.org/copyright.html /** -******************************************************************************* -* Copyright (C) 1996-2010, International Business Machines Corporation and * -* others. All Rights Reserved. * -******************************************************************************* -*/ - + * ****************************************************************************** Copyright (C) + * 1996-2010, International Business Machines Corporation and * others. All Rights Reserved. * + * ****************************************************************************** + */ package com.ibm.icu.dev.demo.translit; + +import com.ibm.icu.lang.UCharacter; +import com.ibm.icu.text.Transliterator; +import com.ibm.icu.text.UTF16; +import com.ibm.icu.text.UnicodeSet; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -15,208 +18,674 @@ import java.util.Set; import java.util.TreeSet; -import com.ibm.icu.lang.UCharacter; -import com.ibm.icu.text.Transliterator; -import com.ibm.icu.text.UTF16; -import com.ibm.icu.text.UnicodeSet; - -/** - * Incrementally returns the set of all strings that case-fold to the same value. - */ +/** Incrementally returns the set of all strings that case-fold to the same value. */ public class CaseIterator { - + // testing stuff static Transliterator toName = Transliterator.getInstance("[:^ascii:] Any-Name"); static Transliterator toHex = Transliterator.getInstance("[:^ascii:] Any-Hex"); static Transliterator toHex2 = Transliterator.getInstance("[[^\u0021-\u007F]-[,]] Any-Hex"); - + // global tables (could be precompiled) private static Map fromCaseFold = new HashMap(); private static Map toCaseFold = new HashMap(); private static int maxLength = 0; - - // This exception list is generated on the console by turning on the GENERATED flag, + + // This exception list is generated on the console by turning on the GENERATED flag, // which MUST be false for normal operation. // Once the list is generated, it is pasted in here. - // A bit of a cludge, but this bootstrapping is the easiest way + // A bit of a cludge, but this bootstrapping is the easiest way // to get around certain complications in the data. - + private static final boolean GENERATE = false; private static final boolean DUMP = false; - + private static String[][] exceptionList = { // a\N{MODIFIER LETTER RIGHT HALF RING} - {"a\u02BE","A\u02BE","a\u02BE",}, + { + "a\u02BE", "A\u02BE", "a\u02BE", + }, // ff - {"ff","FF","Ff","fF","ff",}, + { + "ff", "FF", "Ff", "fF", "ff", + }, // ffi - {"ffi","FFI","FFi","FfI","Ffi","F\uFB01","fFI","fFi","ffI","ffi","f\uFB01","\uFB00I","\uFB00i",}, + { + "ffi", "FFI", "FFi", "FfI", "Ffi", "F\uFB01", "fFI", "fFi", "ffI", "ffi", "f\uFB01", + "\uFB00I", "\uFB00i", + }, // ffl - {"ffl","FFL","FFl","FfL","Ffl","F\uFB02","fFL","fFl","ffL","ffl","f\uFB02","\uFB00L","\uFB00l",}, + { + "ffl", "FFL", "FFl", "FfL", "Ffl", "F\uFB02", "fFL", "fFl", "ffL", "ffl", "f\uFB02", + "\uFB00L", "\uFB00l", + }, // fi - {"fi","FI","Fi","fI","fi",}, + { + "fi", "FI", "Fi", "fI", "fi", + }, // fl - {"fl","FL","Fl","fL","fl",}, + { + "fl", "FL", "Fl", "fL", "fl", + }, // h\N{COMBINING MACRON BELOW} - {"h\u0331","H\u0331","h\u0331",}, + { + "h\u0331", "H\u0331", "h\u0331", + }, // i\N{COMBINING DOT ABOVE} - {"i\u0307","I\u0307","i\u0307",}, + { + "i\u0307", "I\u0307", "i\u0307", + }, // j\N{COMBINING CARON} - {"j\u030C","J\u030C","j\u030C",}, + { + "j\u030C", "J\u030C", "j\u030C", + }, // ss - {"ss","SS","Ss","S\u017F","sS","ss","s\u017F","\u017FS","\u017Fs","\u017F\u017F",}, + { + "ss", + "SS", + "Ss", + "S\u017F", + "sS", + "ss", + "s\u017F", + "\u017FS", + "\u017Fs", + "\u017F\u017F", + }, // st - {"st","ST","St","sT","st","\u017FT","\u017Ft",}, + { + "st", "ST", "St", "sT", "st", "\u017FT", "\u017Ft", + }, // t\N{COMBINING DIAERESIS} - {"t\u0308","T\u0308","t\u0308",}, + { + "t\u0308", "T\u0308", "t\u0308", + }, // w\N{COMBINING RING ABOVE} - {"w\u030A","W\u030A","w\u030A",}, + { + "w\u030A", "W\u030A", "w\u030A", + }, // y\N{COMBINING RING ABOVE} - {"y\u030A","Y\u030A","y\u030A",}, + { + "y\u030A", "Y\u030A", "y\u030A", + }, // \N{MODIFIER LETTER APOSTROPHE}n - {"\u02BCn","\u02BCN","\u02BCn",}, + { + "\u02BCn", "\u02BCN", "\u02BCn", + }, // \N{GREEK SMALL LETTER ALPHA WITH TONOS}\N{GREEK SMALL LETTER IOTA} - {"\u03AC\u03B9","\u0386\u0345","\u0386\u0399","\u0386\u03B9","\u0386\u1FBE","\u03AC\u0345","\u03AC\u0399","\u03AC\u03B9","\u03AC\u1FBE",}, + { + "\u03AC\u03B9", + "\u0386\u0345", + "\u0386\u0399", + "\u0386\u03B9", + "\u0386\u1FBE", + "\u03AC\u0345", + "\u03AC\u0399", + "\u03AC\u03B9", + "\u03AC\u1FBE", + }, // \N{GREEK SMALL LETTER ETA WITH TONOS}\N{GREEK SMALL LETTER IOTA} - {"\u03AE\u03B9","\u0389\u0345","\u0389\u0399","\u0389\u03B9","\u0389\u1FBE","\u03AE\u0345","\u03AE\u0399","\u03AE\u03B9","\u03AE\u1FBE",}, + { + "\u03AE\u03B9", + "\u0389\u0345", + "\u0389\u0399", + "\u0389\u03B9", + "\u0389\u1FBE", + "\u03AE\u0345", + "\u03AE\u0399", + "\u03AE\u03B9", + "\u03AE\u1FBE", + }, // \N{GREEK SMALL LETTER ALPHA}\N{COMBINING GREEK PERISPOMENI} - {"\u03B1\u0342","\u0391\u0342","\u03B1\u0342",}, + { + "\u03B1\u0342", "\u0391\u0342", "\u03B1\u0342", + }, // \N{GREEK SMALL LETTER ALPHA}\N{COMBINING GREEK PERISPOMENI}\N{GREEK SMALL LETTER IOTA} - {"\u03B1\u0342\u03B9","\u0391\u0342\u0345","\u0391\u0342\u0399","\u0391\u0342\u03B9","\u0391\u0342\u1FBE", - "\u03B1\u0342\u0345","\u03B1\u0342\u0399","\u03B1\u0342\u03B9","\u03B1\u0342\u1FBE","\u1FB6\u0345", - "\u1FB6\u0399","\u1FB6\u03B9","\u1FB6\u1FBE",}, + { + "\u03B1\u0342\u03B9", + "\u0391\u0342\u0345", + "\u0391\u0342\u0399", + "\u0391\u0342\u03B9", + "\u0391\u0342\u1FBE", + "\u03B1\u0342\u0345", + "\u03B1\u0342\u0399", + "\u03B1\u0342\u03B9", + "\u03B1\u0342\u1FBE", + "\u1FB6\u0345", + "\u1FB6\u0399", + "\u1FB6\u03B9", + "\u1FB6\u1FBE", + }, // \N{GREEK SMALL LETTER ALPHA}\N{GREEK SMALL LETTER IOTA} - {"\u03B1\u03B9","\u0391\u0345","\u0391\u0399","\u0391\u03B9","\u0391\u1FBE","\u03B1\u0345","\u03B1\u0399","\u03B1\u03B9","\u03B1\u1FBE",}, + { + "\u03B1\u03B9", + "\u0391\u0345", + "\u0391\u0399", + "\u0391\u03B9", + "\u0391\u1FBE", + "\u03B1\u0345", + "\u03B1\u0399", + "\u03B1\u03B9", + "\u03B1\u1FBE", + }, // \N{GREEK SMALL LETTER ETA}\N{COMBINING GREEK PERISPOMENI} - {"\u03B7\u0342","\u0397\u0342","\u03B7\u0342",}, + { + "\u03B7\u0342", "\u0397\u0342", "\u03B7\u0342", + }, // \N{GREEK SMALL LETTER ETA}\N{COMBINING GREEK PERISPOMENI}\N{GREEK SMALL LETTER IOTA} - {"\u03B7\u0342\u03B9","\u0397\u0342\u0345","\u0397\u0342\u0399","\u0397\u0342\u03B9","\u0397\u0342\u1FBE", - "\u03B7\u0342\u0345","\u03B7\u0342\u0399","\u03B7\u0342\u03B9","\u03B7\u0342\u1FBE","\u1FC6\u0345","\u1FC6\u0399", - "\u1FC6\u03B9","\u1FC6\u1FBE",}, + { + "\u03B7\u0342\u03B9", + "\u0397\u0342\u0345", + "\u0397\u0342\u0399", + "\u0397\u0342\u03B9", + "\u0397\u0342\u1FBE", + "\u03B7\u0342\u0345", + "\u03B7\u0342\u0399", + "\u03B7\u0342\u03B9", + "\u03B7\u0342\u1FBE", + "\u1FC6\u0345", + "\u1FC6\u0399", + "\u1FC6\u03B9", + "\u1FC6\u1FBE", + }, // \N{GREEK SMALL LETTER ETA}\N{GREEK SMALL LETTER IOTA} - {"\u03B7\u03B9","\u0397\u0345","\u0397\u0399","\u0397\u03B9","\u0397\u1FBE","\u03B7\u0345","\u03B7\u0399","\u03B7\u03B9","\u03B7\u1FBE",}, + { + "\u03B7\u03B9", + "\u0397\u0345", + "\u0397\u0399", + "\u0397\u03B9", + "\u0397\u1FBE", + "\u03B7\u0345", + "\u03B7\u0399", + "\u03B7\u03B9", + "\u03B7\u1FBE", + }, // \N{GREEK SMALL LETTER IOTA}\N{COMBINING DIAERESIS}\N{COMBINING GRAVE ACCENT} - {"\u03B9\u0308\u0300","\u0345\u0308\u0300","\u0399\u0308\u0300","\u03B9\u0308\u0300","\u1FBE\u0308\u0300",}, + { + "\u03B9\u0308\u0300", + "\u0345\u0308\u0300", + "\u0399\u0308\u0300", + "\u03B9\u0308\u0300", + "\u1FBE\u0308\u0300", + }, // \N{GREEK SMALL LETTER IOTA}\N{COMBINING DIAERESIS}\N{COMBINING ACUTE ACCENT} - {"\u03B9\u0308\u0301","\u0345\u0308\u0301","\u0399\u0308\u0301","\u03B9\u0308\u0301","\u1FBE\u0308\u0301",}, + { + "\u03B9\u0308\u0301", + "\u0345\u0308\u0301", + "\u0399\u0308\u0301", + "\u03B9\u0308\u0301", + "\u1FBE\u0308\u0301", + }, // \N{GREEK SMALL LETTER IOTA}\N{COMBINING DIAERESIS}\N{COMBINING GREEK PERISPOMENI} - {"\u03B9\u0308\u0342","\u0345\u0308\u0342","\u0399\u0308\u0342","\u03B9\u0308\u0342","\u1FBE\u0308\u0342",}, + { + "\u03B9\u0308\u0342", + "\u0345\u0308\u0342", + "\u0399\u0308\u0342", + "\u03B9\u0308\u0342", + "\u1FBE\u0308\u0342", + }, // \N{GREEK SMALL LETTER IOTA}\N{COMBINING GREEK PERISPOMENI} - {"\u03B9\u0342","\u0345\u0342","\u0399\u0342","\u03B9\u0342","\u1FBE\u0342",}, + { + "\u03B9\u0342", "\u0345\u0342", "\u0399\u0342", "\u03B9\u0342", "\u1FBE\u0342", + }, // \N{GREEK SMALL LETTER RHO}\N{COMBINING COMMA ABOVE} - {"\u03C1\u0313","\u03A1\u0313","\u03C1\u0313","\u03F1\u0313",}, + { + "\u03C1\u0313", "\u03A1\u0313", "\u03C1\u0313", "\u03F1\u0313", + }, // \N{GREEK SMALL LETTER UPSILON}\N{COMBINING DIAERESIS}\N{COMBINING GRAVE ACCENT} - {"\u03C5\u0308\u0300","\u03A5\u0308\u0300","\u03C5\u0308\u0300",}, + { + "\u03C5\u0308\u0300", "\u03A5\u0308\u0300", "\u03C5\u0308\u0300", + }, // \N{GREEK SMALL LETTER UPSILON}\N{COMBINING DIAERESIS}\N{COMBINING ACUTE ACCENT} - {"\u03C5\u0308\u0301","\u03A5\u0308\u0301","\u03C5\u0308\u0301",}, + { + "\u03C5\u0308\u0301", "\u03A5\u0308\u0301", "\u03C5\u0308\u0301", + }, // \N{GREEK SMALL LETTER UPSILON}\N{COMBINING DIAERESIS}\N{COMBINING GREEK PERISPOMENI} - {"\u03C5\u0308\u0342","\u03A5\u0308\u0342","\u03C5\u0308\u0342",}, + { + "\u03C5\u0308\u0342", "\u03A5\u0308\u0342", "\u03C5\u0308\u0342", + }, // \N{GREEK SMALL LETTER UPSILON}\N{COMBINING COMMA ABOVE} - {"\u03C5\u0313","\u03A5\u0313","\u03C5\u0313",}, + { + "\u03C5\u0313", "\u03A5\u0313", "\u03C5\u0313", + }, // \N{GREEK SMALL LETTER UPSILON}\N{COMBINING COMMA ABOVE}\N{COMBINING GRAVE ACCENT} - {"\u03C5\u0313\u0300","\u03A5\u0313\u0300","\u03C5\u0313\u0300","\u1F50\u0300",}, + { + "\u03C5\u0313\u0300", "\u03A5\u0313\u0300", "\u03C5\u0313\u0300", "\u1F50\u0300", + }, // \N{GREEK SMALL LETTER UPSILON}\N{COMBINING COMMA ABOVE}\N{COMBINING ACUTE ACCENT} - {"\u03C5\u0313\u0301","\u03A5\u0313\u0301","\u03C5\u0313\u0301","\u1F50\u0301",}, + { + "\u03C5\u0313\u0301", "\u03A5\u0313\u0301", "\u03C5\u0313\u0301", "\u1F50\u0301", + }, // \N{GREEK SMALL LETTER UPSILON}\N{COMBINING COMMA ABOVE}\N{COMBINING GREEK PERISPOMENI} - {"\u03C5\u0313\u0342","\u03A5\u0313\u0342","\u03C5\u0313\u0342","\u1F50\u0342",}, + { + "\u03C5\u0313\u0342", "\u03A5\u0313\u0342", "\u03C5\u0313\u0342", "\u1F50\u0342", + }, // \N{GREEK SMALL LETTER UPSILON}\N{COMBINING GREEK PERISPOMENI} - {"\u03C5\u0342","\u03A5\u0342","\u03C5\u0342",}, + { + "\u03C5\u0342", "\u03A5\u0342", "\u03C5\u0342", + }, // \N{GREEK SMALL LETTER OMEGA}\N{COMBINING GREEK PERISPOMENI} - {"\u03C9\u0342","\u03A9\u0342","\u03C9\u0342","\u2126\u0342",}, + { + "\u03C9\u0342", "\u03A9\u0342", "\u03C9\u0342", "\u2126\u0342", + }, // \N{GREEK SMALL LETTER OMEGA}\N{COMBINING GREEK PERISPOMENI}\N{GREEK SMALL LETTER IOTA} - {"\u03C9\u0342\u03B9","\u03A9\u0342\u0345","\u03A9\u0342\u0399","\u03A9\u0342\u03B9","\u03A9\u0342\u1FBE","\u03C9\u0342\u0345","\u03C9\u0342\u0399","\u03C9\u0342\u03B9","\u03C9\u0342\u1FBE","\u1FF6\u0345", - "\u1FF6\u0399","\u1FF6\u03B9","\u1FF6\u1FBE","\u2126\u0342\u0345","\u2126\u0342\u0399","\u2126\u0342\u03B9","\u2126\u0342\u1FBE",}, + { + "\u03C9\u0342\u03B9", + "\u03A9\u0342\u0345", + "\u03A9\u0342\u0399", + "\u03A9\u0342\u03B9", + "\u03A9\u0342\u1FBE", + "\u03C9\u0342\u0345", + "\u03C9\u0342\u0399", + "\u03C9\u0342\u03B9", + "\u03C9\u0342\u1FBE", + "\u1FF6\u0345", + "\u1FF6\u0399", + "\u1FF6\u03B9", + "\u1FF6\u1FBE", + "\u2126\u0342\u0345", + "\u2126\u0342\u0399", + "\u2126\u0342\u03B9", + "\u2126\u0342\u1FBE", + }, // \N{GREEK SMALL LETTER OMEGA}\N{GREEK SMALL LETTER IOTA} - {"\u03C9\u03B9","\u03A9\u0345","\u03A9\u0399","\u03A9\u03B9","\u03A9\u1FBE","\u03C9\u0345","\u03C9\u0399","\u03C9\u03B9","\u03C9\u1FBE","\u2126\u0345","\u2126\u0399","\u2126\u03B9","\u2126\u1FBE",}, + { + "\u03C9\u03B9", + "\u03A9\u0345", + "\u03A9\u0399", + "\u03A9\u03B9", + "\u03A9\u1FBE", + "\u03C9\u0345", + "\u03C9\u0399", + "\u03C9\u03B9", + "\u03C9\u1FBE", + "\u2126\u0345", + "\u2126\u0399", + "\u2126\u03B9", + "\u2126\u1FBE", + }, // \N{GREEK SMALL LETTER OMEGA WITH TONOS}\N{GREEK SMALL LETTER IOTA} - {"\u03CE\u03B9","\u038F\u0345","\u038F\u0399","\u038F\u03B9","\u038F\u1FBE","\u03CE\u0345","\u03CE\u0399","\u03CE\u03B9","\u03CE\u1FBE",}, + { + "\u03CE\u03B9", + "\u038F\u0345", + "\u038F\u0399", + "\u038F\u03B9", + "\u038F\u1FBE", + "\u03CE\u0345", + "\u03CE\u0399", + "\u03CE\u03B9", + "\u03CE\u1FBE", + }, // \N{ARMENIAN SMALL LETTER ECH}\N{ARMENIAN SMALL LETTER YIWN} - {"\u0565\u0582","\u0535\u0552","\u0535\u0582","\u0565\u0552","\u0565\u0582",}, + { + "\u0565\u0582", "\u0535\u0552", "\u0535\u0582", "\u0565\u0552", "\u0565\u0582", + }, // \N{ARMENIAN SMALL LETTER MEN}\N{ARMENIAN SMALL LETTER ECH} - {"\u0574\u0565","\u0544\u0535","\u0544\u0565","\u0574\u0535","\u0574\u0565",}, + { + "\u0574\u0565", "\u0544\u0535", "\u0544\u0565", "\u0574\u0535", "\u0574\u0565", + }, // \N{ARMENIAN SMALL LETTER MEN}\N{ARMENIAN SMALL LETTER INI} - {"\u0574\u056B","\u0544\u053B","\u0544\u056B","\u0574\u053B","\u0574\u056B",}, + { + "\u0574\u056B", "\u0544\u053B", "\u0544\u056B", "\u0574\u053B", "\u0574\u056B", + }, // \N{ARMENIAN SMALL LETTER MEN}\N{ARMENIAN SMALL LETTER XEH} - {"\u0574\u056D","\u0544\u053D","\u0544\u056D","\u0574\u053D","\u0574\u056D",}, + { + "\u0574\u056D", "\u0544\u053D", "\u0544\u056D", "\u0574\u053D", "\u0574\u056D", + }, // \N{ARMENIAN SMALL LETTER MEN}\N{ARMENIAN SMALL LETTER NOW} - {"\u0574\u0576","\u0544\u0546","\u0544\u0576","\u0574\u0546","\u0574\u0576",}, + { + "\u0574\u0576", "\u0544\u0546", "\u0544\u0576", "\u0574\u0546", "\u0574\u0576", + }, // \N{ARMENIAN SMALL LETTER VEW}\N{ARMENIAN SMALL LETTER NOW} - {"\u057E\u0576","\u054E\u0546","\u054E\u0576","\u057E\u0546","\u057E\u0576",}, + { + "\u057E\u0576", "\u054E\u0546", "\u054E\u0576", "\u057E\u0546", "\u057E\u0576", + }, // \N{GREEK SMALL LETTER ALPHA WITH PSILI}\N{GREEK SMALL LETTER IOTA} - {"\u1F00\u03B9","\u1F00\u0345","\u1F00\u0399","\u1F00\u03B9","\u1F00\u1FBE","\u1F08\u0345","\u1F08\u0399","\u1F08\u03B9","\u1F08\u1FBE",}, + { + "\u1F00\u03B9", + "\u1F00\u0345", + "\u1F00\u0399", + "\u1F00\u03B9", + "\u1F00\u1FBE", + "\u1F08\u0345", + "\u1F08\u0399", + "\u1F08\u03B9", + "\u1F08\u1FBE", + }, // \N{GREEK SMALL LETTER ALPHA WITH DASIA}\N{GREEK SMALL LETTER IOTA} - {"\u1F01\u03B9","\u1F01\u0345","\u1F01\u0399","\u1F01\u03B9","\u1F01\u1FBE","\u1F09\u0345","\u1F09\u0399","\u1F09\u03B9","\u1F09\u1FBE",}, + { + "\u1F01\u03B9", + "\u1F01\u0345", + "\u1F01\u0399", + "\u1F01\u03B9", + "\u1F01\u1FBE", + "\u1F09\u0345", + "\u1F09\u0399", + "\u1F09\u03B9", + "\u1F09\u1FBE", + }, // \N{GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA}\N{GREEK SMALL LETTER IOTA} - {"\u1F02\u03B9","\u1F02\u0345","\u1F02\u0399","\u1F02\u03B9","\u1F02\u1FBE","\u1F0A\u0345","\u1F0A\u0399","\u1F0A\u03B9","\u1F0A\u1FBE",}, + { + "\u1F02\u03B9", + "\u1F02\u0345", + "\u1F02\u0399", + "\u1F02\u03B9", + "\u1F02\u1FBE", + "\u1F0A\u0345", + "\u1F0A\u0399", + "\u1F0A\u03B9", + "\u1F0A\u1FBE", + }, // \N{GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA}\N{GREEK SMALL LETTER IOTA} - {"\u1F03\u03B9","\u1F03\u0345","\u1F03\u0399","\u1F03\u03B9","\u1F03\u1FBE","\u1F0B\u0345","\u1F0B\u0399","\u1F0B\u03B9","\u1F0B\u1FBE",}, + { + "\u1F03\u03B9", + "\u1F03\u0345", + "\u1F03\u0399", + "\u1F03\u03B9", + "\u1F03\u1FBE", + "\u1F0B\u0345", + "\u1F0B\u0399", + "\u1F0B\u03B9", + "\u1F0B\u1FBE", + }, // \N{GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA}\N{GREEK SMALL LETTER IOTA} - {"\u1F04\u03B9","\u1F04\u0345","\u1F04\u0399","\u1F04\u03B9","\u1F04\u1FBE","\u1F0C\u0345","\u1F0C\u0399","\u1F0C\u03B9","\u1F0C\u1FBE",}, + { + "\u1F04\u03B9", + "\u1F04\u0345", + "\u1F04\u0399", + "\u1F04\u03B9", + "\u1F04\u1FBE", + "\u1F0C\u0345", + "\u1F0C\u0399", + "\u1F0C\u03B9", + "\u1F0C\u1FBE", + }, // \N{GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA}\N{GREEK SMALL LETTER IOTA} - {"\u1F05\u03B9","\u1F05\u0345","\u1F05\u0399","\u1F05\u03B9","\u1F05\u1FBE","\u1F0D\u0345","\u1F0D\u0399","\u1F0D\u03B9","\u1F0D\u1FBE",}, + { + "\u1F05\u03B9", + "\u1F05\u0345", + "\u1F05\u0399", + "\u1F05\u03B9", + "\u1F05\u1FBE", + "\u1F0D\u0345", + "\u1F0D\u0399", + "\u1F0D\u03B9", + "\u1F0D\u1FBE", + }, // \N{GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI}\N{GREEK SMALL LETTER IOTA} - {"\u1F06\u03B9","\u1F06\u0345","\u1F06\u0399","\u1F06\u03B9","\u1F06\u1FBE","\u1F0E\u0345","\u1F0E\u0399","\u1F0E\u03B9","\u1F0E\u1FBE",}, + { + "\u1F06\u03B9", + "\u1F06\u0345", + "\u1F06\u0399", + "\u1F06\u03B9", + "\u1F06\u1FBE", + "\u1F0E\u0345", + "\u1F0E\u0399", + "\u1F0E\u03B9", + "\u1F0E\u1FBE", + }, // \N{GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI}\N{GREEK SMALL LETTER IOTA} - {"\u1F07\u03B9","\u1F07\u0345","\u1F07\u0399","\u1F07\u03B9","\u1F07\u1FBE","\u1F0F\u0345","\u1F0F\u0399","\u1F0F\u03B9","\u1F0F\u1FBE",}, + { + "\u1F07\u03B9", + "\u1F07\u0345", + "\u1F07\u0399", + "\u1F07\u03B9", + "\u1F07\u1FBE", + "\u1F0F\u0345", + "\u1F0F\u0399", + "\u1F0F\u03B9", + "\u1F0F\u1FBE", + }, // \N{GREEK SMALL LETTER ETA WITH PSILI}\N{GREEK SMALL LETTER IOTA} - {"\u1F20\u03B9","\u1F20\u0345","\u1F20\u0399","\u1F20\u03B9","\u1F20\u1FBE","\u1F28\u0345","\u1F28\u0399","\u1F28\u03B9","\u1F28\u1FBE",}, + { + "\u1F20\u03B9", + "\u1F20\u0345", + "\u1F20\u0399", + "\u1F20\u03B9", + "\u1F20\u1FBE", + "\u1F28\u0345", + "\u1F28\u0399", + "\u1F28\u03B9", + "\u1F28\u1FBE", + }, // \N{GREEK SMALL LETTER ETA WITH DASIA}\N{GREEK SMALL LETTER IOTA} - {"\u1F21\u03B9","\u1F21\u0345","\u1F21\u0399","\u1F21\u03B9","\u1F21\u1FBE","\u1F29\u0345","\u1F29\u0399","\u1F29\u03B9","\u1F29\u1FBE",}, + { + "\u1F21\u03B9", + "\u1F21\u0345", + "\u1F21\u0399", + "\u1F21\u03B9", + "\u1F21\u1FBE", + "\u1F29\u0345", + "\u1F29\u0399", + "\u1F29\u03B9", + "\u1F29\u1FBE", + }, // \N{GREEK SMALL LETTER ETA WITH PSILI AND VARIA}\N{GREEK SMALL LETTER IOTA} - {"\u1F22\u03B9","\u1F22\u0345","\u1F22\u0399","\u1F22\u03B9","\u1F22\u1FBE","\u1F2A\u0345","\u1F2A\u0399","\u1F2A\u03B9","\u1F2A\u1FBE",}, + { + "\u1F22\u03B9", + "\u1F22\u0345", + "\u1F22\u0399", + "\u1F22\u03B9", + "\u1F22\u1FBE", + "\u1F2A\u0345", + "\u1F2A\u0399", + "\u1F2A\u03B9", + "\u1F2A\u1FBE", + }, // \N{GREEK SMALL LETTER ETA WITH DASIA AND VARIA}\N{GREEK SMALL LETTER IOTA} - {"\u1F23\u03B9","\u1F23\u0345","\u1F23\u0399","\u1F23\u03B9","\u1F23\u1FBE","\u1F2B\u0345","\u1F2B\u0399","\u1F2B\u03B9","\u1F2B\u1FBE",}, + { + "\u1F23\u03B9", + "\u1F23\u0345", + "\u1F23\u0399", + "\u1F23\u03B9", + "\u1F23\u1FBE", + "\u1F2B\u0345", + "\u1F2B\u0399", + "\u1F2B\u03B9", + "\u1F2B\u1FBE", + }, // \N{GREEK SMALL LETTER ETA WITH PSILI AND OXIA}\N{GREEK SMALL LETTER IOTA} - {"\u1F24\u03B9","\u1F24\u0345","\u1F24\u0399","\u1F24\u03B9","\u1F24\u1FBE","\u1F2C\u0345","\u1F2C\u0399","\u1F2C\u03B9","\u1F2C\u1FBE",}, + { + "\u1F24\u03B9", + "\u1F24\u0345", + "\u1F24\u0399", + "\u1F24\u03B9", + "\u1F24\u1FBE", + "\u1F2C\u0345", + "\u1F2C\u0399", + "\u1F2C\u03B9", + "\u1F2C\u1FBE", + }, // \N{GREEK SMALL LETTER ETA WITH DASIA AND OXIA}\N{GREEK SMALL LETTER IOTA} - {"\u1F25\u03B9","\u1F25\u0345","\u1F25\u0399","\u1F25\u03B9","\u1F25\u1FBE","\u1F2D\u0345","\u1F2D\u0399","\u1F2D\u03B9","\u1F2D\u1FBE",}, + { + "\u1F25\u03B9", + "\u1F25\u0345", + "\u1F25\u0399", + "\u1F25\u03B9", + "\u1F25\u1FBE", + "\u1F2D\u0345", + "\u1F2D\u0399", + "\u1F2D\u03B9", + "\u1F2D\u1FBE", + }, // \N{GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI}\N{GREEK SMALL LETTER IOTA} - {"\u1F26\u03B9","\u1F26\u0345","\u1F26\u0399","\u1F26\u03B9","\u1F26\u1FBE","\u1F2E\u0345","\u1F2E\u0399","\u1F2E\u03B9","\u1F2E\u1FBE",}, + { + "\u1F26\u03B9", + "\u1F26\u0345", + "\u1F26\u0399", + "\u1F26\u03B9", + "\u1F26\u1FBE", + "\u1F2E\u0345", + "\u1F2E\u0399", + "\u1F2E\u03B9", + "\u1F2E\u1FBE", + }, // \N{GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI}\N{GREEK SMALL LETTER IOTA} - {"\u1F27\u03B9","\u1F27\u0345","\u1F27\u0399","\u1F27\u03B9","\u1F27\u1FBE","\u1F2F\u0345","\u1F2F\u0399","\u1F2F\u03B9","\u1F2F\u1FBE",}, + { + "\u1F27\u03B9", + "\u1F27\u0345", + "\u1F27\u0399", + "\u1F27\u03B9", + "\u1F27\u1FBE", + "\u1F2F\u0345", + "\u1F2F\u0399", + "\u1F2F\u03B9", + "\u1F2F\u1FBE", + }, // \N{GREEK SMALL LETTER OMEGA WITH PSILI}\N{GREEK SMALL LETTER IOTA} - {"\u1F60\u03B9","\u1F60\u0345","\u1F60\u0399","\u1F60\u03B9","\u1F60\u1FBE","\u1F68\u0345","\u1F68\u0399","\u1F68\u03B9","\u1F68\u1FBE",}, + { + "\u1F60\u03B9", + "\u1F60\u0345", + "\u1F60\u0399", + "\u1F60\u03B9", + "\u1F60\u1FBE", + "\u1F68\u0345", + "\u1F68\u0399", + "\u1F68\u03B9", + "\u1F68\u1FBE", + }, // \N{GREEK SMALL LETTER OMEGA WITH DASIA}\N{GREEK SMALL LETTER IOTA} - {"\u1F61\u03B9","\u1F61\u0345","\u1F61\u0399","\u1F61\u03B9","\u1F61\u1FBE","\u1F69\u0345","\u1F69\u0399","\u1F69\u03B9","\u1F69\u1FBE",}, + { + "\u1F61\u03B9", + "\u1F61\u0345", + "\u1F61\u0399", + "\u1F61\u03B9", + "\u1F61\u1FBE", + "\u1F69\u0345", + "\u1F69\u0399", + "\u1F69\u03B9", + "\u1F69\u1FBE", + }, // \N{GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA}\N{GREEK SMALL LETTER IOTA} - {"\u1F62\u03B9","\u1F62\u0345","\u1F62\u0399","\u1F62\u03B9","\u1F62\u1FBE","\u1F6A\u0345","\u1F6A\u0399","\u1F6A\u03B9","\u1F6A\u1FBE",}, + { + "\u1F62\u03B9", + "\u1F62\u0345", + "\u1F62\u0399", + "\u1F62\u03B9", + "\u1F62\u1FBE", + "\u1F6A\u0345", + "\u1F6A\u0399", + "\u1F6A\u03B9", + "\u1F6A\u1FBE", + }, // \N{GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA}\N{GREEK SMALL LETTER IOTA} - {"\u1F63\u03B9","\u1F63\u0345","\u1F63\u0399","\u1F63\u03B9","\u1F63\u1FBE","\u1F6B\u0345","\u1F6B\u0399","\u1F6B\u03B9","\u1F6B\u1FBE",}, + { + "\u1F63\u03B9", + "\u1F63\u0345", + "\u1F63\u0399", + "\u1F63\u03B9", + "\u1F63\u1FBE", + "\u1F6B\u0345", + "\u1F6B\u0399", + "\u1F6B\u03B9", + "\u1F6B\u1FBE", + }, // \N{GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA}\N{GREEK SMALL LETTER IOTA} - {"\u1F64\u03B9","\u1F64\u0345","\u1F64\u0399","\u1F64\u03B9","\u1F64\u1FBE","\u1F6C\u0345","\u1F6C\u0399","\u1F6C\u03B9","\u1F6C\u1FBE",}, + { + "\u1F64\u03B9", + "\u1F64\u0345", + "\u1F64\u0399", + "\u1F64\u03B9", + "\u1F64\u1FBE", + "\u1F6C\u0345", + "\u1F6C\u0399", + "\u1F6C\u03B9", + "\u1F6C\u1FBE", + }, // \N{GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA}\N{GREEK SMALL LETTER IOTA} - {"\u1F65\u03B9","\u1F65\u0345","\u1F65\u0399","\u1F65\u03B9","\u1F65\u1FBE","\u1F6D\u0345","\u1F6D\u0399","\u1F6D\u03B9","\u1F6D\u1FBE",}, + { + "\u1F65\u03B9", + "\u1F65\u0345", + "\u1F65\u0399", + "\u1F65\u03B9", + "\u1F65\u1FBE", + "\u1F6D\u0345", + "\u1F6D\u0399", + "\u1F6D\u03B9", + "\u1F6D\u1FBE", + }, // \N{GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI}\N{GREEK SMALL LETTER IOTA} - {"\u1F66\u03B9","\u1F66\u0345","\u1F66\u0399","\u1F66\u03B9","\u1F66\u1FBE","\u1F6E\u0345","\u1F6E\u0399","\u1F6E\u03B9","\u1F6E\u1FBE",}, + { + "\u1F66\u03B9", + "\u1F66\u0345", + "\u1F66\u0399", + "\u1F66\u03B9", + "\u1F66\u1FBE", + "\u1F6E\u0345", + "\u1F6E\u0399", + "\u1F6E\u03B9", + "\u1F6E\u1FBE", + }, // \N{GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI}\N{GREEK SMALL LETTER IOTA} - {"\u1F67\u03B9","\u1F67\u0345","\u1F67\u0399","\u1F67\u03B9","\u1F67\u1FBE","\u1F6F\u0345","\u1F6F\u0399","\u1F6F\u03B9","\u1F6F\u1FBE",}, + { + "\u1F67\u03B9", + "\u1F67\u0345", + "\u1F67\u0399", + "\u1F67\u03B9", + "\u1F67\u1FBE", + "\u1F6F\u0345", + "\u1F6F\u0399", + "\u1F6F\u03B9", + "\u1F6F\u1FBE", + }, // \N{GREEK SMALL LETTER ALPHA WITH VARIA}\N{GREEK SMALL LETTER IOTA} - {"\u1F70\u03B9","\u1F70\u0345","\u1F70\u0399","\u1F70\u03B9","\u1F70\u1FBE","\u1FBA\u0345","\u1FBA\u0399","\u1FBA\u03B9","\u1FBA\u1FBE",}, + { + "\u1F70\u03B9", + "\u1F70\u0345", + "\u1F70\u0399", + "\u1F70\u03B9", + "\u1F70\u1FBE", + "\u1FBA\u0345", + "\u1FBA\u0399", + "\u1FBA\u03B9", + "\u1FBA\u1FBE", + }, // \N{GREEK SMALL LETTER ETA WITH VARIA}\N{GREEK SMALL LETTER IOTA} - {"\u1F74\u03B9","\u1F74\u0345","\u1F74\u0399","\u1F74\u03B9","\u1F74\u1FBE","\u1FCA\u0345","\u1FCA\u0399","\u1FCA\u03B9","\u1FCA\u1FBE",}, + { + "\u1F74\u03B9", + "\u1F74\u0345", + "\u1F74\u0399", + "\u1F74\u03B9", + "\u1F74\u1FBE", + "\u1FCA\u0345", + "\u1FCA\u0399", + "\u1FCA\u03B9", + "\u1FCA\u1FBE", + }, // \N{GREEK SMALL LETTER OMEGA WITH VARIA}\N{GREEK SMALL LETTER IOTA} - {"\u1F7C\u03B9","\u1F7C\u0345","\u1F7C\u0399","\u1F7C\u03B9","\u1F7C\u1FBE","\u1FFA\u0345","\u1FFA\u0399","\u1FFA\u03B9","\u1FFA\u1FBE",}, + { + "\u1F7C\u03B9", + "\u1F7C\u0345", + "\u1F7C\u0399", + "\u1F7C\u03B9", + "\u1F7C\u1FBE", + "\u1FFA\u0345", + "\u1FFA\u0399", + "\u1FFA\u03B9", + "\u1FFA\u1FBE", + }, }; - + // this initializes the data used to generated the case-equivalents static { - + // Gather up the exceptions in a form we can use - + if (!GENERATE) { for (int i = 0; i < exceptionList.length; ++i) { String[] exception = exceptionList[i]; Set s = new HashSet(); - // there has to be some method to do the following, but I can't find it in the collections + // there has to be some method to do the following, but I can't find it in the + // collections for (int j = 0; j < exception.length; ++j) { s.add(exception[j]); } fromCaseFold.put(exception[0], s); } } - + // walk through all the characters, and at every case fold result, // put a set of all the characters that map to that result @@ -224,15 +693,15 @@ public class CaseIterator { for (int i = 0; i <= 0x10FFFF; ++i) { int cat = UCharacter.getType(i); if (cat == Character.UNASSIGNED || cat == Character.PRIVATE_USE) continue; - + String cp = UTF16.valueOf(i); String mapped = UCharacter.foldCase(cp, defaultmapping); if (mapped.equals(cp)) continue; - + if (maxLength < mapped.length()) maxLength = mapped.length(); - + // at this point, have different case folding - + Set s = (Set) fromCaseFold.get(mapped); if (s == null) { s = new HashSet(); @@ -243,7 +712,7 @@ public class CaseIterator { toCaseFold.put(cp, mapped); toCaseFold.put(mapped, mapped); // add mapping to self } - + // Emit the final data if (DUMP) { @@ -253,7 +722,7 @@ public class CaseIterator { Iterator it = fromCaseFold.keySet().iterator(); while (it.hasNext()) { Object key = it.next(); - System.out.print(" " + toHex2.transliterate((String)key) + ": "); + System.out.print(" " + toHex2.transliterate((String) key) + ": "); Set s = (Set) fromCaseFold.get(key); Iterator it2 = s.iterator(); boolean first = true; @@ -263,7 +732,7 @@ public class CaseIterator { } else { System.out.print(", "); } - System.out.print(toHex2.transliterate((String)it2.next())); + System.out.print(toHex2.transliterate((String) it2.next())); } System.out.println(""); } @@ -273,17 +742,17 @@ public class CaseIterator { while (it.hasNext()) { String key = (String) it.next(); String value = (String) toCaseFold.get(key); - System.out.println(" " + toHex2.transliterate(key) + ": " + toHex2.transliterate(value)); - } + System.out.println( + " " + toHex2.transliterate(key) + ": " + toHex2.transliterate(value)); + } } - + // Now convert all those sets into linear arrays // We can't do this in place in Java, so make a temporary target array - + // Note: This could be transformed into a single array, with offsets into it. // Might be best choice in C. - - + Map fromCaseFold2 = new HashMap(); Iterator it = fromCaseFold.keySet().iterator(); while (it.hasNext()) { @@ -296,40 +765,40 @@ public class CaseIterator { fromCaseFold = fromCaseFold2; // We have processed everything, so the iterator will now work - // The following is normally OFF. + // The following is normally OFF. // It is here to generate (under the GENERATE flag) the static exception list. // It must be at the very end of initialization, so that the iterator is functional. // (easiest to do it that way) - + if (GENERATE) { // first get small set of items that have multiple characters - + Set multichars = new TreeSet(); it = fromCaseFold.keySet().iterator(); while (it.hasNext()) { String key = (String) it.next(); if (UTF16.countCodePoint(key) < 2) continue; multichars.add(key); - } - + } + // now we will go through each of them. - + CaseIterator ci = new CaseIterator(); it = multichars.iterator(); - + while (it.hasNext()) { String key = (String) it.next(); - + // here is a nasty complication. Take 'ffi' ligature. We // can't just close it, since we would miss the combination // that includes the 'fi' => "fi" ligature // so first do a pass through, and add substring combinations // we call this a 'partial closure' - + Set partialClosure = new TreeSet(); partialClosure.add(key); - + if (UTF16.countCodePoint(key) > 2) { Iterator multiIt2 = multichars.iterator(); while (multiIt2.hasNext()) { @@ -341,25 +810,24 @@ public class CaseIterator { // but works for the actual cased stuff, // and should work for future characters, since we won't have // more ligatures & other oddities. - pos = key.indexOf(otherKey, pos+1); + pos = key.indexOf(otherKey, pos + 1); if (pos < 0) break; int endPos = pos + otherKey.length(); // we know we have a proper substring, // so get the combinations String[] choices = (String[]) fromCaseFold.get(otherKey); for (int ii = 0; ii < choices.length; ++ii) { - String patchwork = key.substring(0, pos) - + choices[ii] - + key.substring(endPos); + String patchwork = + key.substring(0, pos) + choices[ii] + key.substring(endPos); partialClosure.add(patchwork); } } } } - + // now, for each thing in the partial closure, get its // case closure and add it to the final result. - + Set closure = new TreeSet(); // this will be the real closure Iterator partialIt = partialClosure.iterator(); while (partialIt.hasNext()) { @@ -379,65 +847,66 @@ public class CaseIterator { } */ } - + // print it out, so that it can be cut and pasted back into this document. - + Iterator it2 = closure.iterator(); System.out.println("\t// " + toName.transliterate(key)); System.out.print("\t{\"" + toHex.transliterate(key) + "\","); while (it2.hasNext()) { - String item = (String)it2.next(); + String item = (String) it2.next(); System.out.print("\"" + toHex.transliterate(item) + "\","); } System.out.println("},"); } } } - - // ============ PRIVATE CLASS DATA ============ - + + // ============ PRIVATE CLASS DATA ============ + // pieces that we will put together // is not changed during iteration private int count = 0; private String[][] variants; - + // state information, changes during iteration private boolean done = false; private int[] counts; - + // internal buffer for efficiency private StringBuffer nextBuffer = new StringBuffer(); - - // ======================== + + // ======================== /** * Reset to different source. Once reset, the iteration starts from the beginning. + * * @param source The string to get case variants for */ public void reset(String source) { - + // allocate arrays to store pieces // using length might be slightly too long, but we don't care much - + counts = new int[source.length()]; variants = new String[source.length()][]; - + // walk through the source, and break up into pieces // each piece becomes an array of equivalent values // TODO: could optimized this later to coalesce all single string pieces - + String piece = null; count = 0; for (int i = 0; i < source.length(); i += piece.length()) { - + // find *longest* matching piece String caseFold = null; - + if (GENERATE) { // do exactly one CP piece = UTF16.valueOf(source, i); caseFold = (String) toCaseFold.get(piece); - } else { + } else { int max = i + maxLength; if (max > source.length()) max = source.length(); for (int j = max; j > i; --j) { @@ -446,73 +915,69 @@ public void reset(String source) { if (caseFold != null) break; } } - + // if we fail, pick one code point if (caseFold == null) { piece = UTF16.valueOf(source, i); variants[count++] = new String[] {piece}; // single item string } else { - variants[count++] = (String[])fromCaseFold.get(caseFold); + variants[count++] = (String[]) fromCaseFold.get(caseFold); } } reset(); } - - /** - * Restart the iteration from the beginning, but with same source - */ + + /** Restart the iteration from the beginning, but with same source */ public void reset() { done = false; for (int i = 0; i < count; ++i) { counts[i] = 0; } } - + /** * Iterates through the case variants. + * * @return next case variant. Each variant will case-fold to the same value as the source will. - * When the iteration is done, null is returned. + * When the iteration is done, null is returned. */ public String next() { - + if (done) return null; int i; - + // TODO Optimize so we keep the piece before and after the current position // so we don't have so much concatenation - + // get the result, a concatenation - + nextBuffer.setLength(0); for (i = 0; i < count; ++i) { nextBuffer.append(variants[i][counts[i]]); } - + // find the next right set of pieces to concatenate - - for (i = count-1; i >= 0; --i) { + + for (i = count - 1; i >= 0; --i) { counts[i]++; if (counts[i] < variants[i].length) break; counts[i] = 0; } - + // if we go too far, bail - + if (i < 0) { done = true; } - - return nextBuffer.toString(); + + return nextBuffer.toString(); } - - - /** - * Temporary test, just to see how the stuff works. - */ - static public void main(String[] args) { + + /** Temporary test, just to see how the stuff works. */ + public static void main(String[] args) { String[] testCases = {"fiss", "h\u03a3"}; CaseIterator ci = new CaseIterator(); - + for (int i = 0; i < testCases.length; ++i) { String item = testCases[i]; System.out.println(); @@ -541,7 +1006,7 @@ static public void main(String[] args) { fold = temp; if (++count > 1) break; } - if (count==1 && fold.equals(cp)) { + if (count == 1 && fold.equals(cp)) { caseless.add(i); } } @@ -549,7 +1014,7 @@ static public void main(String[] args) { System.out.println("caseless = " + caseless.toPattern(true)); UnicodeSet not_lc = new UnicodeSet("[:^lc:]"); - + UnicodeSet a = new UnicodeSet(); a.set(not_lc); a.removeAll(caseless); diff --git a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/translit/Demo.java b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/translit/Demo.java index 3a91f5a25cec..46fa14aa4f41 100644 --- a/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/translit/Demo.java +++ b/icu4j/demos/src/main/java/com/ibm/icu/dev/demo/translit/Demo.java @@ -8,6 +8,15 @@ */ package com.ibm.icu.dev.demo.translit; +import com.ibm.icu.lang.UCharacter; +import com.ibm.icu.text.BreakIterator; +import com.ibm.icu.text.CanonicalIterator; +import com.ibm.icu.text.Normalizer; +import com.ibm.icu.text.ReplaceableString; +import com.ibm.icu.text.Transliterator; +import com.ibm.icu.text.UTF16; +import com.ibm.icu.text.UnicodeSet; +import com.ibm.icu.text.UnicodeSetIterator; import java.awt.Button; import java.awt.CheckboxMenuItem; import java.awt.FileDialog; @@ -44,40 +53,27 @@ import java.util.Set; import java.util.TreeSet; -import com.ibm.icu.lang.UCharacter; -import com.ibm.icu.text.BreakIterator; -import com.ibm.icu.text.CanonicalIterator; -import com.ibm.icu.text.Normalizer; -import com.ibm.icu.text.ReplaceableString; -import com.ibm.icu.text.Transliterator; -import com.ibm.icu.text.UTF16; -import com.ibm.icu.text.UnicodeSet; -import com.ibm.icu.text.UnicodeSetIterator; - /** - * A frame that allows the user to experiment with keyboard - * transliteration. This class has a main() method so it can be run - * as an application. The frame contains an editable text component - * and uses keyboard transliteration to process keyboard events. + * A frame that allows the user to experiment with keyboard transliteration. This class has a main() + * method so it can be run as an application. The frame contains an editable text component and uses + * keyboard transliteration to process keyboard events. * - *

Copyright (c) IBM Corporation 1999. All rights reserved. + *

Copyright (c) IBM Corporation 1999. All rights reserved. * * @author Alan Liu */ public class Demo extends Frame { - /** - * For serialization - */ + /** For serialization */ private static final long serialVersionUID = 1L; + static final boolean DEBUG = false; - static final String START_TEXT = "(cut,\u03BA\u03C5\u03C4,\u05D0,\u30AF\u30C8,\u4E80,\u091A\u0941\u0924\u094D)"; + static final String START_TEXT = + "(cut,\u03BA\u03C5\u03C4,\u05D0,\u30AF\u30C8,\u4E80,\u091A\u0941\u0924\u094D)"; Transliterator translit = null; String fontName = "Arial Unicode MS"; int fontSize = 18; - - /* boolean compound = false; @@ -96,12 +92,13 @@ public class Demo extends Frame { public static void main(String[] args) { Frame f = new Demo(600, 200); - f.addWindowListener(new WindowAdapter() { - public void windowClosing(WindowEvent e) { - com.ibm.icu.dev.demo.impl.DemoApplet.demoFrameClosed(); -// System.exit(0); - } - }); + f.addWindowListener( + new WindowAdapter() { + public void windowClosing(WindowEvent e) { + com.ibm.icu.dev.demo.impl.DemoApplet.demoFrameClosed(); + // System.exit(0); + } + }); f.setVisible(true); com.ibm.icu.dev.demo.impl.DemoApplet.demoFrameOpened(); } @@ -111,12 +108,13 @@ public Demo(int width, int height) { initMenus(); - addWindowListener(new WindowAdapter() { - public void windowClosing(WindowEvent e) { - handleClose(); - } - }); - + addWindowListener( + new WindowAdapter() { + public void windowClosing(WindowEvent e) { + handleClose(); + } + }); + text = new TransliteratingTextComponent(); Font font = new Font(fontName, Font.PLAIN, fontSize); text.setFont(font); @@ -133,37 +131,38 @@ private void initMenus() { MenuBar mbar; Menu menu; MenuItem mitem; - //CheckboxMenuItem citem; - + // CheckboxMenuItem citem; + setMenuBar(mbar = new MenuBar()); mbar.add(menu = new Menu("File")); menu.add(mitem = new MenuItem("Quit")); - mitem.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - handleClose(); - } - }); -/* - final ItemListener setTransliteratorListener = new ItemListener() { - public void itemStateChanged(ItemEvent e) { - CheckboxMenuItem item = (CheckboxMenuItem) e.getSource(); - if (e.getStateChange() == ItemEvent.DESELECTED) { - // Don't let the current transliterator be deselected. - // Just reselect it. - item.setState(true); - } else if (compound) { - // Adding an item to a compound transliterator - handleAddToCompound(item.getLabel()); - } else if (item != translitItem) { - // Deselect previous choice. Don't need to call - // setState(true) on new choice. - translitItem.setState(false); - translitItem = item; - handleSetTransliterator(item.getLabel()); - } - } - }; -*/ + mitem.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + handleClose(); + } + }); + /* + final ItemListener setTransliteratorListener = new ItemListener() { + public void itemStateChanged(ItemEvent e) { + CheckboxMenuItem item = (CheckboxMenuItem) e.getSource(); + if (e.getStateChange() == ItemEvent.DESELECTED) { + // Don't let the current transliterator be deselected. + // Just reselect it. + item.setState(true); + } else if (compound) { + // Adding an item to a compound transliterator + handleAddToCompound(item.getLabel()); + } else if (item != translitItem) { + // Deselect previous choice. Don't need to call + // setState(true) on new choice. + translitItem.setState(false); + translitItem = item; + handleSetTransliterator(item.getLabel()); + } + } + }; + */ /* translitMenu.add(translitItem = noTranslitItem = new CheckboxMenuItem(NO_TRANSLITERATOR, true)); @@ -177,30 +176,30 @@ public void itemStateChanged(ItemEvent e) { translitMenu.addSeparator(); */ -/* - translitMenu.add(citem = new CheckboxMenuItem("Compound")); - citem.addItemListener(new ItemListener() { - public void itemStateChanged(ItemEvent e) { - CheckboxMenuItem item = (CheckboxMenuItem) e.getSource(); - if (e.getStateChange() == ItemEvent.DESELECTED) { - // If compound gets deselected, then select NONE - setNoTransliterator(); - } else if (!compound) { - // Switching from non-compound to compound - translitItem.setState(false); - translitItem = item; - translit = null; - compound = true; - compoundCount = 0; - for (int i=0; i &Hex($1) &Name($1);\r\n" - + "&Hex-Any($1) < ('\\' [uU] [a-fA-F0-9]*);\r\n" - + "&Name-Any($1) < ('{' [^\\}]* '}');" - ); + + rulesDialog = + new InfoDialog( + this, + "Rule-Based Transliterator", + "", + "([A-Z]) > &Hex($1) &Name($1);\r\n" + + "&Hex-Any($1) < ('\\' [uU] [a-fA-F0-9]*);\r\n" + + "&Name-Any($1) < ('{' [^\\}]* '}');"); button = new Button("Set"); - button.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - String compound = ""; - try { - compound = rulesDialog.getArea().getText(); - String id = ruleId.getText(); - setTransliterator(compound, id); - } catch (RuntimeException ex) { - rulesDialog.getArea().setText(compound + "\n#" + ex.getMessage()); - } - } - }); + button.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + String compound = ""; + try { + compound = rulesDialog.getArea().getText(); + String id = ruleId.getText(); + setTransliterator(compound, id); + } catch (RuntimeException ex) { + rulesDialog.getArea().setText(compound + "\n#" + ex.getMessage()); + } + } + }); rulesDialog.getBottom().add(button); ruleId = new TextField("test1", 20); Label temp = new Label(" Name:"); rulesDialog.getBottom().add(temp); rulesDialog.getBottom().add(ruleId); - - - translitMenu.add(mitem = new MenuItem("From Rules...", - new MenuShortcut(KeyEvent.VK_R))); - mitem.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - rulesDialog.show(); - } - }); - - - translitMenu.add(mitem = new MenuItem("From File...", - new MenuShortcut(KeyEvent.VK_F))); + + translitMenu.add(mitem = new MenuItem("From Rules...", new MenuShortcut(KeyEvent.VK_R))); + mitem.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + rulesDialog.show(); + } + }); + + translitMenu.add(mitem = new MenuItem("From File...", new MenuShortcut(KeyEvent.VK_F))); mitem.addActionListener(new FileListener(this, RULE_FILE)); - + translitMenu.add(mitem = new MenuItem("Test File...")); mitem.addActionListener(new FileListener(this, TEST_FILE)); - + // Flesh out the menu with the installed transliterators - + translitMenu.addSeparator(); - + Iterator sources = add(new TreeSet(), Transliterator.getAvailableSources()).iterator(); - while(sources.hasNext()) { + while (sources.hasNext()) { String source = (String) sources.next(); - Iterator targets = add(new TreeSet(), Transliterator.getAvailableTargets(source)).iterator(); + Iterator targets = + add(new TreeSet(), Transliterator.getAvailableTargets(source)).iterator(); Menu targetMenu = new Menu(source); - while(targets.hasNext()) { + while (targets.hasNext()) { String target = (String) targets.next(); - Set variantSet = add(new TreeSet(), Transliterator.getAvailableVariants(source, target)); + Set variantSet = + add(new TreeSet(), Transliterator.getAvailableVariants(source, target)); if (variantSet.size() < 2) { mitem = new MenuItem(target); mitem.addActionListener(new TransliterationListener(source + "-" + target)); @@ -399,12 +411,14 @@ public void actionPerformed(ActionEvent e) { } else { Iterator variants = variantSet.iterator(); Menu variantMenu = new Menu(target); - while(variants.hasNext()) { + while (variants.hasNext()) { String variant = (String) variants.next(); String menuName = variant.length() == 0 ? "" : variant; - //System.out.println("<" + source + "-" + target + "/" + variant + ">, <" + menuName + ">"); + // System.out.println("<" + source + "-" + target + "/" + variant + ">, <" + + // menuName + ">"); mitem = new MenuItem(menuName); - mitem.addActionListener(new TransliterationListener(source + "-" + target + "/" + variant)); + mitem.addActionListener( + new TransliterationListener(source + "-" + target + "/" + variant)); variantMenu.add(mitem); } targetMenu.add(variantMenu); @@ -412,30 +426,29 @@ public void actionPerformed(ActionEvent e) { } translitMenu.add(targetMenu); } - - } - + static final int RULE_FILE = 0, TEST_FILE = 1; + // static class FileListener implements ActionListener { Demo frame; int choice; - + FileListener(Demo frame, int choice) { this.frame = frame; this.choice = choice; } - + public void actionPerformed(ActionEvent e) { String id = frame.translit.getID(); int slashPos = id.indexOf('/'); String variant = ""; if (slashPos >= 0) { - variant = "_" + id.substring(slashPos+1); + variant = "_" + id.substring(slashPos + 1); id = id.substring(0, slashPos); } - + FileDialog fileDialog = new FileDialog(frame, "Input File"); fileDialog.setFile("Test_" + id + ".txt"); fileDialog.show(); @@ -445,22 +458,23 @@ public void actionPerformed(ActionEvent e) { try { File f = new File(fileDirectory, fileName); if (choice == RULE_FILE) { - + // read stuff into buffer - + StringBuffer buffer = new StringBuffer(); FileInputStream fis = new FileInputStream(f); InputStreamReader isr = new InputStreamReader(fis, "UTF8"); - BufferedReader br = new BufferedReader(isr, 32*1024); + BufferedReader br = new BufferedReader(isr, 32 * 1024); while (true) { String line = br.readLine(); if (line == null) break; - if (line.length() > 0 && line.charAt(0) == '\uFEFF') line = line.substring(1); // strip BOM + if (line.length() > 0 && line.charAt(0) == '\uFEFF') + line = line.substring(1); // strip BOM buffer.append('\n'); buffer.append(line); } br.close(); - + // Transform file name into id if (fileName.startsWith("Transliterator_")) { fileName = fileName.substring("Transliterator_".length()); @@ -470,31 +484,34 @@ public void actionPerformed(ActionEvent e) { id = fileName; } else { id = fileName.substring(0, pos) + "-"; - int pos2 = fileName.indexOf('_', pos+1); + int pos2 = fileName.indexOf('_', pos + 1); if (pos2 < 0) { - id += fileName.substring(pos+1); + id += fileName.substring(pos + 1); } else { - id += fileName.substring(pos+1, pos2) + "/" + fileName.substring(pos2 + 1); + id += + fileName.substring(pos + 1, pos2) + + "/" + + fileName.substring(pos2 + 1); } - } + } pos = id.lastIndexOf('.'); if (pos >= 0) id = id.substring(0, pos); - + // Now set - + frame.setTransliterator(buffer.toString(), id); } else if (choice == TEST_FILE) { genTestFile(f, frame.translit, variant); } } catch (Exception e2) { e2.printStackTrace(); - System.out.println("Problem opening/reading: " + fileDirectory + ", " + fileName); + System.out.println( + "Problem opening/reading: " + fileDirectory + ", " + fileName); } } fileDialog.dispose(); } } - boolean transliterateTyping = true; Transliterator fromHex = Transliterator.getInstance("Hex-Any"); @@ -508,14 +525,16 @@ public void actionPerformed(ActionEvent e) { MenuItem convertTypingItem = null; Menu historyMenu; Map historyMap = new HashMap(); - Set historySet = new TreeSet(new Comparator() { - public int compare(Object a, Object b) { - MenuItem aa = (MenuItem)a; - MenuItem bb = (MenuItem)b; - return aa.getLabel().compareTo(bb.getLabel()); - } - }); - + Set historySet = + new TreeSet( + new Comparator() { + public int compare(Object a, Object b) { + MenuItem aa = (MenuItem) a; + MenuItem bb = (MenuItem) b; + return aa.getLabel().compareTo(bb.getLabel()); + } + }); + // ADD Factory since otherwise getInverse blows out static class DummyFactory implements Transliterator.Factory { static DummyFactory singleton = new DummyFactory(); @@ -527,11 +546,12 @@ static void add(String ID, Transliterator t) { System.out.println("Registering: " + ID + ", " + t.toRules(true)); Transliterator.registerFactory(ID, singleton); } + public Transliterator getInstance(String ID) { return (Transliterator) m.get(ID); } } - + static void printBreaks(int num, String testSource, BreakIterator brkItr) { String result = ""; int lastPos = 0; @@ -544,7 +564,7 @@ static void printBreaks(int num, String testSource, BreakIterator brkItr) { } System.out.println("Test" + num + ": " + result); } - + static void printIteration(int num, String testSource, CharacterIterator ci) { String result = ""; while (true) { @@ -554,9 +574,11 @@ static void printIteration(int num, String testSource, CharacterIterator ci) { } System.out.println("Test" + num + ": " + result); } - + static void printSources() { - String[] list = {"Latin-ThaiLogical", "ThaiLogical-Latin", "Thai-ThaiLogical", "ThaiLogical-Thai"}; + String[] list = { + "Latin-ThaiLogical", "ThaiLogical-Latin", "Thai-ThaiLogical", "ThaiLogical-Thai" + }; UnicodeSet all = new UnicodeSet(); for (int i = 0; i < list.length; ++i) { Transliterator tr = Transliterator.getInstance(list[i]); @@ -568,44 +590,45 @@ static void printSources() { UnicodeSet rem = new UnicodeSet("[[:latin:][:thai:]]"); System.out.println("missing from [:latin:][:thai:]: " + all.removeAll(rem).toPattern(true)); } - + // 200E;LEFT-TO-RIGHT MARK;Cf;0;L;;;;;N;;;;; static Transliterator title = Transliterator.getInstance("title"); - static String hexAndNameRules = " ([:c:]) > \\u200E &hex/unicode($1) ' ( ) ' &name($1) \\u200E ' ';" - + "([:mark:]) > \\u200E &hex/unicode($1) ' ( ' \\u200E \u25CC $1 \\u200E ' ) ' &name($1) \\u200E ' ';" - + "(.) > \\u200E &hex/unicode($1) ' ( ' \\u200E $1 \\u200E ' ) ' &name($1) ' ' \\u200E;"; + static String hexAndNameRules = + " ([:c:]) > \\u200E &hex/unicode($1) ' ( ) ' &name($1) \\u200E ' ';" + + "([:mark:]) > \\u200E &hex/unicode($1) ' ( ' \\u200E \u25CC $1 \\u200E ' ) ' &name($1) \\u200E ' ';" + + "(.) > \\u200E &hex/unicode($1) ' ( ' \\u200E $1 \\u200E ' ) ' &name($1) ' ' \\u200E;"; - static Transliterator hexAndName = Transliterator.createFromRules("any-hexAndName", - hexAndNameRules, Transliterator.FORWARD); - + static Transliterator hexAndName = + Transliterator.createFromRules( + "any-hexAndName", hexAndNameRules, Transliterator.FORWARD); + // static Transliterator upper = Transliterator.getInstance("upper"); - //static Transliterator upper = Transliterator.getInstance("upper"); - static final byte NONE = 0, TITLEWORD = 1, TITLELINE = 2; - + static void genTestFile(File sourceFile, Transliterator translit, String variant) { BufferedReader in = null; try { - + System.out.println("Reading: " + sourceFile.getCanonicalPath()); - in = new BufferedReader( - new InputStreamReader( - new FileInputStream(sourceFile), "UTF-8")); + in = + new BufferedReader( + new InputStreamReader(new FileInputStream(sourceFile), "UTF-8")); String targetFile = sourceFile.getCanonicalPath(); int dotPos = targetFile.lastIndexOf('.'); - if (dotPos >= 0) targetFile = targetFile.substring(0,dotPos); + if (dotPos >= 0) targetFile = targetFile.substring(0, dotPos); targetFile += variant; - + File outFile = new File(targetFile + ".html"); System.out.println("Writing: " + outFile.getCanonicalPath()); - - PrintWriter out = new PrintWriter( - new BufferedWriter( - new OutputStreamWriter( - new FileOutputStream(outFile), "UTF-8"))); - + + PrintWriter out = + new PrintWriter( + new BufferedWriter( + new OutputStreamWriter( + new FileOutputStream(outFile), "UTF-8"))); + String direction = ""; String id = translit.getID(); if (id.indexOf("Arabic") >= 0 || id.indexOf("Hebrew") >= 0) { @@ -617,7 +640,8 @@ static void genTestFile(File sourceFile, Transliterator translit, String variant testRoundTrip = false; generateSets = false; } - out.println(""); + out.println( + ""); out.println(""); out.println("" + id + " Transliteration Check"); - out.println("

See Test_Instructions.html for details.

"); + out.println( + "

See Test_Instructions.html for details.

"); out.println(""); - - //out.println(""); - + + // out.println(""); + Transliterator tl = translit; Transliterator lt = tl.getInverse(); - + Transliterator ltFilter = tl.getInverse(); ltFilter.setFilter(new UnicodeSet("[:^Lu:]")); Transliterator tlFilter = lt.getInverse(); tlFilter.setFilter(new UnicodeSet("[:^Lu:]")); - - //Transliterator.getInstance("[:^Lu:]" + lt.getID()); - + + // Transliterator.getInstance("[:^Lu:]" + lt.getID()); + BreakIterator sentenceBreak = BreakIterator.getSentenceInstance(); - + byte titleSetting = TITLELINE; - //boolean upperfilter = false; + // boolean upperfilter = false; boolean first = true; while (true) { String line = in.readLine(); @@ -656,91 +683,110 @@ static void genTestFile(File sourceFile, Transliterator translit, String variant line = line.trim(); if (line.length() == 0) continue; if (line.charAt(0) == '\uFEFF') line = line.substring(1); // remove BOM - + if (line.charAt(0) == '#') continue; // comments - + if (line.equals("@TITLECASE@")) { titleSetting = TITLEWORD; out.println(""); continue; } else if (line.equals("@UPPERFILTER@")) { - //upperfilter = true; + // upperfilter = true; continue; } else if (line.startsWith("@SET")) { UnicodeSet s = new UnicodeSet(line.substring(4).trim()); out.println(""); UnicodeSetIterator it = new UnicodeSetIterator(s); while (it.next()) { - addSentenceToTable(out, it.codepoint != UnicodeSetIterator.IS_STRING - ? UTF16.valueOf(it.codepoint) - : it.string, - NONE, true, testRoundTrip, first, tl, lt); + addSentenceToTable( + out, + it.codepoint != UnicodeSetIterator.IS_STRING + ? UTF16.valueOf(it.codepoint) + : it.string, + NONE, + true, + testRoundTrip, + first, + tl, + lt); } continue; } - + sentenceBreak.setText(line); int start = 0; while (true) { int end = sentenceBreak.next(); if (end == BreakIterator.DONE) break; String coreSentence = line.substring(start, end); - //System.out.println("Core: " + hex.transliterate(coreSentence)); + // System.out.println("Core: " + hex.transliterate(coreSentence)); end = start; - + int oldPos = 0; while (oldPos < coreSentence.length()) { // hack, because sentence doesn't seem to be working right int pos = coreSentence.indexOf(". ", oldPos); - if (pos < 0) pos = coreSentence.length(); else pos = pos+2; + if (pos < 0) pos = coreSentence.length(); + else pos = pos + 2; int pos2 = coreSentence.indexOf('\u3002', oldPos); - if (pos2 < 0) pos2 = coreSentence.length(); else pos2 = pos2 + 1; + if (pos2 < 0) pos2 = coreSentence.length(); + else pos2 = pos2 + 1; if (pos > pos2) pos = pos2; String sentence = coreSentence.substring(oldPos, pos).trim(); - //System.out.println("Sentence: " + hex.transliterate(coreSentence)); + // System.out.println("Sentence: " + hex.transliterate(coreSentence)); oldPos = pos; - - addSentenceToTable(out, sentence, - titleSetting, false, testRoundTrip, first, tl, lt); - + + addSentenceToTable( + out, sentence, titleSetting, false, testRoundTrip, first, tl, lt); + first = false; } } } out.println("
ThaiLatinThai
ThaiLatinThai
Names
Characters
"); out.close(); - + // Now write the source/target sets if (generateSets) { outFile = new File(targetFile + "_Sets.html"); System.out.println("Writing: " + outFile.getCanonicalPath()); - - out = new PrintWriter( - new BufferedWriter( - new OutputStreamWriter( - new FileOutputStream(outFile), "UTF-8"))); - out.println(""); + + out = + new PrintWriter( + new BufferedWriter( + new OutputStreamWriter( + new FileOutputStream(outFile), "UTF-8"))); + out.println( + ""); out.println(""); out.println("" + id + " Transliteration Sets"); out.println(""); - + int dashPos = id.indexOf('-'); int slashPos = id.indexOf('/'); if (slashPos < 0) slashPos = id.length(); UnicodeSet sourceSuper = null; try { - String temp = id.substring(0,dashPos); - if (temp.equals("ja")) sourceSuper = new UnicodeSet("[[:Han:][:hiragana:][:katakana:]]"); + String temp = id.substring(0, dashPos); + if (temp.equals("ja")) + sourceSuper = new UnicodeSet("[[:Han:][:hiragana:][:katakana:]]"); else sourceSuper = new UnicodeSet("[[:" + temp + ":][:Mn:][:Me:]]"); - } catch (Exception e) {} - + } catch (Exception e) { + } + UnicodeSet targetSuper = null; try { - targetSuper = new UnicodeSet("[[:" + id.substring(dashPos+1, slashPos) + ":][:Mn:][:Me:]]"); - } catch (Exception e) {} - + targetSuper = + new UnicodeSet( + "[[:" + + id.substring(dashPos + 1, slashPos) + + ":][:Mn:][:Me:]]"); + } catch (Exception e) { + } + int nfdStyle = CLOSE_CASE | CLOSE_FLATTEN | CLOSE_CANONICAL; int nfkdStyle = nfdStyle | CLOSE_COMPATIBILITY; out.println("