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

目次

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

1. はじめに

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


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つのグループのウィンドウについて理解しておくと役立ちます。

ここでは、これらのウィンドウ・グループをインプット・メソッドでどのように処理できるかについて説明します。

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, 2020, Oracle and/or its affiliates. All rights reserved.