文档

Java™教程
隐藏目录
将拉丁数字转换为其他Unicode数字
路径:国际化
课程:处理文本

将拉丁数字转换为其他Unicode数字

默认情况下,当文本包含数字时,这些数字使用拉丁(欧洲)数字显示。如果希望使用其他Unicode数字形状,则可以使用java.awt.font.NumericShaper类。 NumericShaper API使您能够以任何Unicode数字形状显示以ASCII值表示的数字值。

以下代码片段来自ArabicDigits示例,展示了如何使用NumericShaper实例将拉丁数字转换为阿拉伯数字。确定形状动作的行已用粗体标出。

ArabicDigitsPanel(String fontname) {
    HashMap map = new HashMap();
    Font font = new Font(fontname, Font.PLAIN, 60);
    map.put(TextAttribute.FONT, font);
    map.put(TextAttribute.NUMERIC_SHAPING,
        NumericShaper.getShaper(NumericShaper.ARABIC));

    FontRenderContext frc = new FontRenderContext(null, false, false);
    layout = new TextLayout(text, map, frc);
}

// ...

public void paint(Graphics g) {
    Graphics2D g2d = (Graphics2D)g;
    layout.draw(g2d, 10, 50);
}

阿拉伯数字的NumericShaper实例被获取并放置在HashMap中作为TextLayout.NUMERIC_SHAPING属性键。哈希映射被传递给TextLayout实例。在paint方法中呈现文本后,数字将以所需的脚本显示。在此示例中,拉丁数字0到9以阿拉伯数字的形式绘制。

ArabicDigits示例输出显示从0到9的阿拉伯数字

上一个示例使用NumericShaper.ARABIC常量来检索所需的形状器,但NumericShaper类为许多语言提供了常量。这些常量被定义为位掩码,并称为NumericShaper 位掩码常量

基于枚举的范围常量

指定特定数字集的另一种方法是使用NumericShaper.Range枚举类型。该枚举在Java SE 7版本中引入,也提供了一组常量。尽管这些常量使用不同的机制定义,但NumericShaper.ARABIC位掩码在功能上等同于NumericShaper.Range.ARABIC枚举,并且每个常量类型都有相应的getShaper方法:

示例ArabicDigitsEnumArabicDigits示例相同,只是它使用NumericShaper.Range枚举来指定语言脚本:

ArabicDigitsEnumPanel(String fontname) {
    HashMap map = new HashMap();
    Font font = new Font(fontname, Font.PLAIN, 60);
    map.put(TextAttribute.FONT, font);
    map.put(TextAttribute.NUMERIC_SHAPING,
        NumericShaper.getShaper(NumericShaper.Range.ARABIC));
    FontRenderContext frc = new FontRenderContext(null, false, false);
    layout = new TextLayout(text, map, frc);
}

两个getShaper方法都接受singleRange参数。对于任何一个常量类型,都可以指定一段特定语言的脚本。基于位掩码的常量可以使用OR操作符进行组合,或者您可以创建一组NumericShaper.Range枚举。以下示例演示如何使用每个常量类型定义一个范围:

NumericShaper.MONGOLIAN | NumericShaper.THAI |
NumericShaper.TIBETAN
EnumSet.of(
    NumericShaper.Range.MONGOLIAN,
    NumericShaper.Range.THAI,
    NumericShaper.Range.TIBETAN)

您可以使用getRanges方法(基于位掩码的shaper)或getRangeSet方法(基于枚举的shaper)查询NumericShaper对象支持的范围。


注意: 

您可以使用传统的基于位掩码的常量或基于Range枚举的常量。在决定使用哪个时,请考虑以下几点:

  • Range API需要JDK 7或更高版本。
  • Range API涵盖的Unicode范围比基于位掩码的API更多。
  • 基于位掩码的API比Range API稍快。

根据语言环境呈现数字

示例ArabicDigits旨在使用特定语言的shaper,但有时必须根据语言环境呈现数字。例如,如果数字前面的文本使用泰语脚本,优先显示泰语数字。如果文本显示为藏文,则首选显示藏文数字。

你可以使用以下的getContextualShaper方法来实现:

前两个方法使用位掩码常量,后两个方法使用枚举常量。接受defaultContext参数的方法允许您在显示文本之前的数字值时指定初始形状。当未定义默认上下文时,任何前导数字都使用拉丁形状显示。

示例ShapedDigits演示了形状的工作原理。显示了五种文本布局:

  1. 第一个布局不使用形状器;所有数字都显示为拉丁字符。
  2. 第二个布局将所有数字形状化为阿拉伯数字,无论语言环境如何。
  3. 第三个布局使用使用阿拉伯数字的上下文形状器。默认上下文被定义为阿拉伯语。
  4. 第四个布局使用使用阿拉伯数字的上下文形状器,但形状器未指定默认上下文。
  5. 第五个布局使用使用ALL_RANGES位掩码的上下文形状器,但形状器未指定默认上下文。
ShapedDigits示例输出,说明上下文形状器的工作原理

以下代码显示了如何定义形状器(如果使用):

  1. 未使用形状器。
  2. NumericShaper arabic = NumericShaper.getShaper(NumericShaper.ARABIC);
  3. NumericShaper contextualArabic = NumericShaper.getContextualShaper(NumericShaper.ARABIC, NumericShaper.ARABIC);
  4. NumericShaper contextualArabicASCII = NumericShaper.getContextualShaper(NumericShaper.ARABIC);
  5. NumericShaper contextualAll = NumericShaper.getContextualShaper(NumericShaper.ALL_RANGES);

有关更多实现细节,请参见ShapedDigits.java示例。


上一页: 行边界
下一页: 转换非Unicode文本