インプットメソッドエンジン SPI チュートリアル

目次

  1. はじめに
  2. インプットメソッドについて
  3. クライアントコンポーネントとの通信
  4. インプットメソッドウィンドウの使用
  5. 変換の実装
  6. エンジン固有の機能の提供
  7. インプットメソッドのパッケージ化
  8. サンプルコード

1. はじめに

インプットメソッドエンジン SPI を使うと、任意の Java 2 Runtime Environment で使える Java プログラミング言語のインプットメソッドを開発できます。Input Method Framework では、インプットメソッドは InputMethodDescriptor インタフェースおよび InputMethod インタフェースを実装する 2 つのクラスで構成され、拡張機能としていくつかの追加情報とともにパッケージ化されて Java 実行環境にインストールされます。 java.awt.im.spi パッケージの仕様、および InputMethodDescriptorInputMethod インタフェースによって、インプットメソッドの実装に必要なコアの情報が提供されます。このチュートリアルの追加情報を読めば、インプットメソッドを簡単に開発することができ、Java 2 プラットフォームの異なる実装間で発生する互換性の問題を回避するのに役立つ情報を得ることができます。


2. インプットメソッドについて

Input Method Framework でインプットメソッドの使用を開始する前に、その機能について理解する必要があります。必要な情報は、インプットメソッドの InputMethodDescriptor クラスの実装によって提供されます。この情報は、インプットメソッドを選択するときに使われます。

getAvailableLocales から返される利用可能なロケールのリストは、インプットメソッドの設計に実際に使用されている言語だけで構成されている必要があります。たとえば、中国語の簡体字を作成する Pinyin インプットメソッドでは、キーイベントは通過するだけで、英語またはマレー語も記述できるモードの場合でも、SIMPLIFIED_CHINESE だけを返さなければなりません。一方、 InputMethod.setLocale メソッドを使った場合は、実際に使用されていない言語で構成されている場合にも true を返すことがあります。つまり、getAvailableLocales は、ロードしてインプットメソッド切り替えるかどうかを決定するときに使われます。これは、インプットメソッドで、その言語を処理できる場合にのみ有効です。一方、setLocale は、インプットメソッドから切り替えるかどうかを決定するときに使われます。これは、インプットメソッドで言語をまったく処理できない場合にのみ有効です。


3. クライアントコンポーネントとの通信

インプットメソッドのインスタンスが生成されると、 setInputMethodContext を介して InputMethodContext インスタンスを受け取ります。このインスタンスによって、Input Method Framework、クライアントコンポーネント、または変換用ウィンドウと通信するときに必要な機能がすべて提供されます。変換テキストおよび確定テキストの情報は、 dispatchInputMethodEvent メソッドを使ってインプットメソッドから送信されます。また、InputMethodRequests インタフェースから継承したメソッドを使って、インプットメソッドからクライアントコンポーネントの情報を要求することができます。

Input Method Framework では、オンザスポット入力方式を使ってアクティブクライアントコンポーネントと常に通信していることを前提とする環境が、インプットメソッドに提供されます。実際のクライアントコンポーネントがアクティブクライアントでない場合、または別の入力方式が使われている場合は、イベントおよび要求は、必要に応じてリダイレクトされます。

インプットメソッドから、クライアントコンポーネントに直接アクセスしないでください。直接アクセスすると、フレームワークの切り替え機能およびリダイレクト機能と衝突します。インプットメソッドでは、インプットメソッドコンテキストから提供されたメソッドを常に使用してください。


4. インプットメソッドウィンドウの使用

インプットメソッドでは、ユーザーと通信するときにいくつかのウィンドウが使われることがあります。インプットメソッドでは、通常、次のウィンドウが使われます。

注: プラットフォームによっては、変換テキストを表示する変換用ウィンドウが、インプットメソッドによって表示されることがあります。Java の Input Method Framework では、変換テキストは、常にクライアントコンポーネントまたは Input Method Framework によって表示され、インプットメソッドによって表示されることはありません。

次の 3 つのグループのウィンドウについて理解しておくと役立ちます。

Java 2 プラットフォーム用に記述されたインプットメソッドによって、これらのウィンドウグループに対して行われる処理について説明します。

createInputMethodWindow によって作成されたウィンドウのフォーカスの動作は、実装に依存しています。ウィンドウが最初に表示されたとき、またはユーザーがウィンドウをクリックしたときにフォーカスを取得するようにしたり、まったくフォーカスを取得しないようにしたりすることもできます。インプットメソッドは、いずれの場合にも対応できなければなりません。

変換テキストにウィンドウ (ルックアップウィンドウなど) が自動的に対応するようにするには、インプットメソッドでそのインプットメソッドコンテキストの getTextLocation メソッドが使えなければなりません。現在のクライアントコンポーネントを含むウィンドウを考慮して、ウィンドウ (ステータスウィンドウなど) が自動的に対応するようにするには、インプットメソッドから、インプットメソッドコンテキストの enableClientWindowNotification メソッドを使用してウィンドウの位置と状態に関する通知を登録します。その後、 notifyClientWindowChange メソッドを実装して通知を受け取ります。

インプットメソッドで作成するウィンドウが不要になった場合は、すべてのウィンドウに対して Window.dispose を呼び出す必要があります。これにより、アプリケーションによって起動されているすべての非デーモンスレッドが終了すると、JVM が終了するようになります。詳細は、「AWT スレッドの問題」を参照してください。


