2014-05-17 22 views
0

我正在嘗試製作一個應用程序,用於檢索圖像和.mp3文件,並在音頻完成後從一個圖像切換到下一個圖像。我在這些圖像之間轉換的底層框架有點複雜,但我設法在SWT中獲得了一個成功的操作,使我能夠手動從一個轉換到另一個。但是,當我嘗試將其自動化時,出現了一個問題;當放置到一個循環中時,我的playAudio()方法在我的displayShow()方法所做的所有調用都已解決之前就開始了,這會導致一個空白窗口,儘管音頻仍在播放。JLayer Player放置在循環中時覆蓋SWT小部件的refesh

這裏是我要開始表演動作的run方法:

  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,我可以讓手動轉換工作。如果我刪除這個鎖存器,將這兩個方法封裝在一個循環中的唯一方法是嵌入while循環,這似乎佔用了相當數量的CPU,但仍然無法解決我的問題。我錯過了什麼?

回答

0

audioLatch.await()正在阻塞主程序線程,這是所有SWT操作運行的線程,因此Display.asyncExec可運行列表只會在線程可用前排隊。

如果你真的必須在playAudio方法等待,直到後臺線程完成你可以有運行顯示事件循環:

while (! background thread finished) 
{ 
    if (!display.readAndDispatch()) 
    display.sleep(); 
} 
+0

這工作,非常感謝你。我在演奏音樂的過程中等待並不是必須的。你會在哪裏做到這一點? –

+0

我有一個基於JavaZoom BasicPlayer的播放器 - 它使用監聽器在播放器線程完成時通知主線程。因此,您在播放開始時禁用「播放」按鈕,並在偵聽器被調用播放結束時再次啓用。 –

+0

按照您第一次建議的方式完成後,在每次轉換後,音頻結束和下一次移動之間的等待時間似乎正在增加。有沒有辦法強制顯示屏醒來? –