0

現在、音声認識コンポーネントを既存のアプリケーションに統合しています。私のアプリケーションには、JTree と JTextPane があります。jtextpane の Lost focus イベント ハンドラーと JTree の selection イベント ハンドラーを作成しました。フォーカスが jtextpane にあり、jtree でノードを選択すると、フォーカスが失われたイベント ハンドラーの前に、選択イベント ハンドラーが実行されることがわかります。フォーカス ロスト イベント ハンドラに ThreadPoolExecutor を記述し、ThreadPoolExecutor に 3 つのジョブを追加しました。選択ハンドラを実行する前に、ThradPoolExecutor 内のすべてのジョブを終了する必要があります。そのために、カウントダウンラッチを使用しています。私は多くの同様の投稿を読みましたが、選択イベントハンドラーを実行する前にフォーカスが失われたことを保証する方法を見つけることができませんでした. 一部の投稿では、invokeLater メソッドで選択イベント ハンドラー コードを実行するよう求められていました。しかし、ThreadPoolExecutor はそのコードを別のスレッドで実行するため、これは私の問題の解決策ではありません。以下に、コードを実行したいシーケンスを書き留めます

  1. フォーカス喪失イベント ハンドラーで ThreadPoolExecutor にジョブを追加する
  2. UI スレッドをブロックし、失われたフォーカス イベントで ThreadPoolExecutor に追加されたすべてのジョブを終了します。
  3. 選択イベント ハンドラを実行します。

以下は私のフォーカスハンドラの書かれたコードです

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();
      }

    }

  }
4

1 に答える 1

0

選択イベントがイベントと並行してのみ発生する場合は、を呼び出してから、選択イベントでメソッドを呼び出すfocusLost()必要があります。そうでない場合、最善の解決策はおそらくイベント ディスパッチャーでしょう。すべてのイベントをイベント ディスパッチャーに送信した場合、待機する必要があるかどうかを調整し、必要なスレッドを実行してから、適切なタイミングで適切なコンポーネントにイベントを再ディスパッチできます。 awaitTermination()ThreadPoolExecutorinvokeLater()JTree

于 2012-10-18T13:25:30.897 に答える