2 * Copyright 2001 Sun Microsystems, Inc.
4 * See the file "license.terms" for information on usage and
5 * redistribution of this file, and for a DISCLAIMER OF ALL
8 import java.awt.BorderLayout;
9 import java.awt.Component;
10 import java.awt.Dimension;
12 import java.awt.event.ActionEvent;
13 import java.awt.event.ActionListener;
14 import java.awt.event.WindowAdapter;
15 import java.awt.event.WindowEvent;
19 import javax.speech.synthesis.SynthesizerModeDesc;
20 import javax.speech.synthesis.Voice;
22 import javax.swing.JFileChooser;
23 import javax.swing.JFrame;
24 import javax.swing.JMenu;
25 import javax.swing.JMenuBar;
26 import javax.swing.JMenuItem;
27 import javax.swing.JOptionPane;
28 import javax.swing.ListModel;
29 import javax.swing.LookAndFeel;
30 import javax.swing.SwingUtilities;
31 import javax.swing.UIManager;
33 public class Player extends JFrame {
35 private PlayerModel playerModel;
36 private PlayerPanel playerPanel;
37 private PlayerMenuBar playerMenuBar;
39 private Font globalFont;
40 private String globalFontFace = "Arial";
44 * Constructs a Player with the given title.
46 * @param title the title of the Player
48 public Player(String title) {
51 setDefaultLookAndFeelDecorated(true);
52 addWindowListener(new WindowAdapter() {
53 public void windowClosing(WindowEvent e) {
59 playerModel = new PlayerModelImpl();
60 playerPanel = new PlayerPanel(playerModel);
61 setSize(playerPanel.getSize());
62 getContentPane().add(playerPanel, BorderLayout.CENTER);
67 * Returns the view model of this Player application.
69 * @return the view model
71 public PlayerPanel getView() {
77 * Returns the data model of this Player application.
79 * @return the data model
81 public PlayerModel getModel() {
87 * Sets the menubar for this Player.
89 * @param menubar the menubar
91 public void setMenuBar(PlayerMenuBar menubar) {
92 playerMenuBar = menubar;
93 setJMenuBar(playerMenuBar);
98 * Show/hide the current monitor from the applcation frame.
100 * @param show true to show, false to hide
102 public void showMonitor(boolean show) {
103 Monitor monitor = playerModel.getMonitor();
104 int newHeight = getSize().height;
105 int monitorHeight = monitor.getSize().height;
108 playerPanel.add(monitor, BorderLayout.SOUTH);
109 newHeight += monitorHeight;
111 playerPanel.remove(monitor);
112 newHeight -= monitorHeight;
115 Dimension newSize = new Dimension(getSize().width, newHeight);
116 playerPanel.setSize(newSize);
119 playerModel.setMonitorVisible(show);
125 * Changes the font size of all components in this Player.
127 * @param change the change in font size
129 public void setGlobalFontSize(int fontSize) {
130 if (globalFont == null) {
131 globalFont = getFont();
133 globalFont = new Font(globalFontFace, Font.BOLD, fontSize);
135 UIManager.put("Button.font", globalFont);
136 UIManager.put("ComboBox.font", globalFont);
137 UIManager.put("Label.font", globalFont);
138 UIManager.put("List.font", globalFont);
139 UIManager.put("Menu.font", globalFont);
140 UIManager.put("MenuItem.font", globalFont);
141 UIManager.put("TextArea.font", globalFont);
142 UIManager.put("ToggleButton.font", globalFont);
143 UIManager.put("ToolTip.font", globalFont);
147 SwingUtilities.updateComponentTreeUI(this);
153 * A convenience method for setting the Look & Feel.
155 * @param lookAndFeel the Look & Feel specification
157 public void setLookAndFeel(Object lookAndFeel) {
159 if (lookAndFeel instanceof String) {
160 UIManager.setLookAndFeel((String) lookAndFeel);
161 } else if (lookAndFeel instanceof LookAndFeel) {
162 UIManager.setLookAndFeel((LookAndFeel) lookAndFeel);
165 SwingUtilities.updateComponentTreeUI(this);
167 } catch (Exception ex) {
168 ex.printStackTrace();
173 * Sets the voice for the Player. The main purpose of this
174 * method is to set the Player to a nice voice on startup.
176 public void setVoice(String voiceName) {
177 PlayerModel model = getModel();
178 ListModel descList = model.getSynthesizerList();
179 for (int i = 0; i < descList.getSize(); i++) {
180 SynthesizerModeDesc desc = (SynthesizerModeDesc)
181 descList.getElementAt(i);
182 Voice[] voices = desc.getVoices();
183 for (int j = 0; j < voices.length; j++) {
184 if (voices[j].getName().equals(voiceName)) {
185 model.setSynthesizer(i);
195 * The main() method of the Player.
197 public static void main(String[] args) throws Exception {
198 boolean showMonitor = false;
199 String firstVoice = "kevin16";
201 Player player = new Player("FreeTTS Player");
203 for (int i = 0; i < args.length; i++) {
204 if (args[i].equals("-voice")) {
205 if (++i < args.length) {
206 firstVoice = args[i];
208 } else if (args[i].equals("-fontsize")) {
209 if (++i < args.length) {
210 player.setGlobalFontSize(Integer.parseInt(args[i]));
212 } else if (args[i].equals("-monitor")) {
214 } else if (args[i].equals("-input")) {
216 PlayerModel model = player.getModel();
218 for (i++; i < args.length; i++) {
219 int start = args[i].indexOf(':');
221 String content = args[i].substring(start+1);
222 System.out.println(content);
223 if (args[i].startsWith("plaintext:")) {
225 (Playable.createTextPlayable(content));
226 } else if (args[i].startsWith("textfile:")) {
228 (Playable.createTextFilePlayable
229 (new File(content)));
230 } else if (args[i].startsWith("jsmltext:")) {
232 (Playable.createJSMLPlayable(content));
233 } else if (args[i].startsWith("jsmlfile:")) {
235 (Playable.createJSMLFilePlayable
236 (new File(content)));
243 player.setMenuBar(new PlayerMenuBar(player));
244 player.getModel().createSynthesizers();
245 player.setVoice(firstVoice);
250 player.showMonitor(showMonitor);
256 * Implements the menubar of the Player application.
258 class PlayerMenuBar extends JMenuBar {
259 private Player player;
260 private PlayerModel playerModel;
262 private JFileChooser fileChooser;
264 private JMenuItem fileSpeakJSMLMenuItem;
265 private JMenuItem fileSpeakTextMenuItem;
266 private JMenuItem fileSpeakURLMenuItem;
267 private JMenuItem fileExitMenuItem;
269 private JMenuItem styleLFCrossPlatformMenuItem;
270 private JMenuItem styleLFSystemMenuItem;
271 private JMenuItem styleFontSizeLargerMenuItem;
272 private JMenuItem styleFontSizeSmallerMenuItem;
274 private JMenuItem monitorHideMenuItem;
275 private JMenuItem monitorShowMenuItem;
277 private static char crossPlatformMnemonic = 'C';
278 private static char exitMnemonic = 'X';
279 private static char fileMnemonic = 'F';
280 private static char hideMonitorMnemonic = 'H';
281 private static char jsmlMnemonic = 'J';
282 private static char monitorMnemonic = 'M';
283 private static char showMonitorMnemonic = 'S';
284 private static char speakMnemonic = 'S';
285 private static char styleMnemonic = 'E';
286 private static char styleLFMnemonic = 'L';
287 private static char systemMnemonic = 'S';
288 private static char textMnemonic = 'T';
289 private static char urlMnemonic = 'U';
293 * Constructs a menubar with the given Player data model.
295 * @param playerModel the Player data model
297 public PlayerMenuBar(Player player) {
299 this.player = player;
300 this.playerModel = player.getModel();
301 this.fileChooser = new JFileChooser();
302 fileChooser.setCurrentDirectory
303 (new File(System.getProperty("user.dir")));
305 add(createFileMenu());
306 add(createStyleMenu());
307 add(createMonitorMenu());
312 * Creates the File menu.
314 * @return the File menu
316 private JMenu createFileMenu() {
317 JMenu fileMenu = new JMenu("File");
318 fileMenu.setMnemonic(fileMnemonic);
321 JMenu fileSpeakMenu = new JMenu("Speak");
322 fileSpeakMenu.setMnemonic(speakMnemonic);
324 fileSpeakJSMLMenuItem = new JMenuItem("JSML File ...");
325 fileSpeakTextMenuItem = new JMenuItem("Text File ...");
326 fileSpeakURLMenuItem = new JMenuItem("URL ...");
327 fileSpeakJSMLMenuItem.setMnemonic(jsmlMnemonic);
328 fileSpeakTextMenuItem.setMnemonic(textMnemonic);
329 fileSpeakURLMenuItem.setMnemonic(urlMnemonic);
331 fileSpeakMenu.add(fileSpeakJSMLMenuItem);
332 fileSpeakMenu.add(fileSpeakTextMenuItem);
333 fileSpeakMenu.add(fileSpeakURLMenuItem);
335 fileExitMenuItem = new JMenuItem("Exit");
336 fileExitMenuItem.setMnemonic(exitMnemonic);
338 fileMenu.add(fileSpeakMenu);
339 fileMenu.addSeparator();
340 fileMenu.add(fileExitMenuItem);
342 addFileMenuListeners();
349 * Adds the given Playaable to the play list, and plays it.
351 private void playPlayable(Playable playable) {
352 playerModel.addPlayable(playable);
353 player.getView().getPlayList().setSelectedValue(playable, true);
354 playerModel.play(playable);
359 * Add listenrs to the file menu.
361 private void addFileMenuListeners() {
362 fileExitMenuItem.addActionListener(new ActionListener() {
363 public void actionPerformed(ActionEvent e) {
368 fileSpeakJSMLMenuItem.addActionListener(new ActionListener() {
369 public void actionPerformed(ActionEvent e) {
370 File file = chooseFile();
372 playPlayable(Playable.createJSMLFilePlayable(file));
376 fileSpeakTextMenuItem.addActionListener(new ActionListener() {
377 public void actionPerformed(ActionEvent e) {
378 File file = chooseFile();
380 playPlayable(Playable.createTextFilePlayable(file));
384 fileSpeakURLMenuItem.addActionListener(new ActionListener() {
385 public void actionPerformed(ActionEvent e) {
386 String url = JOptionPane.showInputDialog
387 (getParent(), "Enter URL:", "Speak URL",
388 JOptionPane.QUESTION_MESSAGE);
389 if (url != null && url.length() > 0) {
390 playPlayable(Playable.createURLPlayable(url));
398 * Creates the Style menu.
400 * @return the Style menu
402 private JMenu createStyleMenu() {
403 JMenu styleMenu = new JMenu("Style");
404 styleMenu.setMnemonic(styleMnemonic);
406 JMenu styleLFMenu = new JMenu("Look & Feel");
407 styleLFMenu.setMnemonic(styleLFMnemonic);
409 styleLFCrossPlatformMenuItem = new JMenuItem("Cross Platform");
410 styleLFCrossPlatformMenuItem.setMnemonic(crossPlatformMnemonic);
412 styleLFSystemMenuItem = new JMenuItem("System");
413 styleLFSystemMenuItem.setMnemonic(systemMnemonic);
415 styleLFMenu.add(styleLFCrossPlatformMenuItem);
416 styleLFMenu.add(styleLFSystemMenuItem);
418 styleMenu.add(styleLFMenu);
420 addStyleMenuListeners();
427 * Add listeners to the Style menu.
429 private void addStyleMenuListeners() {
430 styleLFCrossPlatformMenuItem.addActionListener(new ActionListener() {
431 public void actionPerformed(ActionEvent e) {
432 player.setLookAndFeel
433 (UIManager.getCrossPlatformLookAndFeelClassName());
436 styleLFSystemMenuItem.addActionListener(new ActionListener() {
437 public void actionPerformed(ActionEvent e) {
438 player.setLookAndFeel
439 (UIManager.getSystemLookAndFeelClassName());
446 * Creates the Style menu.
448 * @return the Style menu
450 private JMenu createMonitorMenu() {
451 JMenu monitorMenu = new JMenu("Monitor");
452 monitorMenu.setMnemonic(monitorMnemonic);
454 monitorShowMenuItem = new JMenuItem("Show");
455 monitorShowMenuItem.setMnemonic(showMonitorMnemonic);
456 monitorShowMenuItem.setEnabled(!playerModel.isMonitorVisible());
458 monitorHideMenuItem = new JMenuItem("Hide");
459 monitorHideMenuItem.setMnemonic(hideMonitorMnemonic);
460 monitorHideMenuItem.setEnabled(playerModel.isMonitorVisible());
462 monitorMenu.add(monitorShowMenuItem);
463 monitorMenu.add(monitorHideMenuItem);
465 addMonitorMenuListeners();
472 * Add listeners to the monitor menu.
474 private void addMonitorMenuListeners() {
475 monitorShowMenuItem.addActionListener(new ActionListener() {
476 public void actionPerformed(ActionEvent e) {
477 monitorShowMenuItem.setEnabled(false);
478 monitorHideMenuItem.setEnabled(true);
480 player.showMonitor(true);
483 monitorHideMenuItem.addActionListener(new ActionListener() {
484 public void actionPerformed(ActionEvent e) {
485 monitorShowMenuItem.setEnabled(true);
486 monitorHideMenuItem.setEnabled(false);
488 SwingUtilities.invokeLater
491 player.showMonitor(false);
501 * Returns the JFrame which this menu bar belongs to.
503 * @return the JFrame which this menu bar belongs
505 private JFrame getFrame() {
506 return (JFrame) player;
511 * Shows a JFileChooser screen and returns the chosen file.
513 * @return the chosen file
515 private File chooseFile() {
516 int option = fileChooser.showOpenDialog(getParent());
517 if (option == JFileChooser.APPROVE_OPTION) {
518 return fileChooser.getSelectedFile();