/[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 1567 - (show annotations) (download)
Thu Dec 6 19:37:41 2007 UTC (16 years, 4 months ago) by iliev
File size: 18661 byte(s)
* added confirmation dialog on exit
* some minor gui enhancements
* preparations for release 0.8a

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

  ViewVC Help
Powered by ViewVC