選択肢からテキストを選び出す
MessageFormatで利用できる値の種類の中にChoiceFormatというものが登場していました。これについても触れておきましょう。MessageFormatは、複数の項目から1つを選択するためのものです。これは、次のような形でインスタンスを作成し利用します。
new ChoiceFormat( [double配列], [Object配列] );
String 変数 = [ChoiceFormat].format( double値 );
ChoiceFormatの基本的な考え方は、割とシンプルです。あらかじめ数値とメッセージのテキストをそれぞれ配列として用意しておき、ある数値を与えられたら、それがdouble配列のどこにあるものかをチェックして、それに対応する要素をObject配列から取り出し返します。
これ自体は非常にシンプルですが、このChoiceFormatは、「MessageFormatの中で利用できる」という点がポイントです。MessageFormatの中にChoiceFormatを埋め込むことで、与えられた値に応じて自動的にメッセージを生成するような仕組みを作ることができます。実際にやってみましょう。
import java.text.ChoiceFormat; // ……(略)…… public static void main(String args[]) { GregorianCalendar cal = new GregorianCalendar(); System.out.println(getMsg(cal)); } public static String getMsg(Calendar cal){ double[] month = {0,1,2,3,4,5,6,7,8,9,10,11}; String[] strs = {"新しい年となりました。", "寒さ厳しい季節となりました。", "水ぬるむ季節となりました。", "暖かな季節となりました。", "風薫る季節となりました。", "うっとおしい季節となりました。", "暑中お見舞い申し上げます。", "残暑お見舞い申し上げます。", "秋の気配を感じる時節となりました。", "秋も深まってまいりました。", "朝晩冷え込む季節となりました。", "今年も押し詰まってまいりました。" }; ChoiceFormat choice = new ChoiceFormat(month,strs); String msg = "{0}月、{1}いかがお過ごしですか。"; MessageFormat format = new MessageFormat(msg); format.setFormatByArgumentIndex(1,choice); int m = cal.get(Calendar.MONTH); Object[] objs = {(m + 1),m}; return format.format(objs); }

これは、Calendar引数で渡すと、時節の挨拶文を生成して返すgetMsgというメソッドを作成して利用するサンプルです。このgetMsgでは、ChoiceFormatで月の値から時節の挨拶を取り出す仕組みを用意し、これをMessageFormatで利用し挨拶文を作っています。
まず、ChoiceFormatの部分を見てみましょう。ここでは、double配列に0~11の「月の値」を用意し、Object配列には各月の挨拶文をString配列としてまとめてあります。そして、これらをもとにしてインスタンスを作成します。
通常ならば、後はformatメソッドを呼び出すだけですが、MessageFormat内から利用する場合には、ちょっとした仕掛けが必要です。まず、メッセージのパターンとなるテキストを用意し、MessageFormatインスタンスを生成します。
String msg = "{0}月、{1}いかがお過ごしですか。"; MessageFormat format = new MessageFormat(msg);
ここでは、月の数字を{0}として、また時節のテキストを{1}としてはめ込むようにしてあります。ここまでは、通常のMessageFormatの利用と同じです。次に、作成したChoiceFormatを、インデックス番号1番の{1}に設定されるようにします。
format.setFormatByArgumentIndex(1,choice);
このsetFormatByArgumentIndexは、パターン内の{}の項目に特定のオブジェクトを関連付けるためのものです。これにより、{1}には、choice(すなわちChoiceFormatのインスタンス)が関連付けられるようになります。
int m = cal.get(Calendar.MONTH); Object[] objs = {(m + 1),m}; return format.format(objs);
Calendarからgetで月の値を取り出し、これを元にObject配列を作成します。ここでは、{(m + 1),m}となっていますね。通常であれば、{0}には(m + 1)が、{1}にはmがそれぞれはめこまれるはずです。が、先にsetFormatByArgumentIndexで{1}にはChoiceFormatを設定してあります。ということは? このObject配列に用意されたmの値を引数にして、関連付けられているChoiceFormatのformatが実行され、その結果のStringが{1}にはめ込まれるようになるのです。
まぁ、この「ChoiceFormatとMessageFormatのあわせ技」は、何がどうなってるのか呑み込むのが大変かもしれません。実際にいくつかサンプルを書いて動かしてみると、どの値がどこでどう変換されているのか、次第に分かってくるはずです。まずは、MessageFormatをしっかり覚えて、「余裕があれば、こっちも挑戦してみるか」という程度に考えておきましょう。
まとめ
今回取り上げた「日時の値」と「各種の値のフォーマット」は、機能的にはそれほど重要なものではないように思えるかも知れません。が、実際に利用するためのプログラムを作っていくと、これらは非常に大きなウェイトを占めるものであることが分かってきます。実務的なデータを扱うプログラムでは、日時の値は必須といってよいでしょう。また値のフォーマットも、各種の値をいかに見やすく分かりやすく加工するかということを考えたとき、重要です。
Javaには非常にたくさんのクラスライブラリがあります。これまでの連載で、大きな機能についてはざっくりと使い方を説明してきました。が、「それらが分かればプログラムは作れる」というわけでもありません。実際に利用されるプログラムを作るには、意外に細かなところで引っかかるものです。今回の「日時」や「フォーマット」などは、その代表的なものといってよいでしょう。
少しずつ、実際のプログラムで必要とされるクラスの使い方を覚えていく。そうして語彙を増やしていくことが、プログラミングに習熟するということだ、といってよいでしょう。
