8.2.17 动态设置占位符的数据类型和显示模式

优质
小牛编辑
130浏览
2023-12-01

除了可以通过占位符本身指定数据类型和显示模式。还可以通过MessageFormat类的一系列setter方法来完成同样的工作。看下面的代码:

String pattern = "abc,{0}, {1}, {0}, {2}, {1}";

Object[] msgArgs = {"acb", "bac", new Date()};

MessageFormat mf = new MessageFormat(pattern);

mf.format(msgArgs);

上面的这段代码的模式字符串有五个占位符,但{0}和{1}占位符出现了两次。因此,在使用format方法格式化pattern时,只需要指定3个参数即可。

MessageFormat类用于设置占位符的setter方法如下:

setFormat方法和setFormats方法

这两个方法的定义如下:

public void setFormat(int formatElementIndex, Format newFormat)

public void setFormats(Format[] newFormats)

其中formatElementIndex参数表示占位符在整个模式字符串出现的位置。大家要注意,是“在模式字符串中出现的位置”,并不是在参数数组中的索引位置。也就是说,要设置格式化pattern,需要为其中的5个占位符单独设置数据类型和显示模式。即使有重复的占位符,也必须单独为每一个占位符设置数据类型和显示模式。newFormat参数表示封装当前占位符的数据类型、显示模式等信息的Format对象。

要注意的是,formatElementIndex参数指定的占位符在模式字符串中的位置,与占位符表达式本身的索引无关。如下面的代码所示:

String pattern = "abc,{1}, {0}";

Object[] msgArgs = {"bca", new Date()};

MessageFormat mf = new MessageFormat(pattern);

mf.setFormat(0, DateFormat.getDateInstance(DateFormat.LONG, Locale.US));

mf.format(msgArgs);

上面代码的setFormat方法的第一个参数虽然为0,但设置的是{1}占位符,而不是{0}占位符。

setFormats方法的newFormats参数是一个Format类型的数组。该方法的功能和setFormat方法类似,只是setFormats方法是一次性设置了模式字符串中所有的占位符的数据类型和显示模式。其中Format数组中的每一个元素的索引与它们各自对应的占位符在模式字符串中出现的位置对应。如果不打算对某个占位符进行设置,和该占位符对应的数组元素应设为null。

setFormatByArgumentIndex方法和setFormatsByArgumentIndex方法

这两个方法的定义如下:

public void setFormatByArgumentIndex(int argumentIndex, Format newFormat)

public void setFormatsByArgumentIndex(Format[] newFormats)

这两个方法和相应的setFormat及setFormats方法的参数相同。但所表示的含义却不同。setFormatByArgumentIndex方法中的argumentIndex参数表示参数数组中的元素的索引,也可以认为是占位符表达式中的索引。也就是说,setFormatByArgumentIndex方法设置的是msgArgs数组中元素的格式。如果在模式字符串中有重复的占位符,如{0}出现多次,只需使用下面的代码就可设置所有的{0}占位符的格式:

MessageFormat mf = new MessageFormat(pattern);

mf.setFormatByArgumentIndex(0, DateFormat.getDateInstance(DateFormat.LONG,

    Locale.US));

setFormatsByArgumentIndex方法中的newFormats参数也有类似的功能。该方法可以一次性地设置参数数组中所有元素的格式。如果不想设置某个占位符的格式,可以将相应的数组元素设为null。

上面两组方法可以根据不同的顺序设置指定占位符的格式。如果同一个占位符在模式字符串中多次出现,并且这些重复的占位符需要设置不同的格式,可以使用setFormat或setFormats方法来完成。如果要将所有相同的占位符都设置成同样的格式,可以使用setFormatByArgumentIndex或setFormatsByArgumentIndex方法。

下面的例子演示了如何使用setFormatByArgumentIndex方法动态设置占位符的数据类型和显示模式:

package chapter8;
import java.util.Locale;
import java.util.Date;
import java.text.MessageFormat;
import java.text.DateFormat;
import java.text.NumberFormat;
public class DynamicFormat
{
    public static void main(String[] args) throws Exception
    {
        String pattern = "今天的日期是{0},现在的时间是{1},据说今晚会下雨,但我认为至少有{2}的可能性不下雨。" + "现在快下班了,今天发了薪水,{3}多呢!哈哈!";
        MessageFormat mf = new MessageFormat(pattern);
        Date date = new Date();
        Object[] msgArgs = {date, date, 0.85, 5000};
        System.out.println("未动态设置占位符的数据类型和显示模式:");
        System.out.println(mf.format(msgArgs));
        System.out.println("动态设置点占符的数据类型和显示模式:");
        mf.setFormatByArgumentIndex(0, DateFormat.getDateInstance(DateFormat.LONG, Locale.US));
        mf.setFormatByArgumentIndex(1, DateFormat.getTimeInstance(DateFormat.LONG, Locale.US));
        mf.setFormatByArgumentIndex(2, NumberFormat.getPercentInstance(Locale.US));
        mf.setFormatByArgumentIndex(3, NumberFormat.getCurrencyInstance(Locale.US));       
        System.out.println(mf.format(msgArgs));
    }
}

DynamicFormat程序的输出结果如下:

未动态设置占位符的数据类型和显示模式:

今天的日期是08-10-19 下午4:55,现在的时间是08-10-19 下午4:55,据说今晚会下雨,但我认为至少有0.85的可能性不下雨。现在快下班了,今天发了薪水,5,000多呢!哈哈!

动态设置点占符的数据类型和显示模式:

今天的日期是October 19, 2008,现在的时间是4:55:17 PM CST,据说今晚会下雨,但我认为至少有85%的可能性不下雨。现在快下班了,今天发了薪水,$5,000.00多呢!哈哈!