upstream version 1.2.2
[debian/freetts] / demo / JSAPI / Player / Player.java
1 /**
2  * Copyright 2001 Sun Microsystems, Inc.
3  * 
4  * See the file "license.terms" for information on usage and
5  * redistribution of this file, and for a DISCLAIMER OF ALL 
6  * WARRANTIES.
7  */
8 import java.awt.BorderLayout;
9 import java.awt.Component;
10 import java.awt.Dimension;
11 import java.awt.Font;
12 import java.awt.event.ActionEvent;
13 import java.awt.event.ActionListener;
14 import java.awt.event.WindowAdapter;
15 import java.awt.event.WindowEvent;
16
17 import java.io.File;
18
19 import javax.speech.synthesis.SynthesizerModeDesc;
20 import javax.speech.synthesis.Voice;
21
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;
32
33 public class Player extends JFrame {
34
35     private PlayerModel playerModel;
36     private PlayerPanel playerPanel;
37     private PlayerMenuBar playerMenuBar;
38
39     private Font globalFont;
40     private String globalFontFace = "Arial";
41     
42             
43     /**
44      * Constructs a Player with the given title.
45      *
46      * @param title the title of the Player
47      */
48     public Player(String title) {
49         super(title);
50
51         setDefaultLookAndFeelDecorated(true);
52         addWindowListener(new WindowAdapter() {
53                 public void windowClosing(WindowEvent e) {
54                     playerModel.close();
55                     System.exit(0);
56                 }
57             });
58
59         playerModel = new PlayerModelImpl();
60         playerPanel = new PlayerPanel(playerModel);
61         setSize(playerPanel.getSize());
62         getContentPane().add(playerPanel, BorderLayout.CENTER);
63     }
64
65
66     /**
67      * Returns the view model of this Player application.
68      *
69      * @return the view model
70      */
71     public PlayerPanel getView() {
72         return playerPanel;
73     }
74     
75
76     /**
77      * Returns the data model of this Player application.
78      *
79      * @return the data model
80      */
81     public PlayerModel getModel() {
82         return playerModel;
83     }
84     
85
86     /**
87      * Sets the menubar for this Player.
88      *
89      * @param menubar the menubar
90      */
91     public void setMenuBar(PlayerMenuBar menubar) {
92         playerMenuBar = menubar;
93         setJMenuBar(playerMenuBar);
94     }
95
96
97     /**
98      * Show/hide the current monitor from the applcation frame.
99      *
100      * @param show true to show, false to hide
101      */
102     public void showMonitor(boolean show) {
103         Monitor monitor = playerModel.getMonitor();
104         int newHeight = getSize().height;
105         int monitorHeight = monitor.getSize().height;
106
107         if (show) {
108             playerPanel.add(monitor, BorderLayout.SOUTH);
109             newHeight += monitorHeight;
110         } else {
111             playerPanel.remove(monitor);
112             newHeight -= monitorHeight;
113         }
114
115         Dimension newSize = new Dimension(getSize().width, newHeight);
116         playerPanel.setSize(newSize);
117         setSize(newSize);
118
119         playerModel.setMonitorVisible(show);
120         repaint();
121     }
122
123
124     /**
125      * Changes the font size of all components in this Player.
126      * 
127      * @param change the change in font size
128      */
129     public void setGlobalFontSize(int fontSize) {
130         if (globalFont == null) {
131             globalFont = getFont();
132         }
133         globalFont = new Font(globalFontFace, Font.BOLD, fontSize);
134                 
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);
144
145         setFont(globalFont);
146         
147         SwingUtilities.updateComponentTreeUI(this);
148         repaint();
149     }
150
151
152     /**
153      * A convenience method for setting the Look & Feel.
154      *
155      * @param lookAndFeel the Look & Feel specification
156      */
157     public void setLookAndFeel(Object lookAndFeel) {
158         try {
159             if (lookAndFeel instanceof String) {
160                 UIManager.setLookAndFeel((String) lookAndFeel);
161             } else if (lookAndFeel instanceof LookAndFeel) {
162                 UIManager.setLookAndFeel((LookAndFeel) lookAndFeel);
163             }
164
165             SwingUtilities.updateComponentTreeUI(this);
166             repaint();
167         } catch (Exception ex) {
168             ex.printStackTrace();
169         }
170     }
171
172     /**
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.
175      */
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);
186                     model.setVoice(j);
187                     break;
188                 }
189             }
190         }
191     }
192     
193
194     /**
195      * The main() method of the Player.
196      */
197     public static void main(String[] args) throws Exception {
198         boolean showMonitor = false;
199         String firstVoice = "kevin16";
200         
201         Player player = new Player("FreeTTS Player");
202
203         for (int i = 0; i < args.length; i++) {
204             if (args[i].equals("-voice")) {
205                 if (++i < args.length) {
206                     firstVoice = args[i];
207                 }
208             } else if (args[i].equals("-fontsize")) {
209                 if (++i < args.length) {
210                     player.setGlobalFontSize(Integer.parseInt(args[i]));
211                 }
212             } else if (args[i].equals("-monitor")) {
213                 showMonitor = true;
214             } else if (args[i].equals("-input")) {
215
216                 PlayerModel model = player.getModel();
217
218                 for (i++; i < args.length; i++) {
219                     int start = args[i].indexOf(':');
220                     if (start > -1) {
221                         String content = args[i].substring(start+1);
222                         System.out.println(content);
223                         if (args[i].startsWith("plaintext:")) {
224                             model.addPlayable
225                                 (Playable.createTextPlayable(content));
226                         } else if (args[i].startsWith("textfile:")) {
227                             model.addPlayable
228                                 (Playable.createTextFilePlayable
229                                  (new File(content)));
230                         } else if (args[i].startsWith("jsmltext:")) {
231                             model.addPlayable
232                                 (Playable.createJSMLPlayable(content));
233                         } else if (args[i].startsWith("jsmlfile:")) {
234                             model.addPlayable
235                                 (Playable.createJSMLFilePlayable
236                                  (new File(content)));
237                         }
238                     }
239                 }
240             }
241         }
242
243         player.setMenuBar(new PlayerMenuBar(player));
244         player.getModel().createSynthesizers();
245         player.setVoice(firstVoice);
246         
247         player.show();
248
249         if (showMonitor) {
250             player.showMonitor(showMonitor);
251         }
252     }
253 }
254
255 /**
256  * Implements the menubar of the Player application.
257  */
258 class PlayerMenuBar extends JMenuBar {
259     private Player player;
260     private PlayerModel playerModel;
261
262     private JFileChooser fileChooser;
263     
264     private JMenuItem fileSpeakJSMLMenuItem;
265     private JMenuItem fileSpeakTextMenuItem;
266     private JMenuItem fileSpeakURLMenuItem;
267     private JMenuItem fileExitMenuItem;
268
269     private JMenuItem styleLFCrossPlatformMenuItem;
270     private JMenuItem styleLFSystemMenuItem;
271     private JMenuItem styleFontSizeLargerMenuItem;
272     private JMenuItem styleFontSizeSmallerMenuItem;
273
274     private JMenuItem monitorHideMenuItem;
275     private JMenuItem monitorShowMenuItem;
276                 
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';
290
291
292     /**
293      * Constructs a menubar with the given Player data model.
294      *
295      * @param playerModel the Player data model
296      */
297     public PlayerMenuBar(Player player) {
298         super();
299         this.player = player;
300         this.playerModel = player.getModel();
301         this.fileChooser = new JFileChooser();
302         fileChooser.setCurrentDirectory
303             (new File(System.getProperty("user.dir")));
304
305         add(createFileMenu());
306         add(createStyleMenu());
307         add(createMonitorMenu());
308     }
309
310
311     /**
312      * Creates the File menu.
313      *
314      * @return the File menu
315      */
316     private JMenu createFileMenu() {
317         JMenu fileMenu = new JMenu("File");
318         fileMenu.setMnemonic(fileMnemonic);
319         add(fileMenu);
320         
321         JMenu fileSpeakMenu = new JMenu("Speak");
322         fileSpeakMenu.setMnemonic(speakMnemonic);
323         
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);
330                 
331         fileSpeakMenu.add(fileSpeakJSMLMenuItem);
332         fileSpeakMenu.add(fileSpeakTextMenuItem);
333         fileSpeakMenu.add(fileSpeakURLMenuItem);
334                                 
335         fileExitMenuItem = new JMenuItem("Exit");
336         fileExitMenuItem.setMnemonic(exitMnemonic);
337         
338         fileMenu.add(fileSpeakMenu);
339         fileMenu.addSeparator();
340         fileMenu.add(fileExitMenuItem);
341         
342         addFileMenuListeners();
343         
344         return fileMenu;
345     }
346
347
348     /**
349      * Adds the given Playaable to the play list, and plays it.
350      */
351     private void playPlayable(Playable playable) {
352         playerModel.addPlayable(playable);
353         player.getView().getPlayList().setSelectedValue(playable, true);
354         playerModel.play(playable);
355     }
356
357
358     /**
359      * Add listenrs to the file menu.
360      */
361     private void addFileMenuListeners() {
362         fileExitMenuItem.addActionListener(new ActionListener() {
363                 public void actionPerformed(ActionEvent e) {
364                     playerModel.close();
365                     System.exit(0);
366                 }
367             });
368         fileSpeakJSMLMenuItem.addActionListener(new ActionListener() {
369                 public void actionPerformed(ActionEvent e) {
370                     File file = chooseFile();
371                     if (file != null) {
372                         playPlayable(Playable.createJSMLFilePlayable(file));
373                     }
374                 }
375             });
376         fileSpeakTextMenuItem.addActionListener(new ActionListener() {
377                 public void actionPerformed(ActionEvent e) {
378                     File file = chooseFile();
379                     if (file != null) {
380                         playPlayable(Playable.createTextFilePlayable(file));
381                     }
382                 }
383             });
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));
391                     }
392                 }
393             });
394     }
395
396
397     /**
398      * Creates the Style menu.
399      *
400      * @return the Style menu
401      */
402     private JMenu createStyleMenu() {
403         JMenu styleMenu = new JMenu("Style");
404         styleMenu.setMnemonic(styleMnemonic);
405         
406         JMenu styleLFMenu = new JMenu("Look & Feel");
407         styleLFMenu.setMnemonic(styleLFMnemonic);
408         
409         styleLFCrossPlatformMenuItem = new JMenuItem("Cross Platform");
410         styleLFCrossPlatformMenuItem.setMnemonic(crossPlatformMnemonic);
411         
412         styleLFSystemMenuItem = new JMenuItem("System");
413         styleLFSystemMenuItem.setMnemonic(systemMnemonic);
414         
415         styleLFMenu.add(styleLFCrossPlatformMenuItem);
416         styleLFMenu.add(styleLFSystemMenuItem);
417         
418         styleMenu.add(styleLFMenu);
419         
420         addStyleMenuListeners();
421         
422         return styleMenu;
423     }
424
425
426     /**
427      * Add listeners to the Style menu.
428      */
429     private void addStyleMenuListeners() {
430         styleLFCrossPlatformMenuItem.addActionListener(new ActionListener() {
431                 public void actionPerformed(ActionEvent e) {
432                     player.setLookAndFeel
433                         (UIManager.getCrossPlatformLookAndFeelClassName());
434                 }
435             });
436         styleLFSystemMenuItem.addActionListener(new ActionListener() {
437                 public void actionPerformed(ActionEvent e) {
438                     player.setLookAndFeel
439                         (UIManager.getSystemLookAndFeelClassName());
440                 }
441             });
442     }
443
444
445     /**
446      * Creates the Style menu.
447      *
448      * @return the Style menu
449      */
450     private JMenu createMonitorMenu() {
451         JMenu monitorMenu = new JMenu("Monitor");
452         monitorMenu.setMnemonic(monitorMnemonic);
453         
454         monitorShowMenuItem = new JMenuItem("Show");
455         monitorShowMenuItem.setMnemonic(showMonitorMnemonic);
456         monitorShowMenuItem.setEnabled(!playerModel.isMonitorVisible());
457                 
458         monitorHideMenuItem = new JMenuItem("Hide");
459         monitorHideMenuItem.setMnemonic(hideMonitorMnemonic);
460         monitorHideMenuItem.setEnabled(playerModel.isMonitorVisible());
461                 
462         monitorMenu.add(monitorShowMenuItem);
463         monitorMenu.add(monitorHideMenuItem);
464                 
465         addMonitorMenuListeners();
466         
467         return monitorMenu;
468     }
469
470
471     /**
472      * Add listeners to the monitor menu.
473      */
474     private void addMonitorMenuListeners() {
475         monitorShowMenuItem.addActionListener(new ActionListener() {
476                 public void actionPerformed(ActionEvent e) {
477                     monitorShowMenuItem.setEnabled(false);
478                     monitorHideMenuItem.setEnabled(true);
479
480                     player.showMonitor(true);
481                 }
482             });
483         monitorHideMenuItem.addActionListener(new ActionListener() {
484                 public void actionPerformed(ActionEvent e) {
485                     monitorShowMenuItem.setEnabled(true);
486                     monitorHideMenuItem.setEnabled(false);
487         
488                     SwingUtilities.invokeLater
489                         (new Runnable() {
490                                 public void run() {
491                                     player.showMonitor(false);
492                                 }
493                             });
494                 }
495             });
496     }
497     
498
499
500     /**
501      * Returns the JFrame which this menu bar belongs to.
502      *
503      * @return the JFrame which this menu bar belongs
504      */
505     private JFrame getFrame() {
506         return (JFrame) player;
507     }
508
509
510     /**
511      * Shows a JFileChooser screen and returns the chosen file.
512      *
513      * @return the chosen file
514      */
515     private File chooseFile() {
516         int option = fileChooser.showOpenDialog(getParent());
517         if (option == JFileChooser.APPROVE_OPTION) {
518             return fileChooser.getSelectedFile();
519         } else {
520             return null;
521         }
522     }
523 }
524