/[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 1355 - (show annotations) (download)
Mon Sep 17 23:55:27 2007 UTC (16 years, 7 months ago) by iliev
File size: 18353 byte(s)
* Added support for formatting the instruments database
* Now database instruments and directories can have multiline descriptions
* Fantasia: added detailed error dialog

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.helpAbout);
427 mi.setIcon(null);
428 m.add(mi);
429
430 menuBar.add(m);
431 }
432
433 /**
434 * This method does nothing, because <b>Fantasia</b> has exactly
435 * one pane containing sampler channels, which can not be changed.
436 */
437 public void
438 insertChannelsPane(JSChannelsPane pane, int idx) {
439
440 }
441
442 /**
443 * This method always returns the <code>JSChannelsPane</code> at index 0,
444 * because the <b>Fantasia</b> view has exactly one pane containing sampler channels.
445 * @return The <code>JSChannelsPane</code> at index 0.
446 */
447 public JSChannelsPane
448 getSelectedChannelsPane() { return getChannelsPane(0); }
449
450 /**
451 * This method does nothing because the <b>Fantasia</b> view has
452 * exactly one pane containing sampler channels which is always shown.
453 */
454 public void
455 setSelectedChannelsPane(JSChannelsPane pane) { }
456
457 public void
458 installJSamplerHome() {
459 JSamplerHomeChooser chooser = new JSamplerHomeChooser(this);
460 chooser.setVisible(true);
461 if(chooser.isCancelled()) return;
462
463 CC.changeJSamplerHome(chooser.getJSamplerHome());
464 }
465
466 public void
467 showDetailedErrorMessage(Frame owner, String err, String details) {
468 JSDetailedErrorDlg dlg = new JSDetailedErrorDlg (
469 owner, Res.iconWarning32, i18n.getError("error"), err, details
470 );
471 dlg.setVisible(true);
472 }
473
474 public void
475 showDetailedErrorMessage(Dialog owner, String err, String details) {
476 JSDetailedErrorDlg dlg = new JSDetailedErrorDlg (
477 owner, Res.iconWarning32, i18n.getError("error"), err, details
478 );
479 dlg.setVisible(true);
480 }
481
482 protected LSConsoleModel
483 getLSConsoleModel() { return getLSConsolePane().getModel(); }
484
485 protected LSConsolePane
486 getLSConsolePane() {
487 return getLSConsoleFrame().getLSConsolePane();
488 }
489
490 protected LSConsoleFrame
491 getLSConsoleFrame() { return lsConsoleFrame; }
492
493 protected void
494 runScript() {
495 String s = preferences().getStringProperty("lastScriptLocation");
496 JFileChooser fc = new JFileChooser(s);
497 fc.setFileFilter(new LscpFileFilter());
498 int result = fc.showOpenDialog(this);
499 if(result != JFileChooser.APPROVE_OPTION) return;
500
501 String path = fc.getCurrentDirectory().getAbsolutePath();
502 preferences().setStringProperty("lastScriptLocation", path);
503
504 runScript(fc.getSelectedFile());
505 }
506
507 private void
508 runScript(String script) { runScript(new File(script)); }
509
510 private void
511 runScript(File script) {
512 FileReader fr;
513 try { fr = new FileReader(script); }
514 catch(FileNotFoundException e) {
515 HF.showErrorMessage(i18n.getMessage("FileNotFound!"));
516 return;
517 }
518
519 BufferedReader br = new BufferedReader(fr);
520
521 try {
522 String s = br.readLine();
523 while(s != null) {
524 getLSConsoleModel().setCommandLineText(s);
525 getLSConsoleModel().execCommand();
526 s = br.readLine();
527 }
528 } catch(Exception e) {
529 HF.showErrorMessage(e);
530 return;
531 }
532
533 String s = script.getAbsolutePath();
534 recentScripts.remove(s);
535 recentScripts.insertElementAt(s, 0);
536
537 updateRecentScriptsMenu();
538 }
539
540 protected void
541 clearRecentScripts() {
542 recentScripts.removeAllElements();
543 updateRecentScriptsMenu();
544 }
545
546 protected void
547 updateRecentScriptsMenu() {
548 int size = preferences().getIntProperty(RECENT_LSCP_SCRIPTS_SIZE);
549 while(recentScripts.size() > size) {
550 recentScripts.removeElementAt(recentScripts.size() - 1);
551 }
552
553 recentScriptsMenu.removeAll();
554
555 for(String script : recentScripts) {
556 JMenuItem mi = new JMenuItem(script);
557 recentScriptsMenu.add(mi);
558 mi.addActionListener(new RecentScriptHandler(script));
559 }
560
561 recentScriptsMenu.setEnabled(recentScripts.size() != 0);
562 }
563
564 private void
565 showToolBar(boolean b) {
566 preferences().setBoolProperty("toolBar.visible", b);
567 standardBar.setVisible(b);
568 }
569
570 private void
571 showSidePane(boolean b) {
572 preferences().setBoolProperty("sidePane.visible", b);
573 rootPane.remove(rightPane);
574 rootPane.remove(hSplitPane);
575
576 if(b) {
577 hSplitPane.setRightComponent(rightPane);
578 rootPane.add(hSplitPane);
579 int i = preferences().getIntProperty("MainFrame.hSplitDividerLocation", 220);
580
581 hSplitPane.setDividerLocation(i);
582 hSplitPane.validate();
583 } else {
584 rootPane.add(rightPane);
585
586 }
587
588 int w = getPreferredSize().width;
589 int h = getSize().height;
590 setSize(new Dimension(w, h));
591
592 rootPane.revalidate();
593 rootPane.validate();
594 rootPane.repaint();
595
596 SwingUtilities.invokeLater(new Runnable() {
597 public void
598 run() { sidePanesVisibilityChanged(); }
599 });
600 }
601
602 private void
603 showDevicesPane(boolean b) {
604 preferences().setBoolProperty("devicesPane.visible", b);
605
606 int width = sidePane.getWidth();
607 int height = sidePane.getPreferredSize().height;
608 if(width != 0) sidePane.setPreferredSize(new Dimension(width, height));
609
610 if(b) {
611 int w = preferences().getIntProperty("devicesPane.width", 200);
612
613 int h = spDevicesPane.getPreferredSize().height;
614 spDevicesPane.setPreferredSize(new Dimension(w, h));
615 } else {
616 int w = spDevicesPane.getWidth();
617 if(w > 0 && w < 200) w = 200;
618 if(w != 0) preferences().setIntProperty("devicesPane.width", w);
619 }
620
621 hSplitPane.setResizeWeight(0.0);
622 spDevicesPane.setVisible(b);
623 hSplitPane.resetToPreferredSizes();
624
625 int w = getPreferredSize().width;
626 int h = getSize().height;
627 setSize(new Dimension(w, h));
628
629 rootPane.validate();
630 rootPane.repaint();
631 //hSplitPane.validate();
632
633 SwingUtilities.invokeLater(new Runnable() {
634 public void
635 run() { sidePanesVisibilityChanged(); }
636 });
637 }
638
639 private void
640 sidePanesVisibilityChanged() {
641 boolean sidePaneVisible = cbmiSidePaneVisible.isSelected();
642 boolean devicesPaneVisible = cbmiDevicesPaneVisible.isSelected();
643
644 if(sidePaneVisible && devicesPaneVisible) {
645 hSplitPane.setResizeWeight(0.5);
646 } else if(sidePaneVisible && !devicesPaneVisible) {
647 hSplitPane.setResizeWeight(1.0);
648 }
649
650 if(!sidePaneVisible && !devicesPaneVisible) {
651 standardBar.showFantasiaLogo(false);
652 if(isResizable()) setResizable(false);
653 } else {
654 standardBar.showFantasiaLogo(true);
655 if(!isResizable()) setResizable(true);
656 }
657 }
658
659 private class RecentScriptHandler implements ActionListener {
660 private String script;
661
662 RecentScriptHandler(String script) { this.script = script; }
663
664 public void
665 actionPerformed(ActionEvent e) {
666 runScript(script);
667 if(preferences().getBoolProperty(SHOW_LS_CONSOLE_WHEN_RUN_SCRIPT)) {
668 a4n.windowLSConsole.actionPerformed(null);
669 }
670 }
671 }
672
673 private static class FantasiaMenu extends JMenu {
674 FantasiaMenu(String s) {
675 super(s);
676 setFont(getFont().deriveFont(java.awt.Font.BOLD));
677 setOpaque(false);
678 }
679 }
680
681 private class FantasiaMenuBar extends JMenuBar {
682 private Insets pixmapInsets = new Insets(6, 6, 0, 6);
683 private Insets pixmapInsets2 = new Insets(6, 6, 6, 6);
684
685 FantasiaMenuBar() {
686 setOpaque(false);
687 }
688
689 protected void
690 paintComponent(Graphics g) {
691 super.paintComponent(g);
692 if(standardBar.isVisible()) {
693 PixmapPane.paintComponent(this, g, Res.gfxMenuBarBg, pixmapInsets);
694 } else {
695 PixmapPane.paintComponent(this, g, Res.gfxRoundBg14, pixmapInsets2);
696 }
697 }
698 }
699 }

  ViewVC Help
Powered by ViewVC