0

画像と .mp3 ファイルを取得し、オーディオが終了するとある画像から次の画像に移行するアプリケーションを作成しようとしています。これらの画像間をどのように移行するかの基本的なフレームワークは少し複雑ですが、SWT でアクションを取得して、ある画像から次の画像に手動で移行できるようにすることに成功しました。ただし、自動化しようとしたときに問題が発生しました。ループに入ると、displayShow() メソッドで行ったすべての呼び出しが解決される前に playAudio() メソッドが開始され、オーディオがまだ再生されているにもかかわらず、空白のウィンドウが表示されます。

ショーを開始したいアクションの実行メソッドは次のとおりです。

            Action startAction = new Action("Start") {
            public void run() {

                //do {
                    displayShow();
                    playAudio();
                //} while(true);            
            }
        };

これが playAudio() です。問題なくオーディオを再生できます。

    public void playAudio() {

    final String audio = "Happy_Birthday.mp3";
    audioLatch = new CountDownLatch(1);
    audioThread = new Thread() {
        public void run() {

            try {               
                Player player = new Player
                                    (new BufferedInputStream
                                        (new FileInputStream(audio)));

                player.play();  
                audioLatch.countDown();

            } catch (JavaLayerException e) {

            } catch (FileNotFoundException e) {

            } catch (Exception e) {

            }
        }   
    };
    audioThread.start();
    try {
        audioLatch.await();
    } catch (InterruptedException e) {

    }   
}

そして、ここにdisplayShow()があります:

    private void displayShow() {

    new Thread() {
        public void run() {
            Display.getDefault().asyncExec(new Runnable() {
                public void run() {
                    Control[] children = container.getChildren();

                    for (int i = 0; i < children.length; i++) {
                        children[i].dispose();
                    }

                    show.showSlide(container);
                    container.layout();
                }
            });
        }
    }.start();
}

show.showSlide は、最上位の親コンポジットの直接の子であるコンテナを親とするコンポジットを返します。新しく作成されたコンポジット内で、画像がラベルに追加され、ラベルの親がコンポジットに割り当てられます。displayShow() が別のスレッドにあるかどうかは重要ではないようです。これは私が試した最後のことでした。

リフレッシュが実行されない原因は、ループの追加だけではありません。手動トランジションを機能させる唯一の方法は、playAudio() メソッドから CountDownLatch を削除することです。このラッチを削除した場合、これら 2 つのメソッドをループに入れる唯一の方法は、while ループを埋め込むことです。これはかなりの量の CPU を占有しているように見えますが、それでも私の問題は解決しません。何か不足していますか?

4

1 に答える 1

0

audioLatch.await()メイン プログラム スレッドをブロックしています。これはすべての SWT 操作が実行されるスレッドであるためDisplay.asyncExec、スレッドが使用可能になるまでランナブルがキューに入れられます。

メソッドで本当に待機する必要がある場合はplayAudio、バックグラウンド スレッドが終了するまでそこで表示イベント ループを実行できます。

while (! background thread finished)
 {
   if (!display.readAndDispatch())
     display.sleep();
 }
于 2014-05-17T07:29:13.123 に答える