現在、音声認識コンポーネントを既存のアプリケーションに統合しています。私のアプリケーションには、JTree と JTextPane があります。jtextpane の Lost focus イベント ハンドラーと JTree の selection イベント ハンドラーを作成しました。フォーカスが jtextpane にあり、jtree でノードを選択すると、フォーカスが失われたイベント ハンドラーの前に、選択イベント ハンドラーが実行されることがわかります。フォーカス ロスト イベント ハンドラに ThreadPoolExecutor を記述し、ThreadPoolExecutor に 3 つのジョブを追加しました。選択ハンドラを実行する前に、ThradPoolExecutor 内のすべてのジョブを終了する必要があります。そのために、カウントダウンラッチを使用しています。私は多くの同様の投稿を読みましたが、選択イベントハンドラーを実行する前にフォーカスが失われたことを保証する方法を見つけることができませんでした. 一部の投稿では、invokeLater メソッドで選択イベント ハンドラー コードを実行するよう求められていました。しかし、ThreadPoolExecutor はそのコードを別のスレッドで実行するため、これは私の問題の解決策ではありません。以下に、コードを実行したいシーケンスを書き留めます
- フォーカス喪失イベント ハンドラーで ThreadPoolExecutor にジョブを追加する
- UI スレッドをブロックし、失われたフォーカス イベントで ThreadPoolExecutor に追加されたすべてのジョブを終了します。
- 選択イベント ハンドラを実行します。
以下は私のフォーカスハンドラの書かれたコードです
public void focusLost(FocusEvent e)
{
if (ecaControl.isInitialized())
{
ecaControl.addStopRecordingJobToExecutor();
ecaControl.addSaveJobToExecutor(this.currentMetaFileName != null ? this.currentMetaFileName : this.getName());
ecaControl.addCloseJobToExecutor();
co = new CountDownLatch(ecaControl.getExecutor().counter);
ecaControl.getExecutor().setCountdownla(co);
try
{
System.out.println("------- count before" + ecaControl.getExecutor().counter);
co.await();
ecaControl.getExecutor().setCountdownla(null);
}
catch (InterruptedException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println("--------count after" + ecaControl.getExecutor().counter);
try
{
System.out.println("The text is "
+ this.getStyledDocument().getText(0, getStyledDocument().getLength()));
}
catch (BadLocationException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}