使用 Swing UI 和 FreeTTS 在 Java 中实现的语音时钟。






4.27/5 (5投票s)
一个可在 Windows、Mac 和 Linux 上运行的平台无关应用程序

引言
这是一个简单的报时钟应用程序,主要演示三点
- TPI 概念 - 真正的平台独立性 - 这意味着此应用程序可在安装 JRE 的任何地方运行,例如 Linux 发行版、MacOS 或 Windows 平台。
- Nimbus UI - 这是一种新型的平台无关 UI,用于保持基于 Swing 的软件在不同平台上的视觉设计一致性。
- 使用 FreeTTS - 一个完全用 Java 编写的开源语音合成系统。运行此应用程序必须安装它,可以在这里找到 这里(由于大小限制为 6MB,无法在此上传)。
背景
在开发平台无关应用程序期间,我经常考虑使用 JSAPI(Java 语音 API)来创建语音辅助应用程序,最终找到了这个基于 Flite 的 JSAPI 实现 - FreeTTS(免费文本转语音)。
Using the Code
第一部分是构造函数的工作。它应用 Nimbus UI,然后创建一个计时器“tt
”,每秒钟调用一次“taskperformer
”,并启动它,最后将初始文本(即当前日期和时间)应用于按钮。
第二部分是taskperformer
本身,这里编写的任何代码都将每秒执行一次。在本例中,它应用当前日期和时间。
第三部分是程序的实际核心。使用变量“nulls
”,我们保存日期时间的实例,然后使用SHORT
格式化它,以便它只返回 12 小时格式的时间,最终存储在字符串“sText
”中以及需要朗读的其他文本。在检查文本非空后,我们创建父对象 -“VoiceManager
”和子对象“Voice
”,分别使用实例“voiceManager
”(注意小写字母)和“syntheticVoice
”,两者都赋值为null
。
接下来,我们分别使用getinstance()
和getvoice()
方法为voiceManager
和syntheticVoice
赋值。getvoice()
方法的参数用于将所需的语音应用于我们的语音,其详细信息可以在 FreeTTS 文档中找到。最后,我们使用allocate()
和speak()
以及参数sText
来实际朗读时间。
public MainForm()
{
// The below try block is used to apply the platform independent
// nimbus look to Application.
try
{
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
}
catch(Exception e){}
initComponents();
// Creation of timer that ticks after 1000 milli seconds = 1 second.
Timer tt = new Timer(1000, taskPerformer);
tt.start();
setDefaultCloseOperation(EXIT_ON_CLOSE);
//Button initially set to display current date and time.
jButton1.setText(new Date().toString());
}
ActionListener taskPerformer = new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
// action performed at every tick, i.e. refresh the text with current time.
jButton1.setText(new Date().toString());
}
};
private void jButton1MouseClicked(java.awt.event.MouseEvent evt)
{
// string to hold the text to be spoken.
String sText;
//nulls is a temporary variable to hold datetime for further formatting.
Date nulls=new Date();
// Creation of final output using SHORT format of datetime.
sText="The Time is :"
+(DateFormat.getTimeInstance(DateFormat.SHORT).format(nulls));
// Checking though unnecessary, is used avoid exceptions.
if (sText != null && sText.trim().length() > 0)
{
VoiceManager voiceManager = null;
Voice syntheticVoice = null;
try
{
voiceManager = VoiceManager.getInstance();
// other voices are also supported,
// like alan,kevin etc see freeTTS documentation on sourceforge.
syntheticVoice = voiceManager.getVoice("kevin16");
syntheticVoice.allocate();
syntheticVoice.speak(sText);
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
syntheticVoice.deallocate();
}
}
}
注意:在 NetBeans 下使用源代码会非常方便(文件->打开项目->解压的文件夹),但是手动编译src->Regular_App下的MainForm.java 并使用 -jar 开关也可以达到同样的效果。建议使用最新的 JRE 来运行应用程序,而 JDK 则是编译源代码所必需的。
关注点
由于我对 Java 非常陌生,我最初使用正则表达式来分割字符串以格式化日期和时间的长格式。但在搜索日期格式时,我最终找到了这行简单的代码来格式化Date
。
历史
未使用标准格式化的旧(笨拙的)版本可以通过私信获取。