5. 変換の実装

インプットメソッドでは、主にテキスト入力を変換するときのユーザーアクションの解釈が行われます。ユーザーアクションには、キーボードからの入力、マウスの使用、手書き、または音声などがあります。

activate および deactivate メソッドからインプットメソッドに対して、クライアントコンポーネントにフォーカスが設定されているかどうか、およびテキスト入力のターゲットになっているかどうかが通知されます。標準では、インプットメソッドでは、イベントがアクティブなときにのみテキストを変換するイベントが処理されます。

インプットメソッドがアクティブなときは、特定の種類のイベントが dispatchEvent メソッドによってインプットメソッドにディスパッチされ、クライアントコンポーネントによって処理されます。インプットメソッドでは、イベントごとに処理するかどうかが決定されます。処理された場合は、そのイベントに消費済みであることが指定され、クライアントコンポーネントでは処理されません。

: キーイベントの場合、インプットメソッドでは、KEY_TYPED イベントは、入力中の文字の情報を取得するときだけに使い、KEY_PRESSED または KEY_RELEASED イベントは、KEY_TYPED イベントが発生しないファンクションキーの情報を取得するときだけに使います。キーの押し下げと文字のマッピングは、プラットフォーム、ハードウェア、ロケール、およびその他の要素に依存しているため、基本的なオペレーティングシステムの設定を使うことをお勧めします。

インプットメソッドでは、テキストの変換および確定が行われているときに、クライアントコンポーネントでテキストが再描画されるように、クライアントコンポーネントに対して変更をすべて通知する必要があります。この通知は、 InputMethodContext.dispatchInputMethodEvent を使って、クライアントコンポーネントに対してインプットメソッドイベントの構築およびディスパッチをすることによって行います。Input Method Framework では、現在のイベントフローモデルに基づいて、イベントが変換用ウィンドウにリダイレクトされます。Java のインプットメソッドでは、インプットメソッドイベントをディスパッチしないと、変換されたテキストは表示されません。

変換されたテキストは、通常、現在の変換の状態がわかるように反転表示されます。テキストに対して TextAttribute.INPUT_METHOD_HIGHLIGHT キーおよび InputMethodHighlight のインスタンスを属性値として追加すると、反転表示されます。通常は、インプットメソッドには、インプットメソッド反転表示の状態および特定のプロパティーを使って抽象的反転表示だけを定義し、具体的なスタイルへのマッピングはレンダリングシステムで指定します。ただし、必要に応じて、インプットメソッドのスタイルプロパティーを使って、反転表示に具体的なスタイル情報を追加することができます。具体的なスタイルは、 Toolkit.mapInputMethodHighlight からの戻り値で変更できるように設計することをお勧めします。

クライアントコンポーネントおよび Input Method Framework では、現在の変換を終了しなければならない状況、およびすべての変換テキストを確定またはキャンセルしなければならない状況が認識されています。これらの情報は、endComposition メソッドを使ってインプットメソッドに通知されます。endComposition は、インプットメソッドがアクティブでないときに呼び出されます。

クライアントコンポーネントでは、いくつかのメソッドを使って、変換の文字セットの設定を変更できます。 InputContext.setCharacterSubsets メソッドを使って、インプットメソッドから入力できる Unicode 文字セットのサブセットを制限することができます。インプットメソッドでは、通常は、特定のサブセット以外の文字は作成されず、特定の文字サブセットがサポートされる別の入力モードに切り替えられます。 InputContext.setCompositionEnabled および isCompositionEnabled メソッドを使うと、現在のインプットメソッドが変換可能かどうかを検査および制御できます。InputContext.reconvert メソッドを使用すると、再変換を開始できます。


6. エンジン固有の機能の提供

インプットメソッドによっては、その Input Method Framework の API では利用できない機能を、クライアントコンポーネントに提供しなければならないことがあります。これは、インプットメソッドコントロールオブジェクトによって可能になります。インプットメソッドを開発するときは、このオブジェクトのインタフェースを公開し、InputMethod.getControlObject を介してインスタンスを返す必要があります。追加の機能を利用するクライアントコンポーネントは、 InputContext.getInputMethodControlObject を呼び出し、返されたオブジェクトが既知のコントロールオブジェクトクラスのインスタンスであるかどうかを確認し、そうである場合は、そのメソッドを呼び出します。


7. インプットメソッドのパッケージ化

インプットメソッドは、インストールされる拡張機能としてパッケージ化されます。設定内容については、SPI 仕様の「インプットメソッドのパッケージ化」を参照してください。Java アプリケーション環境にインストールされる拡張機能は、すべて同じ名前空間を共有します。名前の衝突を回避するには、インプットメソッドがパッケージの命名規約に準拠する必要があります。詳細は、Java 言語仕様を参照してください。これらの規約は、辞書などのインプットメソッド JAR ファイルにパッケージ化される、クラスファイル以外のファイルの命名にも適用する必要があります。


8. サンプルコード

City インプットメソッドは、インプットメソッドエンジン SPI の提供するインタフェースの使用方法を示す、単純なインプットメソッドです。


Copyright © 1993, 2013, Oracle and/or its affiliates. All rights reserved.