インライン編集タイプのTextFieldとItemStateListener - Dialerバージョン1.0.0での問題

 Dialerでは、一つのTextFieldの内容が変更されたときに関連する他のTextFieldが自動的に更新されるように、ItemStateListenerを使っている。このリスナーを設定したFormに置かれたItemの状態がユーザー操作によって変化すると、ItemStateListener.itemStateChanged()メソッドが呼ばれる仕組みである。
 ところが、インライン編集するタイプのTextFieldとItemStateListenerの相性はよくない。数字を入力するときのように1ストロークで入力が確定するときはよいが、マルチタップで英文字を入力する場合やT9などのインプットメソッドが介在する場合、キーを押して入力中の文字が変わるごとにitemStateChanged()が呼び出される。このことは数年前に別のメーカーの機種*1をいじっていて気がついたのだが、そのときは文字通りいじっていただけだったので、すっかり失念していた。
:以下はMIDletから見たノキアS60機での動きである。他の機種でインライン編集タイプのTextFieldを採用していたとしても、同じことが起こるとは限らない。)

 ItemStateListener.itemStateChanged()メソッドが呼ばれたところでTextField.getString()メソッドを使うと、未確定状態の文字も含めて、その状態での入力内容を受け取ることができる。にもかかわらず、実際には入力が確定していないためか、プラットフォーム側に処理が戻ると未確定の文字が消えてしまう。プラットフォームとMIDPの間で、状態が不整合になっているように見受けられる。
 かな漢字変換システムを使う場合、さらに状況が深刻化するようである。上記のような状態になった後、そのままMIDP実行環境が異常終了してしまう。全てはプラットフォーム側で起こっているため、MIDletとしてはどうすることもできない*2。操作フローを変更して、そのような状況にならないよう工夫する以外にない。端的に言うと、インライン編集タイプのTextFieldに対して、ItemStateListener.itemStateChanged()メソッドを使って処理することをあきらめるしかない。Dialerについては、簡単な対策を行ったバージョンを作った後、全く違った操作フローのバージョンを作るつもりである。
 ところで、今回調査していて一つ気づいたことがある。ConstraintsにNUMERICを指定したTexiFieldに対して、松茸では「+」「p」「w」「#」を入力しようとすることができる*3。これらの記号は電話番号の一部として用いるもので、数値として入力されるべきものではない。ConstraintsにPHUNENUMBERを指定したTextFieldと、扱いを区別していないようだ。数値しか入力されないはずのTextFieldに「+」「p」「w」「#」が入力されると、ItemStateListenerを使う使わないに関係なく、MIDP実行環境は異常終了する。

*1:記憶が曖昧だが、BenQに買収される以前のシーメンス機だったと思う。

*2:RuntimeExceptionとしてエラーが通知されることもない。そもそもMIDPには「テキスト編集中」という状態が存在しない。

*3:ここで、「+」は正数を示す符号ではないし、加算記号でもない。一方、負数を示す「-」を入力することはできない。