- PR -

FEP(IME)で入力した文字について

1
投稿者投稿内容
ショウ
会議室デビュー日: 2004/10/14
投稿数: 15
投稿日時: 2006-01-23 15:21
Swingを使用した画面アプリを開発しております。
JTextFieldでFEP(IME)起動中に文字を入力し、確定しない(下線が表示されている)状態で他のコンポーネントにフォーカスを移動すると、そのJTextFieldに下線が残った状態になってしまいます。
再度フォーカスをそのJTextFieldに移動すると、キャレットはその入力途中?文字列の最後にあるのですが、文字を入力(キーを押下)すると前回までの文字が消えてしまいました。
(例)
 ・「あいうえお」と入力。
 ・他のコンポーネントにフォーカスを移動。
 ・再度フォーカスを戻すと「あいうえお」の「お」の右にキャレット。
 ・何かキーを押すと「あいうえお」が消えて、今入力した文字だけになる。

上記を解消するために、JTextFieldにフォーカスリスナを追加し、フォーカスロスト時に設定してあるDocumentから未確定の文字列を取得し、InputMethodEventオブジェクトを自分で生成して、JTextFieldのdispatchEvent()を呼び出しました。
これでフォーカス移動時に下線が消え決定された状態になり、上記の不安定な動作を解消する事ができましたが、画面遷移等で上記動作を行った画面を終了してもヒープメモリが解放されないメモリリークが発生してしまいました。

InputMethodEventの生成は問題がなく、dispatchEvent()を呼び出すと発生するところまでは確認できました。
InputMethodEventは自分で生成しディスパッチしてはいけないのでしょうか?dispatchEvent()を呼び出すとなぜメモリリークが発生してしまうのでしょうか?

ご教授のほど、よろしくお願い致します。


【環境】
WindowsXP Pro Ver.2002 SP2
j2sdk1.4.2_04
ショウ
会議室デビュー日: 2004/10/14
投稿数: 15
投稿日時: 2006-01-24 10:03
自己返答です。
元の記載に間違っている部分がありました。

> Swingを使用した画面アプリを開発しております。
> JTextFieldでFEP(IME)起動中に文字を入力し、確定しない(下線が表示されている) 状態で他のコンポーネント
> にフォーカスを移動すると、そのJTextFieldに下線が残った状態になってしまいます。
> 再度フォーカスをそのJTextFieldに移動すると、キャレットはその入力途中?文字列の最後にあるのですが、文字
> を入力(キーを押下)すると前回までの文字が消えてしまいました。
上記の部分は自分で実装した箇所によるバグでした。

しかし、純粋なjavaだけを使用しても(例)にある入力をすると見かけ上問題なく動作しているのですが、メモリリークが発生してしまいます。(実行時のオプションに「-Xloggc:FILE_NAME -XX:+PrintGCDetails」を指定して出力されたガベージコレクションの情報により確認しました。)

引き続き、よろしくお願い致します。
ショウ
会議室デビュー日: 2004/10/14
投稿数: 15
投稿日時: 2006-01-25 12:58
自己返答です。
少しわかった事があるので、記述します。

フォーカスロスト時にFEPをOFFにすると、フォーカス移動時に不安定な動作(下線が残った状態)になるようです。
FEPのOFFは「this.getInputContext().setCharacterSubsets(null)」により行っています。
この状態で同じフォーカスロスト時にInputMethodEventをディスパッチするとメモリリークが発生します。

未確定文字列がある状態でフォーカスを移動すると、InputMethodEventはFocusEventの後に発生しています。しかしフォーカスロスト時にFEPをOFFにしてしまうとFocusEvent後のInputMethodEventが発生しなくなってしまいます。そこで元スレッドにあるようにInputMethodEventを自分で生成しディスパッチするようにしました。

ここからは推測ですが・・・
フォーカスロスト時にFEPをOFFにする事で発生すべきInputMethodEventを実行できなくなってしまい、そのイベントオブジェクトに付随するオブジェクトの参照が残りメモリリークが発生しているのでは?と考えています。ただ、FEPをOFFにするだけではメモリリークは発生せず、その後InputMethodEventをディスパッチすると発生するので、違う原因があるのかもしれません。

残ってしまっている?イベントオブジェクトをクリアする方法、また、JTextFieldから他のコンポーネントにフォーカスを移動した際にフォーカスロスト時以外でFEPをOFFにする方法等、何か気づいた点がありましたら、ご教授ください。

よろしくお願い致します。
ショウ
会議室デビュー日: 2004/10/14
投稿数: 15
投稿日時: 2006-01-27 15:30
自己返答です。
回避策が見つかりましたので、記述します。

自分で生成したInputMethodEventを
 JTextField#dispatchEvent(AWTEvent e);
で実行していたのですが、その部分を
 Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(AWTEvent e);
と変更したらメモリリークが発生しなくなりました。

キューに追加する事で実行されるタイミングが変わったため、問題を回避できたのだと思いますが、JTextField#dispatchEvent(AWTEvent e);を使用するとメモリリークが発生する原因はまだ掴めておりません。

何かご存知の方がいましたら、ご教授下さい。

よろしくお願い致します。
1

スキルアップ/キャリアアップ(JOB@IT)