2014-05-17 26 views
0

我有一個Java程序,我在其中使用TTS(文本到語音),在那裏我想要一個動畫gif出現在屏幕上。我使用的是Netbeans GUI構建器,所以我創建了一個新的jpanel form,並將gif添加到該表單(java jpanel表單)的標籤中,之後我將此java作爲jpanel添加到我的主java文件中(通過拖放)。但問題是,只要TTS開始說話,就會停止gif的動畫。如何使它一起工作? 注:我使用的FreeTTS轉換文本到語音多個線程不能同時工作

代碼:

private static final String VOICENAME = "kevin16"; 
VoiceManager voiceManager = VoiceManager.getInstance(); 
..... 
........ 
Voice voice; 
voice = voiceManager.getVoice(VOICENAME); 
voice.allocate(); 
....//Some code here 
t4.setText("" + ran); 
voice.speak(t4.getText()); 
listenanum.setText("" + d); 
listenanum.setVisible(false); 
+0

Downvoter Care請發表評論嗎? –

+1

我們錯過了幾個部分:「您的TTS使用哪種API和實現?」和「你怎麼調用TTS?」。特別是,如果您從Swing UI線程調用TTS,並且您的TTS API在線程發言時阻塞線程,則UI中的任何內容都不會更新 - 如果是這種情況,您需要在不同的線程上講話。 –

+0

@ErwinBolwidt我不知道你寫的是什麼,但我會盡我所能給你提供這些信息,我會展示我正在做的代碼TTS –

回答

3

我不得不擡頭看的Javadoc的FreeTTS,這證實了我的想法。

speak方法Voice阻塞,直到口頭文本完成。方法speak(String)調用speak(FreeTTSSpeakable speakable),它具有此Javadoc:

說出給定的隊列項目。這是一種同步方法,不會 返回,直到說話完全被說出或已被取消。

但是,在Swing中,只要你在UI線程中做了一件事情,它什麼都做不了。所以你的動畫將停止,因爲它也需要UI線程重新繪製圖像。

也許解決這個問題的最好方法是深入研究語音API並在Voice上使用processUtterance(Utterance u)方法。這種方法是異步的;當語音在不同的語音輸出線程上完成時,它立即返回。

但是,一個簡單的解決方案可以讓您在不同的線程上調用speak方法。

final String textToSpeak = t4.getText(); 
Thread speechThread = new Thread(new Runnable() { 
    public void run() { 
     voice.speak(textToSpeak); 
    } 
}); 
speechThread.start(); 

實際上,最好使用線程池而不是每次啓動一個新線程,但這超出了您的直接問題。您可以搜索StackOverflow或查看java.util.concurrent.ThreadPoolExecutor瞭解更多信息。

+0

爲什麼不在一個單獨的線程中運行動畫gif?因爲我將在一個循環中使用TTS,而動畫gif僅在一段時間內啓動一次 –

+0

您不能使用UI線程進行講話,而使用另一個線程進行繪製 - Swing使用UI的單線程模型,並要求用於UI交互。但是您可以將所有與語音相關的工作保留在單獨的線程中,並且當您需要與UI進行交互時,可以使用'EventQueue.invokeLater'。看到之間許多其他Q's:http://stackoverflow.com/questions/19167154/why-is-it-important-to-use-invokelater,http://stackoverflow.com/questions/5544447/why-are-大多數的UI的框架,單線程 –