2014-05-17 82 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的框架,单线程 –