/[svn]/jsampler/trunk/src/org/jsampler/view/fantasia/MainFrame.java
ViewVC logotype

Contents of /jsampler/trunk/src/org/jsampler/view/fantasia/MainFrame.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1496 - (show annotations) (download)
Mon Nov 19 22:22:22 2007 UTC (16 years, 5 months ago) by iliev
File size: 18460 byte(s)
* Added option for turning off the custom window decoration
  (choose Edit/Preferences, then click the `View' tab)
* Added new menu item: Help/Online Tutorial
* Fantasia: first step of implementing a theme manager
* Fantasia: fixed the view of the channel's stream/voice count statistic
* some minor GUI fixes and enhancements

1 /*
2 * JSampler - a java front-end for LinuxSampler
3 *
4 * Copyright (C) 2005-2007 Grigor Iliev <grigor@grigoriliev.com>
5 *
6 * This file is part of JSampler.
7 *
8 * JSampler is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2
10 * as published by the Free Software Foundation.
11 *
12 * JSampler is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with JSampler; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 * MA 02111-1307 USA
21 */
22
23 package org.jsampler.view.fantasia;
24
25 import java.awt.BorderLayout;
26 import java.awt.Dialog;
27 import java.awt.Dimension;
28 import java.awt.Frame;
29 import java.awt.Graphics;
30 import java.awt.GridBagConstraints;
31 import java.awt.GridBagLayout;
32 import java.awt.Insets;
33 import java.awt.Point;
34
35 import java.awt.event.ActionEvent;
36 import java.awt.event.ActionListener;
37 import java.awt.event.KeyEvent;
38 import java.awt.event.MouseAdapter;
39 import java.awt.event.MouseEvent;
40
41 import java.io.BufferedReader;
42 import java.io.File;
43 import java.io.FileNotFoundException;
44 import java.io.FileReader;
45
46 import java.util.Vector;
47 import java.util.logging.Level;
48
49 import javax.swing.BorderFactory;
50 import javax.swing.Box;
51 import javax.swing.BoxLayout;
52 import javax.swing.JCheckBoxMenuItem;
53 import javax.swing.JComponent;
54 import javax.swing.JDialog;
55 import javax.swing.JFileChooser;
56 import javax.swing.JFrame;
57 import javax.swing.JMenu;
58 import javax.swing.JMenuBar;
59 import javax.swing.JMenuItem;
60 import javax.swing.JPanel;
61 import javax.swing.JPopupMenu;
62 import javax.swing.JScrollPane;
63 import javax.swing.JSplitPane;
64 import javax.swing.JToggleButton;
65 import javax.swing.KeyStroke;
66 import javax.swing.SwingUtilities;
67 import javax.swing.UIManager;
68
69 import net.sf.juife.TitleBar;
70
71 import org.jsampler.CC;
72 import org.jsampler.HF;
73 import org.jsampler.LSConsoleModel;
74
75 import org.jsampler.view.JSChannel;
76 import org.jsampler.view.JSChannelsPane;
77 import org.jsampler.view.JSMainFrame;
78 import org.jsampler.view.LscpFileFilter;
79
80 import org.jsampler.view.std.JSDetailedErrorDlg;
81 import org.jsampler.view.std.JSamplerHomeChooser;
82
83 import static org.jsampler.view.fantasia.A4n.a4n;
84 import static org.jsampler.view.fantasia.FantasiaI18n.i18n;
85 import static org.jsampler.view.fantasia.FantasiaPrefs.preferences;
86 import static org.jsampler.view.std.StdPrefs.*;
87
88
89 /**
90 *
91 * @author Grigor Iliev
92 */
93 public class MainFrame extends JSMainFrame {
94 private final StandardBar standardBar = new StandardBar();
95 private final FantasiaMenuBar menuBar = new FantasiaMenuBar();
96 private final JPanel rootPane = new JPanel();
97 private final MainPane mainPane = new MainPane();
98 private final DevicesPane devicesPane = new DevicesPane();
99 private final JScrollPane spDevicesPane = new JScrollPane();
100
101 private final JMenu recentScriptsMenu =
102 new JMenu(i18n.getMenuLabel("actions.recentScripts"));
103
104 private final JSplitPane hSplitPane;
105
106 private final SidePane sidePane = new SidePane();
107 private final JPanel rightPane;
108
109 private final LSConsoleFrame lsConsoleFrame = new LSConsoleFrame();
110 private final Vector<String> recentScripts = new Vector<String>();
111
112
113 private final JCheckBoxMenuItem cbmiToolBarVisible =
114 new JCheckBoxMenuItem(i18n.getMenuLabel("view.toolBar"));
115
116 private final JCheckBoxMenuItem cbmiSidePaneVisible =
117 new JCheckBoxMenuItem(i18n.getMenuLabel("view.sidePane"));
118
119 private final JCheckBoxMenuItem cbmiDevicesPaneVisible =
120 new JCheckBoxMenuItem(i18n.getMenuLabel("view.devicesPane"));
121
122 /** Creates a new instance of <code>MainFrame</code> */
123 public
124 MainFrame() {
125 setTitle(i18n.getLabel("MainFrame.title"));
126
127 if(Res.iconAppIcon != null) setIconImage(Res.iconAppIcon.getImage());
128
129 getContentPane().add(standardBar, BorderLayout.NORTH);
130
131 rightPane = createRightPane();
132
133 hSplitPane = new JSplitPane (
134 JSplitPane.HORIZONTAL_SPLIT,
135 true, // continuousLayout
136 sidePane, rightPane
137 );
138 hSplitPane.setResizeWeight(0.5);
139
140 rootPane.setLayout(new BorderLayout());
141 rootPane.setBorder(BorderFactory.createEmptyBorder(6, 0, 0, 0));
142 rootPane.setOpaque(false);
143 rootPane.add(hSplitPane);
144
145 addMenu();
146
147 addChannelsPane(mainPane.getChannelsPane());
148
149 getContentPane().add(rootPane);
150
151 int i = preferences().getIntProperty("MainFrame.hSplitDividerLocation", 220);
152 hSplitPane.setDividerLocation(i);
153
154 setSavedSize();
155 }
156
157 private JPanel
158 createRightPane() {
159 JPanel p = new JPanel();
160 GridBagLayout gridbag = new GridBagLayout();
161 GridBagConstraints c = new GridBagConstraints();
162
163 p.setLayout(gridbag);
164
165 c.fill = GridBagConstraints.BOTH;
166
167 spDevicesPane.setViewportView(devicesPane);
168 spDevicesPane.setBorder(BorderFactory.createEmptyBorder());
169 int h = spDevicesPane.getMinimumSize().height;
170 spDevicesPane.setMinimumSize(new Dimension(200, h));
171
172 c.gridx = 1;
173 c.gridy = 0;
174 c.weightx = 1.0;
175 c.weighty = 1.0;
176 c.insets = new Insets(0, 3, 3, 0);
177 gridbag.setConstraints(spDevicesPane, c);
178 p.add(spDevicesPane);
179
180 c.gridx = 0;
181 c.gridy = 0;
182 c.weightx = 0.0;
183 c.weighty = 1.0;
184 c.insets = new Insets(0, 3, 3, 3);
185 c.fill = GridBagConstraints.VERTICAL;
186 gridbag.setConstraints(mainPane, c);
187 p.add(mainPane);
188
189 return p;
190 }
191
192 private void
193 setSavedSize() {
194 String s = preferences().getStringProperty("MainFrame.sizeAndLocation");
195 if(s == null) {
196 setDefaultSizeAndLocation();
197 return;
198 }
199 pack();
200 try {
201 int i = s.indexOf(',');
202 int x = Integer.parseInt(s.substring(0, i));
203
204 s = s.substring(i + 1);
205 i = s.indexOf(',');
206 int y = Integer.parseInt(s.substring(0, i));
207
208 s = s.substring(i + 1);
209 i = s.indexOf(',');
210 int width = Integer.parseInt(s.substring(0, i));
211
212 s = s.substring(i + 1);
213 int height = Integer.parseInt(s);
214
215 setBounds(x, y, width, height);
216 } catch(Exception x) {
217 String msg = "Parsing of window size and location string failed";
218 CC.getLogger().log(Level.INFO, msg, x);
219 setDefaultSizeAndLocation();
220 }
221
222 if(preferences().getBoolProperty("MainFrame.windowMaximized")) {
223 setExtendedState(getExtendedState() | MAXIMIZED_BOTH);
224 }
225 }
226
227 private void
228 setDefaultSizeAndLocation() {
229 setPreferredSize(new Dimension(900, 600));
230 pack();
231 setLocationRelativeTo(null);
232 }
233
234
235 /** Invoked when this window is about to close. */
236 protected void
237 onWindowClose() {
238 sidePane.savePreferences();
239
240 int i = hSplitPane.getDividerLocation();
241 preferences().setIntProperty("MainFrame.hSplitDividerLocation", i);
242
243 preferences().setBoolProperty (
244 "MainFrame.windowMaximized",
245 (getExtendedState() & MAXIMIZED_BOTH) == MAXIMIZED_BOTH
246 );
247
248 if(preferences().getBoolProperty("MainFrame.windowMaximized")) {
249 super.onWindowClose();
250 return;
251 }
252
253 java.awt.Point p = getLocation();
254 Dimension d = getSize();
255 StringBuffer sb = new StringBuffer();
256 sb.append(p.x).append(',').append(p.y).append(',');
257 sb.append(d.width).append(',').append(d.height);
258 preferences().setStringProperty("MainFrame.sizeAndLocation", sb.toString());
259
260 String[] list = recentScripts.toArray(new String[recentScripts.size()]);
261 preferences().setStringListProperty(RECENT_LSCP_SCRIPTS, list);
262
263 if(preferences().getBoolProperty(SAVE_LS_CONSOLE_HISTORY)) {
264 if(lsConsoleFrame != null) getLSConsolePane().saveConsoleHistory();
265 }
266
267 super.onWindowClose();
268 }
269
270 private void
271 addMenu() {
272 JMenu m;
273 JMenuItem mi;
274
275 setJMenuBar(menuBar);
276
277 // Actions
278 m = new FantasiaMenu(i18n.getMenuLabel("actions"));
279
280 mi = new JMenuItem(a4n.connect);
281 mi.setIcon(null);
282 //mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, KeyEvent.CTRL_MASK));
283 m.add(mi);
284
285 mi = new JMenuItem(a4n.samplerInfo);
286 mi.setIcon(null);
287 m.add(mi);
288
289 m.addSeparator();
290
291 JMenu exportMenu = new JMenu(i18n.getMenuLabel("actions.export"));
292 m.add(exportMenu);
293
294 mi = new JMenuItem(a4n.exportSamplerConfig);
295 mi.setIcon(null);
296 mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.CTRL_MASK));
297 exportMenu.add(mi);
298
299 mi = new JMenuItem(a4n.exportMidiInstrumentMaps);
300 mi.setIcon(null);
301 exportMenu.add(mi);
302
303 m.addSeparator();
304
305 mi = new JMenuItem(a4n.loadScript);
306 mi.setIcon(null);
307 m.add(mi);
308
309 String[] list = preferences().getStringListProperty(RECENT_LSCP_SCRIPTS);
310 for(String s : list) recentScripts.add(s);
311
312 updateRecentScriptsMenu();
313
314 m.add(recentScriptsMenu);
315
316 m.addSeparator();
317
318 mi = new JMenuItem(i18n.getMenuLabel("actions.exit"));
319 m.add(mi);
320 mi.addActionListener(new ActionListener() {
321 public void
322 actionPerformed(ActionEvent e) { onWindowClose(); }
323 });
324
325 menuBar.add(m);
326
327
328 // Edit
329 m = new FantasiaMenu(i18n.getMenuLabel("edit"));
330 menuBar.add(m);
331
332 mi = new JMenuItem(i18n.getMenuLabel("edit.addChannel"));
333 m.add(mi);
334 mi.addActionListener(new ActionListener() {
335 public void
336 actionPerformed(ActionEvent e) {
337 CC.getSamplerModel().addBackendChannel();
338 }
339 });
340
341 m.addSeparator();
342
343 mi = new JMenuItem(a4n.createMidiDevice);
344 mi.setIcon(null);
345 m.add(mi);
346
347 mi = new JMenuItem(a4n.createAudioDevice);
348 mi.setIcon(null);
349 m.add(mi);
350
351 m.addSeparator();
352
353 mi = new JMenuItem(a4n.editPreferences);
354 mi.setIcon(null);
355 mi.setAccelerator(KeyStroke.getKeyStroke (
356 KeyEvent.VK_P, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK
357 ));
358 m.add(mi);
359
360 // View
361 m = new FantasiaMenu(i18n.getMenuLabel("view"));
362 menuBar.add(m);
363
364 m.add(cbmiToolBarVisible);
365
366 cbmiToolBarVisible.addActionListener(new ActionListener() {
367 public void
368 actionPerformed(ActionEvent e) {
369 showToolBar(cbmiToolBarVisible.getState());
370 }
371 });
372
373 boolean b = preferences().getBoolProperty("toolBar.visible");
374 cbmiToolBarVisible.setSelected(b);
375 showToolBar(b);
376
377 cbmiSidePaneVisible.setAccelerator(KeyStroke.getKeyStroke (
378 KeyEvent.VK_L, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK
379 ));
380 m.add(cbmiSidePaneVisible);
381
382 cbmiSidePaneVisible.addActionListener(new ActionListener() {
383 public void
384 actionPerformed(ActionEvent e) {
385 showSidePane(cbmiSidePaneVisible.getState());
386 }
387 });
388
389 b = preferences().getBoolProperty("sidePane.visible");
390 cbmiSidePaneVisible.setSelected(b);
391 showSidePane(b);
392
393 cbmiDevicesPaneVisible.setAccelerator(KeyStroke.getKeyStroke (
394 KeyEvent.VK_R, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK
395 ));
396 m.add(cbmiDevicesPaneVisible);
397
398 cbmiDevicesPaneVisible.addActionListener(new ActionListener() {
399 public void
400 actionPerformed(ActionEvent e) {
401 showDevicesPane(cbmiDevicesPaneVisible.getState());
402 }
403 });
404
405 b = preferences().getBoolProperty("devicesPane.visible");
406 cbmiDevicesPaneVisible.setSelected(b);
407 showDevicesPane(b);
408
409
410 // Window
411 m = new FantasiaMenu(i18n.getMenuLabel("window"));
412 menuBar.add(m);
413
414 mi = new JMenuItem(a4n.windowLSConsole);
415 mi.setIcon(null);
416 m.add(mi);
417
418 mi = new JMenuItem(a4n.windowInstrumentsDb);
419 mi.setIcon(null);
420 m.add(mi);
421
422
423 // Help
424 m = new FantasiaMenu(i18n.getMenuLabel("help"));
425
426 mi = new JMenuItem(a4n.browseOnlineTutorial);
427 mi.setIcon(null);
428 m.add(mi);
429
430 m.addSeparator();
431
432 mi = new JMenuItem(a4n.helpAbout);
433 mi.setIcon(null);
434 m.add(mi);
435
436 menuBar.add(m);
437 }
438
439 /**
440 * This method does nothing, because <b>Fantasia</b> has exactly
441 * one pane containing sampler channels, which can not be changed.
442 */
443 public void
444 insertChannelsPane(JSChannelsPane pane, int idx) {
445
446 }
447
448 /**
449 * This method always returns the <code>JSChannelsPane</code> at index 0,
450 * because the <b>Fantasia</b> view has exactly one pane containing sampler channels.
451 * @return The <code>JSChannelsPane</code> at index 0.
452 */
453 public JSChannelsPane
454 getSelectedChannelsPane() { return getChannelsPane(0); }
455
456 /**
457 * This method does nothing because the <b>Fantasia</b> view has
458 * exactly one pane containing sampler channels which is always shown.
459 */
460 public void
461 setSelectedChannelsPane(JSChannelsPane pane) { }
462
463 public void
464 installJSamplerHome() {
465 JSamplerHomeChooser chooser = new JSamplerHomeChooser(this);
466 chooser.setVisible(true);
467 if(chooser.isCancelled()) return;
468
469 CC.changeJSamplerHome(chooser.getJSamplerHome());
470 }
471
472 public void
473 showDetailedErrorMessage(Frame owner, String err, String details) {
474 JSDetailedErrorDlg dlg = new JSDetailedErrorDlg (
475 owner, Res.iconWarning32, i18n.getError("error"), err, details
476 );
477 dlg.setVisible(true);
478 }
479
480 public void
481 showDetailedErrorMessage(Dialog owner, String err, String details) {
482 JSDetailedErrorDlg dlg = new JSDetailedErrorDlg (
483 owner, Res.iconWarning32, i18n.getError("error"), err, details
484 );
485 dlg.setVisible(true);
486 }
487
488 protected LSConsoleModel
489 getLSConsoleModel() { return getLSConsolePane().getModel(); }
490
491 protected LSConsolePane
492 getLSConsolePane() {
493 return getLSConsoleFrame().getLSConsolePane();
494 }
495
496 protected LSConsoleFrame
497 getLSConsoleFrame() { return lsConsoleFrame; }
498
499 protected void
500 runScript() {
501 String s = preferences().getStringProperty("lastScriptLocation");
502 JFileChooser fc = new JFileChooser(s);
503 fc.setFileFilter(new LscpFileFilter());
504 int result = fc.showOpenDialog(this);
505 if(result != JFileChooser.APPROVE_OPTION) return;
506
507 String path = fc.getCurrentDirectory().getAbsolutePath();
508 preferences().setStringProperty("lastScriptLocation", path);
509
510 runScript(fc.getSelectedFile());
511 }
512
513 private void
514 runScript(String script) { runScript(new File(script)); }
515
516 private void
517 runScript(File script) {
518 FileReader fr;
519 try { fr = new FileReader(script); }
520 catch(FileNotFoundException e) {
521 HF.showErrorMessage(i18n.getMessage("FileNotFound!"));
522 return;
523 }
524
525 BufferedReader br = new BufferedReader(fr);
526
527 try {
528 String s = br.readLine();
529 while(s != null) {
530 getLSConsoleModel().setCommandLineText(s);
531 getLSConsoleModel().execCommand();
532 s = br.readLine();
533 }
534 } catch(Exception e) {
535 HF.showErrorMessage(e);
536 return;
537 }
538
539 String s = script.getAbsolutePath();
540 recentScripts.remove(s);
541 recentScripts.insertElementAt(s, 0);
542
543 updateRecentScriptsMenu();
544 }
545
546 protected void
547 clearRecentScripts() {
548 recentScripts.removeAllElements();
549 updateRecentScriptsMenu();
550 }
551
552 protected void
553 updateRecentScriptsMenu() {
554 int size = preferences().getIntProperty(RECENT_LSCP_SCRIPTS_SIZE);
555 while(recentScripts.size() > size) {
556 recentScripts.removeElementAt(recentScripts.size() - 1);
557 }
558
559 recentScriptsMenu.removeAll();
560
561 for(String script : recentScripts) {
562 JMenuItem mi = new JMenuItem(script);
563 recentScriptsMenu.add(mi);
564 mi.addActionListener(new RecentScriptHandler(script));
565 }
566
567 recentScriptsMenu.setEnabled(recentScripts.size() != 0);
568 }
569
570 private void
571 showToolBar(boolean b) {
572 preferences().setBoolProperty("toolBar.visible", b);
573 standardBar.setVisible(b);
574 }
575
576 private void
577 showSidePane(boolean b) {
578 preferences().setBoolProperty("sidePane.visible", b);
579 rootPane.remove(rightPane);
580 rootPane.remove(hSplitPane);
581
582 if(b) {
583 hSplitPane.setRightComponent(rightPane);
584 rootPane.add(hSplitPane);
585 int i = preferences().getIntProperty("MainFrame.hSplitDividerLocation", 220);
586
587 hSplitPane.setDividerLocation(i);
588 hSplitPane.validate();
589 } else {
590 rootPane.add(rightPane);
591
592 }
593
594 int w = getPreferredSize().width;
595 int h = getSize().height;
596 setSize(new Dimension(w, h));
597
598 rootPane.revalidate();
599 rootPane.validate();
600 rootPane.repaint();
601
602 SwingUtilities.invokeLater(new Runnable() {
603 public void
604 run() { sidePanesVisibilityChanged(); }
605 });
606 }
607
608 private void
609 showDevicesPane(boolean b) {
610 preferences().setBoolProperty("devicesPane.visible", b);
611
612 int width = sidePane.getWidth();
613 int height = sidePane.getPreferredSize().height;
614 if(width != 0) sidePane.setPreferredSize(new Dimension(width, height));
615
616 if(b) {
617 int w = preferences().getIntProperty("devicesPane.width", 200);
618
619 int h = spDevicesPane.getPreferredSize().height;
620 spDevicesPane.setPreferredSize(new Dimension(w, h));
621 } else {
622 int w = spDevicesPane.getWidth();
623 if(w > 0 && w < 200) w = 200;
624 if(w != 0) preferences().setIntProperty("devicesPane.width", w);
625 }
626
627 hSplitPane.setResizeWeight(0.0);
628 spDevicesPane.setVisible(b);
629 hSplitPane.resetToPreferredSizes();
630
631 int w = getPreferredSize().width;
632 int h = getSize().height;
633 setSize(new Dimension(w, h));
634
635 rootPane.validate();
636 rootPane.repaint();
637 //hSplitPane.validate();
638
639 SwingUtilities.invokeLater(new Runnable() {
640 public void
641 run() { sidePanesVisibilityChanged(); }
642 });
643 }
644
645 private void
646 sidePanesVisibilityChanged() {
647 boolean sidePaneVisible = cbmiSidePaneVisible.isSelected();
648 boolean devicesPaneVisible = cbmiDevicesPaneVisible.isSelected();
649
650 if(sidePaneVisible && devicesPaneVisible) {
651 hSplitPane.setResizeWeight(0.5);
652 } else if(sidePaneVisible && !devicesPaneVisible) {
653 hSplitPane.setResizeWeight(1.0);
654 }
655
656 if(!sidePaneVisible && !devicesPaneVisible) {
657 standardBar.showFantasiaLogo(false);
658 if(isResizable()) setResizable(false);
659 } else {
660 standardBar.showFantasiaLogo(true);
661 if(!isResizable()) setResizable(true);
662 }
663 }
664
665 private class RecentScriptHandler implements ActionListener {
666 private String script;
667
668 RecentScriptHandler(String script) { this.script = script; }
669
670 public void
671 actionPerformed(ActionEvent e) {
672 runScript(script);
673 if(preferences().getBoolProperty(SHOW_LS_CONSOLE_WHEN_RUN_SCRIPT)) {
674 a4n.windowLSConsole.actionPerformed(null);
675 }
676 }
677 }
678
679 private static class FantasiaMenu extends JMenu {
680 FantasiaMenu(String s) {
681 super(s);
682 setFont(getFont().deriveFont(java.awt.Font.BOLD));
683 setOpaque(false);
684 }
685 }
686
687 private class FantasiaMenuBar extends JMenuBar {
688 private Insets pixmapInsets = new Insets(6, 6, 0, 6);
689 private Insets pixmapInsets2 = new Insets(6, 6, 6, 6);
690
691 FantasiaMenuBar() {
692 setOpaque(false);
693 }
694
695 protected void
696 paintComponent(Graphics g) {
697 super.paintComponent(g);
698 if(standardBar.isVisible()) {
699 PixmapPane.paintComponent(this, g, Res.gfxMenuBarBg, pixmapInsets);
700 } else {
701 PixmapPane.paintComponent(this, g, Res.gfxRoundBg14, pixmapInsets2);
702 }
703 }
704 }
705 }

  ViewVC Help
Powered by ViewVC